From abcb758a568e96194613411d38dada783942fcd8 Mon Sep 17 00:00:00 2001 From: swordshine Date: Mon, 17 Jun 2013 00:21:53 +0000 Subject: [PATCH] - Updated token images - Added Darksteel Garrison --- .gitattributes | 1 + res/cardsfolder/d/darksteel_garrison.txt | 9 + res/lists/token-images.txt | 4 +- src/main/java/forge/Card.java | 208 +++++++++++++++++- src/main/java/forge/CardPredicates.java | 9 + src/main/java/forge/CardUtil.java | 2 + .../card/ability/effects/AttachEffect.java | 4 +- .../ability/effects/ChangeZoneEffect.java | 16 +- .../ability/effects/CopyPermanentEffect.java | 10 +- .../ability/effects/UnattachAllEffect.java | 5 +- .../forge/card/cardfactory/CardFactory.java | 2 + .../card/cardfactory/CardFactoryUtil.java | 29 +++ src/main/java/forge/game/GameAction.java | 42 +++- src/main/java/forge/game/phase/Combat.java | 2 + src/main/java/forge/game/phase/Untap.java | 5 +- .../forge/gui/match/TargetingOverlay.java | 22 ++ src/main/java/forge/view/arcane/PlayArea.java | 14 +- 17 files changed, 360 insertions(+), 24 deletions(-) create mode 100644 res/cardsfolder/d/darksteel_garrison.txt diff --git a/.gitattributes b/.gitattributes index 4677744cec5..8d49fda1d9c 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2395,6 +2395,7 @@ res/cardsfolder/d/darksteel_citadel.txt svneol=native#text/plain res/cardsfolder/d/darksteel_colossus.txt svneol=native#text/plain res/cardsfolder/d/darksteel_forge.txt svneol=native#text/plain res/cardsfolder/d/darksteel_gargoyle.txt svneol=native#text/plain +res/cardsfolder/d/darksteel_garrison.txt -text res/cardsfolder/d/darksteel_ingot.txt svneol=native#text/plain res/cardsfolder/d/darksteel_juggernaut.txt svneol=native#text/plain res/cardsfolder/d/darksteel_myr.txt svneol=native#text/plain diff --git a/res/cardsfolder/d/darksteel_garrison.txt b/res/cardsfolder/d/darksteel_garrison.txt new file mode 100644 index 00000000000..5c3c32dde78 --- /dev/null +++ b/res/cardsfolder/d/darksteel_garrison.txt @@ -0,0 +1,9 @@ +Name:Darksteel Garrison +ManaCost:2 +Types:Artifact Fortification +K:Fortify 3 +S:Mode$ Continuous | Affected$ Land.FortifiedBy | AddKeyword$ Indestructible | Description$ Fortified land is indestructible. +T:Mode$ Taps | ValidCard$ Land.FortifiedBy | Execute$ TrigPump | TriggerDescription$ Whenever fortified land becomes tapped, target creature gets +1/+1 until end of turn. +SVar:TrigPump:AB$ Pump | Cost$ 0 | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ 1 | NumDef$ 1 +SVar:Picture:http://www.wizards.com/global/images/magic/general/darksteel_garrison.jpg +Oracle:Fortified land is indestructible.\nWhenever fortified land becomes tapped, target creature gets +1/+1 until end of turn.\nFortify {3} ({3}: Attach to target land you control. Fortify only as a sorcery. This card enters the battlefield unattached and stays on the battlefield if the land leaves.) diff --git a/res/lists/token-images.txt b/res/lists/token-images.txt index 19b94ff57b0..c4e79ded7ad 100644 --- a/res/lists/token-images.txt +++ b/res/lists/token-images.txt @@ -193,8 +193,9 @@ w_1_1_bird_rtr.jpg http://www.cardforge.org/fpics/tokens/RTR w_1_1_citizen.jpg http://www.cardforge.org/fpics/tokens/w_1_1_citizen.jpg w_1_1_goldmeadow_harrier.jpg http://www.cardforge.org/fpics/tokens/w_1_1_goldmeadow_harrier.jpg w_1_1_human_dka.jpg http://www.cardforge.org/fpics/tokens/w_1_1_human_dka.jpg -w_1_1_human_avr.jpg http://www.cardforge.org/fpics/tokens/w_1_1_human_avr.jpg +w_1_1_human_avr.jpg http://www.cardforge.org/fpics/tokens/w_1_1_human_avr.jpg w_1_1_kithkin_soldier.jpg http://www.cardforge.org/fpics/tokens/w_1_1_kithkin_soldier.jpg +w_1_1_knight.jpg http://www.cardforge.org/fpics/tokens/w_1_1_knight.jpg w_1_1_kor_soldier.jpg http://www.cardforge.org/fpics/tokens/w_1_1_kor_soldier.jpg w_1_1_pegasus.jpg http://www.cardforge.org/fpics/tokens/w_1_1_pegasus.jpg w_1_1_soldier.jpg http://www.cardforge.org/fpics/tokens/w_1_1_soldier.jpg @@ -238,4 +239,3 @@ morph.jpg http://www.cardforge.org/fpics/effects/mo # //These tokens are not currently used by any cards in Forge, but links provided should they be scripted so the correct name is used: # //g_1_1_wolves_of_the_hunt.jpg http://www.cardforge.org/fpics/tokens/g_1_1_wolves_of_the_hunt.jpg [LEG] Master of the Hunt # //rg_1_1_goblin_warrior.jpg http://www.cardforge.org/fpics/tokens/rg_1_1_goblin_warrior.jpg [SHM] Wort, the Raidmother -# //w_1_1_knight.jpg http://www.cardforge.org/fpics/tokens/w_1_1_knight.jpg [ALL] Errand of Duty diff --git a/src/main/java/forge/Card.java b/src/main/java/forge/Card.java index d240b71a9b0..73d445b358a 100644 --- a/src/main/java/forge/Card.java +++ b/src/main/java/forge/Card.java @@ -113,8 +113,14 @@ public class Card extends GameEntity implements Comparable { // equipping size will always be 0 or 1 // if this card is of the type equipment, what card is it currently equipping? private ArrayList equipping = new ArrayList(); - // which auras enchanted this card? + // which fortification cards are fortifying this card? + private ArrayList fortifiedBy = new ArrayList(); + // fortifying size will always be 0 or 1 + // if this card is of the type fortification, what card is it currently fortifying? + private ArrayList fortifying = new ArrayList(); + + // which auras enchanted this card? // if this card is an Aura, what Entity is it enchanting? private GameEntity enchanting = null; @@ -2153,7 +2159,7 @@ public class Card extends GameEntity implements Comparable { sbLong.append("with another unpaired creature when either "); sbLong.append("enters the battlefield. They remain paired for "); sbLong.append("as long as you control both of them)"); - } else if (keyword.startsWith("Equip")) { + } else if (keyword.startsWith("Equip") || keyword.startsWith("Fortification")) { // keyword parsing takes care of adding a proper description continue; } else { @@ -3042,6 +3048,17 @@ public class Card extends GameEntity implements Comparable { return this.equippedBy; } + /** + *

