From 200e191f14c204ab3dbac9095c9d5628d1ba56a4 Mon Sep 17 00:00:00 2001 From: kms70847 Date: Sat, 27 Jul 2019 19:16:00 -0400 Subject: [PATCH 1/3] When adding cards to library, insert "closest to top" card last --- .../java/forge/game/ability/effects/ChangeZoneAllEffect.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneAllEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneAllEffect.java index 72ae0a53850..7292fcc8325 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneAllEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneAllEffect.java @@ -134,6 +134,9 @@ public class ChangeZoneAllEffect extends SpellAbilityEffect { && !sa.hasParam("Shuffle") && cards.size() >= 2 && !random) { Player p = AbilityUtils.getDefinedPlayers(source, sa.getParamOrDefault("DefinedPlayer", "You"), sa).get(0); cards = (CardCollection) p.getController().orderMoveToZoneList(cards, destination); + //the last card in this list will be the closest to the top, but we want the first card to be closest. + //so reverse it here before moving them to the library. + java.util.Collections.reverse(cards); } if (destination == ZoneType.Graveyard) { From 61c42275e6ae1f5d692504395c062f491d4c9f85 Mon Sep 17 00:00:00 2001 From: Hans Mackowiak Date: Sun, 28 Jul 2019 12:21:01 +0000 Subject: [PATCH 2/3] Dash: reworked and better Haste part --- .../forge/game/ability/AbilityFactory.java | 7 ++++++- .../game/ability/SpellAbilityEffect.java | 2 +- .../ability/effects/ChangeZoneEffect.java | 4 ++-- .../forge/game/ability/effects/DigEffect.java | 13 +----------- .../game/ability/effects/PermanentEffect.java | 5 +++-- .../java/forge/game/card/CardFactoryUtil.java | 20 +++++-------------- .../java/forge/game/card/CardProperty.java | 5 +++++ 7 files changed, 23 insertions(+), 33 deletions(-) diff --git a/forge-game/src/main/java/forge/game/ability/AbilityFactory.java b/forge-game/src/main/java/forge/game/ability/AbilityFactory.java index 258d0a4e272..6fd213ea43c 100644 --- a/forge-game/src/main/java/forge/game/ability/AbilityFactory.java +++ b/forge-game/src/main/java/forge/game/ability/AbilityFactory.java @@ -204,7 +204,8 @@ public final class AbilityFactory { else if (api == ApiType.PermanentCreature || api == ApiType.PermanentNoncreature) { // If API is a permanent type, and creating AF Spell // Clear out the auto created SpellPemanent spell - if (type == AbilityRecordType.Spell && !mapParams.containsKey("SubAbility")) { + if (type == AbilityRecordType.Spell + && !mapParams.containsKey("SubAbility") && !mapParams.containsKey("NonBasicSpell")) { hostCard.clearFirstSpell(); } } @@ -389,6 +390,10 @@ public final class AbilityFactory { sa.setBasicSpell(false); } + if (mapParams.containsKey("Dash")) { + sa.setDash(true); + } + if (mapParams.containsKey("Outlast")) { sa.setOutlast(true); } diff --git a/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java b/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java index 6c468779186..a0d4e8b10b4 100644 --- a/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java +++ b/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java @@ -238,7 +238,7 @@ public abstract class SpellAbilityEffect { } sb.append(Lang.joinHomogenous(crds)); if (location.equals("Hand")) { - sb.append("to your hand").append(" "); + sb.append(" to your hand"); } sb.append(" at the "); if (combat) { diff --git a/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java index 4397465f47c..3a053f5937a 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java @@ -537,10 +537,10 @@ public class ChangeZoneEffect extends SpellAbilityEffect { tgtC.getController().getZone(destination), tgtC, sa, null); if (sa.hasParam("Unearth")) { movedCard.setUnearthed(true); - movedCard.addExtrinsicKeyword("Haste"); + movedCard.addChangedCardKeywords(Lists.newArrayList("Haste"), null, false, false, + game.getNextTimestamp(), true); registerDelayedTrigger(sa, "Exile", Lists.newArrayList(movedCard)); addLeaveBattlefieldReplacement(movedCard, sa, "Exile"); - movedCard.updateStateForView(); } if (sa.hasParam("FaceDown")) { movedCard.turnFaceDown(true); diff --git a/forge-game/src/main/java/forge/game/ability/effects/DigEffect.java b/forge-game/src/main/java/forge/game/ability/effects/DigEffect.java index 7d8a8d4cab4..f3e66bad91b 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/DigEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/DigEffect.java @@ -83,10 +83,6 @@ public class DigEffect extends SpellAbilityEffect { boolean changeAll = false; boolean allButOne = false; - final List keywords = new ArrayList(); - if (sa.hasParam("Keywords")) { - keywords.addAll(Arrays.asList(sa.getParam("Keywords").split(" & "))); - } if (sa.hasParam("ChangeNum")) { if (sa.getParam("ChangeNum").equalsIgnoreCase("All")) { @@ -307,9 +303,6 @@ public class DigEffect extends SpellAbilityEffect { else { c = game.getAction().moveTo(zone, c, sa); if (destZone1.equals(ZoneType.Battlefield)) { - for (final String kw : keywords) { - c.addExtrinsicKeyword(kw); - } if (sa.hasParam("Tapped")) { c.setTapped(true); } @@ -377,11 +370,7 @@ public class DigEffect extends SpellAbilityEffect { if (!origin.equals(c.getZone().getZoneType())) { table.put(origin, c.getZone().getZoneType(), c); } - if (destZone2 == ZoneType.Battlefield && !keywords.isEmpty()) { - for (final String kw : keywords) { - c.addExtrinsicKeyword(kw); - } - } else if (destZone2 == ZoneType.Exile) { + if (destZone2 == ZoneType.Exile) { if (sa.hasParam("ExileWithCounter")) { c.addCounter(CounterType.getType(sa.getParam("ExileWithCounter")), 1, player, true, counterTable); diff --git a/forge-game/src/main/java/forge/game/ability/effects/PermanentEffect.java b/forge-game/src/main/java/forge/game/ability/effects/PermanentEffect.java index 3324a88a9a0..f916ee8b67e 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/PermanentEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/PermanentEffect.java @@ -1,5 +1,7 @@ package forge.game.ability.effects; +import com.google.common.collect.Lists; + import forge.game.ability.SpellAbilityEffect; import forge.game.card.Card; import forge.game.player.Player; @@ -25,9 +27,8 @@ public class PermanentEffect extends SpellAbilityEffect { // some extra for Dashing if (sa.isDash()) { - c.addExtrinsicKeyword("Haste"); c.setSVar("EndOfTurnLeavePlay", "Dash"); - c.updateKeywords(); + registerDelayedTrigger(sa, "Hand", Lists.newArrayList(c)); } } } diff --git a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java index a958d18e9ae..5ed5219df8a 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java @@ -3850,23 +3850,11 @@ public class CardFactoryUtil { inst.addSpellAbility(sa); } else if (keyword.startsWith("Dash")) { final String[] k = keyword.split(":"); - final String dashString = "SP$ PermanentCreature | Cost$ " + k[1] + " | SubAbility$" - + " DashDelayedTrigger"; - final String dbDelayTrigger = "DB$ DelayedTrigger | Mode$ Phase | Phase$" - + " End of Turn | Execute$ DashReturnSelf | RememberObjects$ Self" - + " | TriggerDescription$ Return CARDNAME from the battlefield to" + " its owner's hand."; - final String dbReturn = "DB$ ChangeZone | Origin$ Battlefield | Destination$ Hand" - + " | Defined$ DelayTriggerRemembered"; - card.setSVar("DashDelayedTrigger", dbDelayTrigger); - card.setSVar("DashReturnSelf", dbReturn); + final String dashString = "SP$ PermanentCreature | Cost$ " + k[1] + " | StackDescription$ CARDNAME (Dash)" + + " | Dash$ True | NonBasicSpell$ True" + + " | SpellDescription$ Dash " + ManaCostParser.parse(k[1]) + " (" + inst.getReminderText() + ")"; final SpellAbility newSA = AbilityFactory.getAbility(dashString, card); - String desc = "Dash " + ManaCostParser.parse(k[1]) + " (" + inst.getReminderText() - + ")"; - newSA.setStackDescription(card.getName() + " (Dash)"); - newSA.setDescription(desc); - newSA.setBasicSpell(false); - newSA.setDash(true); newSA.setIntrinsic(intrinsic); newSA.setTemporary(!intrinsic); @@ -4527,6 +4515,8 @@ public class CardFactoryUtil { card.setSVar("CipherTrigger", trig); card.setSVar("PlayEncoded", ab); + } else if (keyword.startsWith("Dash")) { + effect = "Mode$ Continuous | Affected$ Card.Self+dashed | AddKeyword$ Haste"; } else if (keyword.equals("Devoid")) { effect = "Mode$ Continuous | EffectZone$ All | Affected$ Card.Self" + " | CharacteristicDefining$ True | SetColor$ Colorless | Secondary$ True" + diff --git a/forge-game/src/main/java/forge/game/card/CardProperty.java b/forge-game/src/main/java/forge/game/card/CardProperty.java index 8828cc02790..6be6628b541 100644 --- a/forge-game/src/main/java/forge/game/card/CardProperty.java +++ b/forge-game/src/main/java/forge/game/card/CardProperty.java @@ -1639,6 +1639,11 @@ public class CardProperty { return false; } return card.getCastSA().isSurged(); + } else if (property.startsWith("dashed")) { + if (card.getCastSA() == null) { + return false; + } + return card.getCastSA().isDash(); } else if (property.startsWith("evoked")) { if (card.getCastSA() == null) { return false; From b23f3d9acc28553ad3fa55890787a48280a38a97 Mon Sep 17 00:00:00 2001 From: Peter Date: Tue, 30 Jul 2019 14:24:54 +0200 Subject: [PATCH 3/3] Fix: We need to pass &face=back to API in order to download backface images correctly. --- .../src/main/java/forge/download/GuiDownloadPicturesHQ.java | 1 + 1 file changed, 1 insertion(+) diff --git a/forge-gui/src/main/java/forge/download/GuiDownloadPicturesHQ.java b/forge-gui/src/main/java/forge/download/GuiDownloadPicturesHQ.java index 8e3e5b95802..cd97aacc017 100644 --- a/forge-gui/src/main/java/forge/download/GuiDownloadPicturesHQ.java +++ b/forge-gui/src/main/java/forge/download/GuiDownloadPicturesHQ.java @@ -94,6 +94,7 @@ public class GuiDownloadPicturesHQ extends GuiDownloadService { cardname = cardname.replace("'", ""); String scryfallurl = ForgeConstants.URL_PIC_SCRYFALL_DOWNLOAD + "named?fuzzy=" + cardname; if(!setCode.equals("???")) scryfallurl += "&set=" + setCode.toLowerCase(); + if(backFace) scryfallurl += "&face=back"; scryfallurl += "&format=image"; downloads.put(destPath, scryfallurl);