diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/CardImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/CardImageSource.java
index 9e71fb1ab88..dac76f4ed1a 100644
--- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/CardImageSource.java
+++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/CardImageSource.java
@@ -6,7 +6,7 @@ package org.mage.plugins.card.dl.sources;
*/
public interface CardImageSource {
- String generateURL(Integer collectorId, String cardName, String cardSet, boolean twoFacedCard, boolean secondFace, boolean isFlipCard, boolean flippedView) throws Exception;
+ String generateURL(Integer collectorId, String cardName, String cardSet, boolean twoFacedCard, boolean secondFace, boolean isFlipCard, boolean isSplitCard, boolean flippedView) throws Exception;
String generateTokenUrl(String name, String set);
Float getAverageSize();
}
diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MagicCardsImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MagicCardsImageSource.java
index 00de2ec4477..29211a86f61 100644
--- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MagicCardsImageSource.java
+++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MagicCardsImageSource.java
@@ -63,7 +63,7 @@ public class MagicCardsImageSource implements CardImageSource {
}
@Override
- public String generateURL(Integer collectorId, String cardName, String cardSet, boolean twoFacedCard, boolean secondSide, boolean isFlipCard, boolean flippedView) throws Exception {
+ public String generateURL(Integer collectorId, String cardName, String cardSet, boolean twoFacedCard, boolean secondSide, boolean isFlipCard, boolean isSplitCard, boolean flippedView) throws Exception {
if (collectorId == null || cardSet == null) {
throw new Exception("Wrong parameters for image: collector id: " + collectorId + ",card set: " + cardSet);
}
@@ -74,6 +74,9 @@ public class MagicCardsImageSource implements CardImageSource {
if (twoFacedCard) {
url.append(secondSide ? "b" : "a");
}
+ if (isSplitCard) {
+ url.append("a");
+ }
if (isFlipCard) {
if (flippedView) { // download rotated by 180 degree image
url.append("b");
diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/WizardCardsImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/WizardCardsImageSource.java
index 13c39869e68..3ec91d028e8 100644
--- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/WizardCardsImageSource.java
+++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/WizardCardsImageSource.java
@@ -93,7 +93,7 @@ public class WizardCardsImageSource implements CardImageSource {
}
@Override
- public String generateURL(Integer collectorId, String cardName, String cardSet, boolean twoFacedCard, boolean secondSide, boolean isFlipCard, boolean flippedView) throws Exception {
+ public String generateURL(Integer collectorId, String cardName, String cardSet, boolean twoFacedCard, boolean secondSide, boolean isFlipCard, boolean isSplitCard, boolean flippedView) throws Exception {
if (collectorId == null || cardSet == null) {
throw new Exception("Wrong parameters for image: collector id: " + collectorId + ",card set: " + cardSet);
}
diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/images/CardInfo.java b/Mage.Client/src/main/java/org/mage/plugins/card/images/CardInfo.java
index 7f6e4364c5e..4c76ccd8e6e 100644
--- a/Mage.Client/src/main/java/org/mage/plugins/card/images/CardInfo.java
+++ b/Mage.Client/src/main/java/org/mage/plugins/card/images/CardInfo.java
@@ -16,6 +16,7 @@ public class CardInfo {
private boolean secondSide;
private boolean flipCard;
private boolean flippedSide;
+ private boolean splitCard;
private boolean usesVariousArt;
public CardInfo(String name, String set, Integer collectorId, boolean usesVariousArt, Integer type) {
@@ -147,6 +148,14 @@ public class CardInfo {
this.flipCard = flipCard;
}
+ public boolean isSplitCard() {
+ return splitCard;
+ }
+
+ public void setSplitCard(boolean splitCard) {
+ this.splitCard = splitCard;
+ }
+
public Integer getType() {
return type;
}
diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java
index b6f6b3e8433..44c4894a6b4 100644
--- a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java
+++ b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java
@@ -244,6 +244,9 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
if (card.isFlipCard()) {
url.setFlipCard(true);
}
+ if (card.isSplitCard()) {
+ url.setSplitCard(true);
+ }
allCardsUrls.add(url);
if (card.canTransform()) {
// add second side for downloading
@@ -417,7 +420,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
url = cardImageSource.generateTokenUrl(card.getName(), card.getSet());
} else {
url = cardImageSource.generateURL(card.getCollectorId(), card.getDownloadName(), card.getSet(),
- card.isTwoFacedCard(), card.isSecondSide(), card.isFlipCard(), card.isFlippedSide());
+ card.isTwoFacedCard(), card.isSecondSide(), card.isFlipCard(), card.isSplitCard(), card.isFlippedSide());
}
if (url != null) {
diff --git a/Mage/src/mage/abilities/keyword/FuseAbility.java b/Mage/src/mage/abilities/keyword/FuseAbility.java
new file mode 100644
index 00000000000..98bfc5d4c13
--- /dev/null
+++ b/Mage/src/mage/abilities/keyword/FuseAbility.java
@@ -0,0 +1,66 @@
+/*
+* 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 mage.abilities.keyword;
+
+import mage.Constants.Zone;
+import mage.abilities.SpellAbility;
+import mage.abilities.costs.mana.ManaCosts;
+import mage.cards.Card;
+
+/**
+ *
+ * @author LevelX2
+ */
+
+public class FuseAbility extends SpellAbility {
+
+ public FuseAbility(Card card, ManaCosts costs) {
+ super(costs, "fused " + card.getName(), Zone.HAND);
+ }
+
+ public FuseAbility(final FuseAbility ability) {
+ super(ability);
+ }
+
+ @Override
+ public FuseAbility copy() {
+ return new FuseAbility(this);
+ }
+
+ @Override
+ public String getRule(boolean all) {
+ return getRule();
+ }
+
+ @Override
+ public String getRule() {
+ return "Fuse (You may cast one or both halves of this card from your hand.)";
+ }
+
+}
diff --git a/Mage/src/mage/cards/Card.java b/Mage/src/mage/cards/Card.java
index d88ff3b4213..b313221ec41 100644
--- a/Mage/src/mage/cards/Card.java
+++ b/Mage/src/mage/cards/Card.java
@@ -63,6 +63,7 @@ public interface Card extends MageObject {
boolean isFaceDown();
boolean isFlipCard();
String getFlipCardName();
+ boolean isSplitCard();
boolean canTransform();
Card getSecondCardFace();
diff --git a/Mage/src/mage/cards/CardImpl.java b/Mage/src/mage/cards/CardImpl.java
index 452ea67194b..859b78c7497 100644
--- a/Mage/src/mage/cards/CardImpl.java
+++ b/Mage/src/mage/cards/CardImpl.java
@@ -72,6 +72,7 @@ public abstract class CardImpl> extends MageObjectImpl
protected Map info;
protected boolean usesVariousArt = false;
protected Counters counters;
+ protected boolean splitCard;
public CardImpl(UUID ownerId, int cardNumber, String name, Rarity rarity, CardType[] cardTypes, String costs) {
this(ownerId, name);
@@ -123,7 +124,10 @@ public abstract class CardImpl> extends MageObjectImpl
info = new HashMap();
info.putAll(card.info);
}
- usesVariousArt = card.usesVariousArt;
+ this.flipCard = card.flipCard;
+ this.flipCardName = card.flipCardName;
+ this.splitCard = card.splitCard;
+ this.usesVariousArt = card.usesVariousArt;
this.counters = card.counters.copy();
}
@@ -499,6 +503,11 @@ public abstract class CardImpl> extends MageObjectImpl
return flipCard;
}
+ @Override
+ public boolean isSplitCard() {
+ return splitCard;
+ }
+
@Override
public String getFlipCardName() {
return flipCardName;
diff --git a/Mage/src/mage/cards/SplitCard.java b/Mage/src/mage/cards/SplitCard.java
new file mode 100644
index 00000000000..3a3e85c5709
--- /dev/null
+++ b/Mage/src/mage/cards/SplitCard.java
@@ -0,0 +1,260 @@
+/*
+ * 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 mage.cards;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+import mage.Constants;
+import mage.Constants.CardType;
+import mage.Constants.Rarity;
+import mage.Constants.Zone;
+import mage.abilities.Abilities;
+import mage.abilities.AbilitiesImpl;
+import mage.abilities.Ability;
+import mage.abilities.SpellAbility;
+import mage.abilities.keyword.FuseAbility;
+import mage.game.Game;
+import mage.watchers.Watcher;
+
+/**
+ *
+ * @author LevelX2
+ */
+
+public abstract class SplitCard> extends CardImpl {
+
+ public enum ActiveCardHalve {
+ NONE, LEFT, RIGHT
+ }
+ private Card leftHalveCard;
+ private Card rightHalveCard;
+
+ private ActiveCardHalve activeCardHalve = ActiveCardHalve.NONE;
+
+ public SplitCard(UUID ownerId, int cardNumber, String name, Rarity rarity, CardType[] cardTypes, String costs) {
+ super(ownerId, cardNumber, name, rarity, cardTypes, costs);
+ this.splitCard = true;
+ }
+
+ public SplitCard(SplitCard card) {
+ super(card);
+ this.leftHalveCard = card.leftHalveCard;
+ this.rightHalveCard = card.rightHalveCard;
+ this.activeCardHalve = card.activeCardHalve;
+ }
+
+ public Card createLeftHalveCard (String name, String costs) {
+ CardType[] cardTypes = new CardType[getCardType().size()];
+ this.getCardType().toArray(cardTypes);
+ leftHalveCard = new leftHalveCard(this.getOwnerId(), this.getCardNumber(), name, this.rarity, cardTypes, costs);
+ leftHalveCard.getAbilities().setSourceId(objectId);
+ return leftHalveCard;
+ }
+
+ public Card createRightHalveCard (String name, String costs) {
+ CardType[] cardTypes = new CardType[getCardType().size()];
+ this.getCardType().toArray(cardTypes);
+ rightHalveCard = new leftHalveCard(this.getOwnerId(), this.getCardNumber(), name, this.rarity, cardTypes, costs);
+ rightHalveCard.getAbilities().setSourceId(objectId);
+ return rightHalveCard;
+ }
+
+ public Card getLeftHalveCard () {
+ return leftHalveCard;
+ }
+
+ public Card getRightHalveCard () {
+ return rightHalveCard;
+ }
+
+ public ActiveCardHalve getActiveCardHalve() {
+ return activeCardHalve;
+ }
+
+ @Override
+ public boolean cast(Game game, Constants.Zone fromZone, SpellAbility ability, UUID controllerId) {
+ if (super.cast(game, fromZone, ability, controllerId)) {
+ if (leftHalveCard.getAbilities().contains(ability)) {
+ activeCardHalve = ActiveCardHalve.LEFT;
+ } else if (rightHalveCard.getAbilities().contains(ability)) {
+ activeCardHalve = ActiveCardHalve.RIGHT;
+ } else {
+ activeCardHalve = ActiveCardHalve.NONE;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean moveToZone(Constants.Zone toZone, UUID sourceId, Game game, boolean flag, ArrayList appliedEffects) {
+ if (super.moveToZone(toZone, sourceId, game, flag, appliedEffects)) {
+ if (!toZone.equals(Zone.STACK)) {
+ activeCardHalve = ActiveCardHalve.NONE;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean moveToExile(UUID exileId, String name, UUID sourceId, Game game, ArrayList appliedEffects) {
+ if(super.moveToExile(exileId, name, sourceId, game, appliedEffects)) {
+ activeCardHalve = ActiveCardHalve.NONE;
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public Abilities getAbilities(){
+ Abilities allAbilites = new AbilitiesImpl();
+ if (activeCardHalve.equals(ActiveCardHalve.NONE) || activeCardHalve.equals(ActiveCardHalve.LEFT)) {
+ allAbilites.addAll(leftHalveCard.getAbilities());
+ }
+ if (activeCardHalve.equals(ActiveCardHalve.NONE) || activeCardHalve.equals(ActiveCardHalve.RIGHT)) {
+ allAbilites.addAll(rightHalveCard.getAbilities());
+ }
+ for (Ability ability: super.getAbilities()) {
+ if (ability instanceof FuseAbility) {
+ allAbilites.add(ability);
+ }
+ }
+ return allAbilites;
+ }
+
+ @Override
+ public SpellAbility getSpellAbility() {
+ switch (activeCardHalve) {
+ case LEFT:
+ return leftHalveCard.getSpellAbility();
+ case RIGHT:
+ return rightHalveCard.getSpellAbility();
+ }
+ return null;
+ }
+
+ @Override
+ public List getRules() {
+ List rules = new ArrayList();
+ if (activeCardHalve.equals(ActiveCardHalve.NONE) || activeCardHalve.equals(ActiveCardHalve.LEFT)) {
+ rules.add(new StringBuilder("").append(leftHalveCard.getName()).append("").toString());
+ rules.addAll(leftHalveCard.getRules());
+ }
+ if (activeCardHalve.equals(ActiveCardHalve.NONE)) {
+ rules.add("
");
+ }
+ if (activeCardHalve.equals(ActiveCardHalve.NONE) || activeCardHalve.equals(ActiveCardHalve.RIGHT)) {
+ rules.add(new StringBuilder("").append(rightHalveCard.getName()).append("").toString());
+ rules.addAll(rightHalveCard.getRules());
+ }
+
+ for (Ability ability: super.getAbilities()) {
+ if (ability instanceof FuseAbility) {
+ rules.add("
------------------------------------------------------------");
+ rules.add(ability.getRule());
+ }
+ }
+ return rules;
+ }
+
+ @Override
+ public void setControllerId(UUID controllerId) {
+ abilities.setControllerId(controllerId);
+ leftHalveCard.getAbilities().setControllerId(controllerId);
+ rightHalveCard.getAbilities().setControllerId(controllerId);
+ }
+
+ @Override
+ public void setOwnerId(UUID ownerId) {
+ this.ownerId = ownerId;
+ abilities.setControllerId(ownerId);
+ leftHalveCard.getAbilities().setControllerId(ownerId);
+ leftHalveCard.setOwnerId(ownerId);
+ rightHalveCard.getAbilities().setControllerId(ownerId);
+ rightHalveCard.setOwnerId(ownerId);
+
+ }
+
+ @Override
+ public List getWatchers() {
+ List allWatchers = new ArrayList();
+ switch (activeCardHalve) {
+ case LEFT:
+ allWatchers.addAll(leftHalveCard.getWatchers());
+ break;
+ case RIGHT:
+ allWatchers.addAll(rightHalveCard.getWatchers());
+ break;
+ }
+ return allWatchers;
+ }
+
+
+
+}
+
+/*
+ * The left side card of the split card
+ */
+class leftHalveCard extends CardImpl {
+
+ public leftHalveCard(UUID ownerId, int cardNumber, String name, Rarity rarity, CardType[] cardTypes, String costs) {
+ super(ownerId, cardNumber, name, rarity, cardTypes, costs);
+ }
+
+ public leftHalveCard(final leftHalveCard card) {
+ super(card);
+ }
+
+ @Override
+ public leftHalveCard copy() {
+ return new leftHalveCard(this);
+ }
+}
+
+/*
+ * The right side card of the split card
+ */
+class rightHalveCard extends CardImpl {
+
+ public rightHalveCard(UUID ownerId, int cardNumber, String name, Rarity rarity, CardType[] cardTypes, String costs) {
+ super(ownerId, cardNumber, name, rarity, cardTypes, costs);
+ }
+
+ public rightHalveCard(final rightHalveCard card) {
+ super(card);
+ }
+
+ @Override
+ public rightHalveCard copy() {
+ return new rightHalveCard(this);
+ }
+}
diff --git a/Mage/src/mage/game/stack/Spell.java b/Mage/src/mage/game/stack/Spell.java
index 9d533039b23..d0cdc8cc8a9 100644
--- a/Mage/src/mage/game/stack/Spell.java
+++ b/Mage/src/mage/game/stack/Spell.java
@@ -337,6 +337,11 @@ public class Spell> implements StackObject, Card {
return null;
}
+ @Override
+ public boolean isSplitCard() {
+ return false;
+ }
+
@Override
public boolean canTransform() {
return false;