+ * Getter for the field fortifiedBy. + *

+ * + * @return a {@link java.util.ArrayList} object. + */ + public final ArrayList getFortifiedBy() { + return this.fortifiedBy; + } + /** *

* Setter for the field equippedBy. @@ -3054,6 +3071,18 @@ public class Card extends GameEntity implements Comparable { this.equippedBy = list; } + /** + *

+ * Setter for the field fortifiedBy. + *

+ * + * @param list + * a {@link java.util.ArrayList} object. + */ + public final void setFortifiedBy(final ArrayList list) { + this.fortifiedBy = list; + } + /** *

* Getter for the field equipping. @@ -3065,6 +3094,17 @@ public class Card extends GameEntity implements Comparable { return this.equipping; } + /** + *

+ * Getter for the field fortifying. + *

+ * + * @return a {@link java.util.ArrayList} object. + */ + public final ArrayList getFortifying() { + return this.fortifying; + } + /** *

* getEquippingCard. @@ -3079,6 +3119,20 @@ public class Card extends GameEntity implements Comparable { return this.equipping.get(0); } + /** + *

+ * getFortifyingCard. + *

+ * + * @return a {@link forge.Card} object. + */ + public final Card getFortifyingCard() { + if (this.fortifying.isEmpty()) { + return null; + } + return this.fortifying.get(0); + } + /** *

* Setter for the field equipping. @@ -3091,6 +3145,18 @@ public class Card extends GameEntity implements Comparable { this.equipping = list; } + /** + *

+ * Setter for the field fortifying. + *

+ * + * @param list + * a {@link java.util.ArrayList} object. + */ + public final void setFortifying(final ArrayList list) { + this.fortifying = list; + } + /** *

* isEquipped. @@ -3102,6 +3168,17 @@ public class Card extends GameEntity implements Comparable { return !this.equippedBy.isEmpty(); } + /** + *

+ * isFortified. + *

+ * + * @return a boolean. + */ + public final boolean isFortified() { + return !this.fortifiedBy.isEmpty(); + } + /** *

* isEquipping. @@ -3113,6 +3190,17 @@ public class Card extends GameEntity implements Comparable { return this.equipping.size() != 0; } + /** + *

+ * isFortifying. + *

+ * + * @return a boolean. + */ + public final boolean isFortifying() { + return !this.fortifying.isEmpty(); + } + /** *

* addEquippedBy. @@ -3126,6 +3214,19 @@ public class Card extends GameEntity implements Comparable { this.updateObservers(); } + /** + *

+ * addFortifiedBy. + *

+ * + * @param c + * a {@link forge.Card} object. + */ + public final void addFortifiedBy(final Card c) { + this.fortifiedBy.add(c); + this.updateObservers(); + } + /** *

* removeEquippedBy. @@ -3139,6 +3240,19 @@ public class Card extends GameEntity implements Comparable { this.updateObservers(); } + /** + *

+ * removeFortifiedBy. + *

+ * + * @param c + * a {@link forge.Card} object. + */ + public final void removeFortifiedBy(final Card c) { + this.fortifiedBy.remove(c); + this.updateObservers(); + } + /** *

* addEquipping. @@ -3153,6 +3267,33 @@ public class Card extends GameEntity implements Comparable { this.updateObservers(); } + /** + *

+ * addFortifying. + *

+ * + * @param c + * a {@link forge.Card} object. + */ + public final void addFortifying(final Card c) { + this.fortifying.add(c); + this.setTimestamp(getGame().getNextTimestamp()); + this.updateObservers(); + } + + /** + *

+ * removeFortifying. + *

+ * + * @param c + * a {@link forge.Card} object. + */ + public final void removeFortifying(final Card c) { + this.fortifying.remove(c); + this.updateObservers(); + } + /** *

* removeEquipping. @@ -3205,6 +3346,31 @@ public class Card extends GameEntity implements Comparable { this.getController().getGame().getTriggerHandler().runTrigger(TriggerType.Attached, runParams, false); } + /** + *

+ * fortifyCard. + *

+ * fortification.fortifyCard(cardToBeFortified) + * + * @param c + * a {@link forge.Card} object. + */ + public final void fortifyCard(final Card c) { + if (this.isFortifying()) { + this.unFortifyCard(this.getFortifying().get(0)); + } + this.addFortifying(c); + c.addFortifiedBy(this); + + // Play the Equip sound + getGame().fireEvent(new GameEventCardEquipped()); + // run trigger + final HashMap runParams = new HashMap(); + runParams.put("AttachSource", this); + runParams.put("AttachTarget", c); + this.getController().getGame().getTriggerHandler().runTrigger(TriggerType.Attached, runParams, false); + } + /** *

* unEquipCard. @@ -3225,6 +3391,19 @@ public class Card extends GameEntity implements Comparable { getGame().getTriggerHandler().runTrigger(TriggerType.Unequip, runParams, false); } + /** + *

+ * unFortifyCard. + *

+ * + * @param c + * a {@link forge.Card} object. + */ + public final void unFortifyCard(final Card c) { // fortification.unEquipCard(fortifiedCard); + this.fortifying.remove(c); + c.removeFortifiedBy(this); + } + /** *

* unEquipAllCards. @@ -4542,6 +4721,7 @@ public class Card extends GameEntity implements Comparable { public final boolean isCreature() { return this.typeContains("Creature"); } public final boolean isArtifact() { return this.typeContains("Artifact"); } public final boolean isEquipment() { return this.typeContains("Equipment"); } + public final boolean isFortification() { return this.typeContains("Fortification"); } public final boolean isScheme() { return this.typeContains("Scheme"); } @@ -4802,6 +4982,12 @@ public class Card extends GameEntity implements Comparable { } } + for (final Card f : this.getFortifiedBy()) { + if (f.isPhasedOut() == phasingIn) { + f.phase(false); + } + } + for (final Card aura : this.getEnchantedBy()) { if (aura.isPhasedOut() == phasingIn) { aura.phase(false); @@ -5319,11 +5505,11 @@ public class Card extends GameEntity implements Comparable { return false; } } else if (property.startsWith("AttachedBy")) { - if (!this.equippedBy.contains(source) && !this.getEnchantedBy().contains(source)) { + if (!this.equippedBy.contains(source) && !this.getEnchantedBy().contains(source) && !this.getFortifiedBy().contains(source)) { return false; } } else if (property.equals("Attached")) { - if (!this.equipping.contains(source) && !source.equals(this.enchanting)) { + if (!this.equipping.contains(source) && !source.equals(this.enchanting) && !this.fortifying.contains(source)) { return false; } } else if (property.startsWith("AttachedTo")) { @@ -5351,8 +5537,8 @@ public class Card extends GameEntity implements Comparable { } } else { if (((this.enchanting == null) || !this.enchanting.isValid(restriction, sourceController, source)) - && (this.equipping.isEmpty() || !this.equipping.get(0).isValid(restriction, sourceController, - source))) { + && (this.equipping.isEmpty() || !this.equipping.get(0).isValid(restriction, sourceController, source)) + && (this.fortifying.isEmpty() || !this.fortifying.get(0).isValid(restriction, sourceController, source))) { return false; } } @@ -5369,7 +5555,7 @@ public class Card extends GameEntity implements Comparable { } } } else if (property.equals("NotAttachedTo")) { - if (this.equipping.contains(source) || source.equals(this.enchanting)) { + if (this.equipping.contains(source) || source.equals(this.enchanting) || this.fortifying.contains(source)) { return false; } } else if (property.startsWith("EnchantedBy")) { @@ -5477,6 +5663,10 @@ public class Card extends GameEntity implements Comparable { return false; } } + } else if (property.startsWith("FortifiedBy")) { + if (!this.fortifiedBy.contains(source)) { + return false; + } } else if (property.startsWith("CanBeEquippedBy")) { if (!this.canBeEquippedBy(source)) { return false; @@ -5485,6 +5675,10 @@ public class Card extends GameEntity implements Comparable { if (!this.equipping.contains(source)) { return false; } + } else if (property.startsWith("Fortified")) { + if (!this.fortifying.contains(source)) { + return false; + } } else if (property.startsWith("HauntedBy")) { if (!this.hauntedBy.contains(source)) { return false; diff --git a/src/main/java/forge/CardPredicates.java b/src/main/java/forge/CardPredicates.java index 17561c0a075..d742b7fb525 100644 --- a/src/main/java/forge/CardPredicates.java +++ b/src/main/java/forge/CardPredicates.java @@ -220,6 +220,15 @@ public final class CardPredicates { return c.isEquipment(); } }; + /** + * a Predicate to get all fortification. + */ + public static final Predicate Fortification = new Predicate() { + @Override + public boolean apply(Card c) { + return c.isFortification(); + } + }; /** * a Predicate to get all unenchanted cards in a list. */ diff --git a/src/main/java/forge/CardUtil.java b/src/main/java/forge/CardUtil.java index 02f062be770..fe6e7687171 100644 --- a/src/main/java/forge/CardUtil.java +++ b/src/main/java/forge/CardUtil.java @@ -147,6 +147,8 @@ public final class CardUtil { newCopy.setEnchantedBy(new ArrayList (in.getEnchantedBy())); newCopy.setEquipping(new ArrayList (in.getEquipping())); newCopy.setEquippedBy(new ArrayList (in.getEquippedBy())); + newCopy.setFortifying(new ArrayList (in.getFortifying())); + newCopy.setFortifiedBy(new ArrayList (in.getFortifiedBy())); newCopy.setClones(in.getClones()); newCopy.setHaunting(in.getHaunting()); for (final Card haunter : in.getHauntedBy()) { diff --git a/src/main/java/forge/card/ability/effects/AttachEffect.java b/src/main/java/forge/card/ability/effects/AttachEffect.java index 534ed756593..d4515f69232 100644 --- a/src/main/java/forge/card/ability/effects/AttachEffect.java +++ b/src/main/java/forge/card/ability/effects/AttachEffect.java @@ -93,8 +93,8 @@ public class AttachEffect extends SpellAbilityEffect { handleAura(card, c); } else if (card.isEquipment()) { card.equipCard(c); - // else if (card.isFortification()) - // card.fortifyCard(c); + } else if (card.isFortification()) { + card.fortifyCard(c); } } else if (o instanceof Player) { // Currently, a few cards can enchant players diff --git a/src/main/java/forge/card/ability/effects/ChangeZoneEffect.java b/src/main/java/forge/card/ability/effects/ChangeZoneEffect.java index 1c30a2d89b8..6f66d772bd6 100644 --- a/src/main/java/forge/card/ability/effects/ChangeZoneEffect.java +++ b/src/main/java/forge/card/ability/effects/ChangeZoneEffect.java @@ -481,12 +481,18 @@ public class ChangeZoneEffect extends SpellAbilityEffect { tgtC.removeEnchanting(oldEnchanted); } tgtC.enchantEntity(attachedTo); - } else { //Equipment + } else if (tgtC.isEquipment()) { //Equipment if (tgtC.isEquipping()) { final Card oldEquiped = tgtC.getEquippingCard(); tgtC.removeEquipping(oldEquiped); } tgtC.equipCard(attachedTo); + } else { // fortification + if (tgtC.isFortifying()) { + final Card oldFortified = tgtC.getFortifyingCard(); + tgtC.removeFortifying(oldFortified); + } + tgtC.fortifyCard(attachedTo); } } else { // When it should enter the battlefield attached to an illegal permanent it fails continue; @@ -815,12 +821,18 @@ public class ChangeZoneEffect extends SpellAbilityEffect { c.removeEnchanting(oldEnchanted); } c.enchantEntity(attachedTo); - } else { //Equipment + } else if (c.isEquipment()) { //Equipment if (c.isEquipping()) { final Card oldEquiped = c.getEquippingCard(); c.removeEquipping(oldEquiped); } c.equipCard(attachedTo); + } else { + if (c.isFortifying()) { + final Card oldFortified = c.getFortifyingCard(); + c.removeFortifying(oldFortified); + } + c.fortifyCard(attachedTo); } } else { // When it should enter the battlefield attached to an illegal permanent it fails continue; diff --git a/src/main/java/forge/card/ability/effects/CopyPermanentEffect.java b/src/main/java/forge/card/ability/effects/CopyPermanentEffect.java index 123f19bc06e..84b76fbb47d 100644 --- a/src/main/java/forge/card/ability/effects/CopyPermanentEffect.java +++ b/src/main/java/forge/card/ability/effects/CopyPermanentEffect.java @@ -235,8 +235,14 @@ public class CopyPermanentEffect extends SpellAbilityEffect { } else {//can't enchant continue; } - } else { //Equipment - copy.equipCard(attachedTo); + } else if (copy.isEquipment()) { //Equipment + if (attachedTo.canBeEquippedBy(copy)) { + copy.equipCard(attachedTo); + } else { + continue; + } + } else { // Fortification + copy.fortifyCard(attachedTo); } } else { continue; diff --git a/src/main/java/forge/card/ability/effects/UnattachAllEffect.java b/src/main/java/forge/card/ability/effects/UnattachAllEffect.java index c4692c8e71f..1c438aebaee 100644 --- a/src/main/java/forge/card/ability/effects/UnattachAllEffect.java +++ b/src/main/java/forge/card/ability/effects/UnattachAllEffect.java @@ -26,7 +26,10 @@ public class UnattachAllEffect extends SpellAbilityEffect { if (cardToUnattach.isEquipping() && c.getEquippedBy().contains(cardToUnattach)) { cardToUnattach.unEquipCard(cardToUnattach.getEquipping().get(0)); } - //TODO - unfortify would also be handled here + } else if (cardToUnattach.isFortification()) { + if (cardToUnattach.isFortifying() && c.getFortifiedBy().contains(cardToUnattach)) { + cardToUnattach.unFortifyCard(cardToUnattach.getFortifying().get(0)); + } } } else if (o instanceof Player) { final Player p = (Player) o; diff --git a/src/main/java/forge/card/cardfactory/CardFactory.java b/src/main/java/forge/card/cardfactory/CardFactory.java index 687958bc1ed..a5a02e29861 100644 --- a/src/main/java/forge/card/cardfactory/CardFactory.java +++ b/src/main/java/forge/card/cardfactory/CardFactory.java @@ -107,6 +107,8 @@ public class CardFactory { // I'm not sure if we really should be copying enchant/equip stuff over. out.setEquipping(in.getEquipping()); out.setEquippedBy(in.getEquippedBy()); + out.setFortifying(in.getFortifying()); + out.setFortifiedBy(in.getFortifiedBy()); out.setEnchantedBy(in.getEnchantedBy()); out.setEnchanting(in.getEnchanting()); out.setClones(in.getClones()); diff --git a/src/main/java/forge/card/cardfactory/CardFactoryUtil.java b/src/main/java/forge/card/cardfactory/CardFactoryUtil.java index 0b62fe17e97..6a88b1771d8 100644 --- a/src/main/java/forge/card/cardfactory/CardFactoryUtil.java +++ b/src/main/java/forge/card/cardfactory/CardFactoryUtil.java @@ -2598,6 +2598,35 @@ public class CardFactoryUtil { card.getUnparsedAbilities().add(abilityStr.toString()); } + if (card.hasStartOfKeyword("Fortify")) { + final int equipPos = card.getKeywordPosition("Fortify"); + final String equipString = card.getKeyword().get(equipPos).substring(7); + final String[] equipExtras = equipString.contains("\\|") ? equipString.split("\\|", 2) : null; + // Get cost string + String equipCost = ""; + if (equipExtras != null) { + equipCost = equipExtras[0].trim(); + } else { + equipCost = equipString.trim(); + } + // Create attach ability string + final StringBuilder abilityStr = new StringBuilder(); + abilityStr.append("AB$ Attach | Cost$ "); + abilityStr.append(equipCost); + abilityStr.append(" | ValidTgts$ Land.YouCtrl | TgtPrompt$ Select target land you control "); + abilityStr.append("| SorcerySpeed$ True | AILogic$ Pump | IsPresent$ Card.Self+nonCreature "); + if (equipExtras != null) { + abilityStr.append("| ").append(equipExtras[1]).append(" "); + } + abilityStr.append("| PrecostDesc$ Fortify | SpellDescription$ (Attach to target land you control. Fortify only as a sorcery.)"); + + // instantiate attach ability + final SpellAbility sa = AbilityFactory.getAbility(abilityStr.toString(), card); + card.addSpellAbility(sa); + // add ability to instrinic strings so copies/clones create the ability also + card.getUnparsedAbilities().add(abilityStr.toString()); + } + setupEtbKeywords(card); } diff --git a/src/main/java/forge/game/GameAction.java b/src/main/java/forge/game/GameAction.java index 9c3cd93587d..6f13b27e4eb 100644 --- a/src/main/java/forge/game/GameAction.java +++ b/src/main/java/forge/game/GameAction.java @@ -278,12 +278,12 @@ public class GameAction { } } } - // Handle unequipping creatures - if (copied.isEquipped()) { - final List equipments = new ArrayList(copied.getEquippedBy()); - for (final Card equipment : equipments) { - if (equipment.isInPlay()) { - equipment.unEquipCard(copied); + // Handle unfortifying lands + if (copied.isFortified()) { + final List fortifications = new ArrayList(copied.getFortifiedBy()); + for (final Card f : fortifications) { + if (f.isInPlay()) { + f.unFortifyCard(copied); } } } @@ -294,6 +294,13 @@ public class GameAction { copied.unEquipCard(equippedCreature); } } + // fortifications moving off battlefield + if (copied.isFortifying()) { + final Card fortifiedLand = copied.getFortifying().get(0); + if (fortifiedLand.isInPlay()) { + copied.unFortifyCard(fortifiedLand); + } + } // remove enchantments from creatures if (copied.isEnchanted()) { final List auras = new ArrayList(copied.getEnchantedBy()); @@ -888,6 +895,16 @@ public class GameAction { } } // if isEquipped() + if (c.isFortified()) { + final List fortifications = new ArrayList(c.getFortifiedBy()); + for (final Card f : fortifications) { + if (!f.isInPlay()) { + f.unFortifyCard(c); + checkAgain = true; + } + } + } // if isFortified() + if (c.isEquipping()) { final Card equippedCreature = c.getEquipping().get(0); if (!equippedCreature.isCreature() || !equippedCreature.isInPlay() @@ -902,6 +919,19 @@ public class GameAction { } } // if isEquipping() + if (c.isFortifying()) { + final Card fortifiedLand = c.getFortifying().get(0); + if (!fortifiedLand.isLand() || !fortifiedLand.isInPlay()) { + c.unFortifyCard(fortifiedLand); + checkAgain = true; + } + // make sure any fortification that has become a creature stops fortifying + if (c.isCreature()) { + c.unFortifyCard(fortifiedLand); + checkAgain = true; + } + } // if isFortifying() + if (c.isAura()) { // Check if Card Aura is attached to is a legal target final GameEntity entity = c.getEnchanting(); diff --git a/src/main/java/forge/game/phase/Combat.java b/src/main/java/forge/game/phase/Combat.java index 17a599f4c94..8f22146b919 100644 --- a/src/main/java/forge/game/phase/Combat.java +++ b/src/main/java/forge/game/phase/Combat.java @@ -473,6 +473,8 @@ public class Combat { attacker = source.getEnchantingCard(); } else if (source.isEquipment()) { attacker = source.getEquippingCard(); + } else if (source.isFortification()) { + attacker = source.getFortifyingCard(); } // return the corresponding defender diff --git a/src/main/java/forge/game/phase/Untap.java b/src/main/java/forge/game/phase/Untap.java index d9f3b309abf..15ec450e9d9 100644 --- a/src/main/java/forge/game/phase/Untap.java +++ b/src/main/java/forge/game/phase/Untap.java @@ -303,8 +303,11 @@ public class Untap extends Phase { if (list.contains(c.getEquippingCard())) { continue; } + } else if (c.isFortification() && c.isFortifying()) { + if (list.contains(c.getFortifyingCard())) { + continue; + } } - // TODO: Fortification c.phase(); } } diff --git a/src/main/java/forge/gui/match/TargetingOverlay.java b/src/main/java/forge/gui/match/TargetingOverlay.java index e750a6701b3..7240c0d6255 100644 --- a/src/main/java/forge/gui/match/TargetingOverlay.java +++ b/src/main/java/forge/gui/match/TargetingOverlay.java @@ -128,8 +128,10 @@ public enum TargetingOverlay { Card enchanting = c.getEnchantingCard(); Card equipping = c.getEquippingCard(); + Card fortifying = c.getFortifyingCard(); List enchantedBy = c.getEnchantedBy(); List equippedBy = c.getEquippedBy(); + List fortifiedBy = c.getFortifiedBy(); Card paired = c.getPairedWith(); if (null != enchanting) { @@ -150,6 +152,15 @@ public enum TargetingOverlay { } } + if (null != fortifying) { + if (!fortifying.getController().equals(c.getController())) { + arcs.add(new Point[] { + endpoints.get(fortifying.getUniqueNumber()), + endpoints.get(c.getUniqueNumber()) + }); + } + } + if (null != enchantedBy) { for (Card enc : enchantedBy) { if (!enc.getController().equals(c.getController())) { @@ -172,6 +183,17 @@ public enum TargetingOverlay { } } + if (null != fortifiedBy) { + for (Card eq : fortifiedBy) { + if (!eq.getController().equals(c.getController())) { + arcs.add(new Point[] { + endpoints.get(c.getUniqueNumber()), + endpoints.get(eq.getUniqueNumber()) + }); + } + } + } + if (null != paired) { arcs.add(new Point[] { endpoints.get(paired.getUniqueNumber()), diff --git a/src/main/java/forge/view/arcane/PlayArea.java b/src/main/java/forge/view/arcane/PlayArea.java index 2d617d858f1..1f33ead84be 100644 --- a/src/main/java/forge/view/arcane/PlayArea.java +++ b/src/main/java/forge/view/arcane/PlayArea.java @@ -589,11 +589,23 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen } } } - + + if (card.isFortified()) { + final ArrayList fortifications = card.getFortifiedBy(); + for (final Card e : fortifications) { + final forge.view.arcane.CardPanel cardE = getCardPanel(e.getUniqueNumber()); + if (cardE != null) { + toPanel.getAttachedPanels().add(cardE); + } + } + } + if (card.isEnchantingCard()) { toPanel.setAttachedToPanel(getCardPanel(card.getEnchantingCard().getUniqueNumber())); } else if (card.isEquipping()) { toPanel.setAttachedToPanel(getCardPanel(card.getEquipping().get(0).getUniqueNumber())); + } else if (card.isFortifying()) { + toPanel.setAttachedToPanel(getCardPanel(card.getFortifying().get(0).getUniqueNumber())); } else { toPanel.setAttachedToPanel(null); }