From a8211c3da3ce55cd5fb66a5dcdb00007d6887e4d Mon Sep 17 00:00:00 2001 From: tool4ever Date: Sun, 7 Apr 2024 22:28:23 +0200 Subject: [PATCH] Fix ChangeZone* not always shuffling (#4976) * Support nicknames for non-rebranded * Fix ChangeZone* not always shuffling --- .../src/main/java/forge/card/CardDb.java | 17 ++++++++-- .../ability/effects/ChangeZoneAllEffect.java | 13 +++----- .../ability/effects/ChangeZoneEffect.java | 32 ++++++++++--------- .../forge/game/ability/effects/DigEffect.java | 1 - .../ability/effects/ManifestBaseEffect.java | 3 +- .../res/cardsfolder/t/temporary_truce.txt | 2 +- forge-gui/res/cardsfolder/t/truce.txt | 2 +- 7 files changed, 40 insertions(+), 30 deletions(-) diff --git a/forge-core/src/main/java/forge/card/CardDb.java b/forge-core/src/main/java/forge/card/CardDb.java index 896592d415a..cff69842f03 100644 --- a/forge-core/src/main/java/forge/card/CardDb.java +++ b/forge-core/src/main/java/forge/card/CardDb.java @@ -30,6 +30,8 @@ import forge.item.PaperCard; import forge.util.CollectionSuppliers; import forge.util.Lang; import forge.util.TextUtil; +import forge.util.lang.LangEnglish; + import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; @@ -371,6 +373,11 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { } private void buildRenamedCards() { + Lang lang = Lang.getInstance(); + if (lang == null) { + // for some tests + lang = new LangEnglish(); + } // for now just check Universes Within for (CardInSet cis : editions.get("SLX").getCards()) { String orgName = alternateName.get(cis.name); @@ -382,7 +389,10 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { renamedMain.setName(renamedMain.getAltName()); renamedMain.setAltName(null); // TODO this could mess up some "named ..." cardname literals but there's no printing like that currently - renamedMain.setOracleText(renamedMain.getOracleText().replace(orgName, renamedMain.getName())); + renamedMain.setOracleText(renamedMain.getOracleText() + .replace(orgName, renamedMain.getName()) + .replace(lang.getNickName(orgName), lang.getNickName(renamedMain.getName())) + ); facesByName.put(renamedMain.getName(), renamedMain); CardFace renamedOther = null; if (org.getOtherPart() != null) { @@ -390,7 +400,10 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { orgName = renamedOther.getName(); renamedOther.setName(renamedOther.getAltName()); renamedOther.setAltName(null); - renamedOther.setOracleText(renamedOther.getOracleText().replace(orgName, renamedOther.getName())); + renamedOther.setOracleText(renamedOther.getOracleText() + .replace(orgName, renamedOther.getName()) + .replace(lang.getNickName(orgName), lang.getNickName(renamedOther.getName())) + ); facesByName.put(renamedOther.getName(), renamedOther); } 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 9445c84ac3b..289468cc4ce 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 @@ -36,12 +36,11 @@ public class ChangeZoneAllEffect extends SpellAbilityEffect { @Override public void resolve(SpellAbility sa) { - final Card source = sa.getHostCard(); - if (!checkValidDuration(sa.getParam("Duration"), sa)) { return; } + final Card source = sa.getHostCard(); final ZoneType destination = ZoneType.smartValueOf(sa.getParam("Destination")); final List origin = ZoneType.listValueOf(sa.getParam("Origin")); @@ -239,13 +238,11 @@ public class ChangeZoneAllEffect extends SpellAbilityEffect { addUntilCommand(sa, untilHostLeavesPlayCommand(triggerList, sa)); } - // if Shuffle parameter exists, and any amount of cards were owned by - // that player, then shuffle that library + // CR 701.20d If an effect would cause a player to shuffle a set of objects into a library, + // that library is shuffled even if there are no objects in that set. if (sa.hasParam("Shuffle")) { - for (Player p : game.getPlayers()) { - if (Iterables.any(cards, CardPredicates.isOwner(p))) { - p.shuffle(sa); - } + for (Player p : tgtPlayers) { + p.shuffle(sa); } } } 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 faee13d98e1..ffdbdb3aa68 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 @@ -450,9 +450,9 @@ public class ChangeZoneEffect extends SpellAbilityEffect { */ private void changeKnownOriginResolve(final SpellAbility sa) { CardCollectionView tgtCards = getTargetCards(sa); - final Player player = sa.getActivatingPlayer(); + final Player activator = sa.getActivatingPlayer(); final Card hostCard = sa.getHostCard(); - final Game game = player.getGame(); + final Game game = activator.getGame(); final CardCollection commandCards = new CardCollection(); ZoneType destination = ZoneType.smartValueOf(sa.getParam("Destination")); @@ -464,7 +464,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect { int libraryPosition = sa.hasParam("LibraryPosition") ? AbilityUtils.calculateAmount(hostCard, sa.getParam("LibraryPosition"), sa) : 0; if (sa.hasParam("DestinationAlternative")) { - Pair pair = handleAltDest(sa, hostCard, destination, libraryPosition, player); + Pair pair = handleAltDest(sa, hostCard, destination, libraryPosition, activator); destination = pair.getKey(); libraryPosition = pair.getValue(); } @@ -503,7 +503,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect { final boolean shuffle = sa.hasParam("Shuffle") && "True".equals(sa.getParam("Shuffle")); boolean combatChanged = false; - Player chooser = player; + Player chooser = activator; if (sa.hasParam("Chooser")) { chooser = AbilityUtils.getDefinedPlayers(hostCard, sa.getParam("Chooser"), sa).get(0); } @@ -588,11 +588,11 @@ public class ChangeZoneEffect extends SpellAbilityEffect { if (sa.hasParam("WithCountersType")) { CounterType cType = CounterType.getType(sa.getParam("WithCountersType")); int cAmount = AbilityUtils.calculateAmount(hostCard, sa.getParamOrDefault("WithCountersAmount", "1"), sa); - gameCard.addEtbCounter(cType, cAmount, player); + gameCard.addEtbCounter(cType, cAmount, activator); } if (sa.hasParam("GainControl")) { final String g = sa.getParam("GainControl"); - Player newController = g.equals("True") ? player : + Player newController = g.equals("True") ? activator : AbilityUtils.getDefinedPlayers(hostCard, g, sa).get(0); if (newController != null) { if (newController != gameCard.getController()) { @@ -615,7 +615,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect { if (!list.isEmpty()) { Map params = Maps.newHashMap(); params.put("Attach", gameCard); - Card attachedTo = player.getController().chooseSingleEntityForEffect(list, sa, Localizer.getInstance().getMessage("lblSelectACardAttachSourceTo", gameCard.toString()), params); + Card attachedTo = activator.getController().chooseSingleEntityForEffect(list, sa, Localizer.getInstance().getMessage("lblSelectACardAttachSourceTo", gameCard.toString()), params); // TODO can't attach later or moveToPlay would attach indirectly // bypass canBeAttached to skip Protection checks when trying to attach multiple auras that would grant protection @@ -630,7 +630,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect { if (!list.isEmpty()) { Map params = Maps.newHashMap(); params.put("Attach", gameCard); - Player attachedTo = player.getController().chooseSingleEntityForEffect(list, sa, Localizer.getInstance().getMessage("lblSelectAPlayerAttachSourceTo", gameCard.toString()), params); + Player attachedTo = activator.getController().chooseSingleEntityForEffect(list, sa, Localizer.getInstance().getMessage("lblSelectAPlayerAttachSourceTo", gameCard.toString()), params); gameCard.attachToEntity(attachedTo, sa); } else { // When it should enter the battlefield attached to an illegal player it fails @@ -715,7 +715,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect { if (ZoneType.Hand.equals(destination) && ZoneType.Command.equals(originZone.getZoneType())) { StringBuilder sb = new StringBuilder(); - sb.append(movedCard.getName()).append(" has moved from Command Zone to ").append(player).append("'s hand."); + sb.append(movedCard.getName()).append(" has moved from Command Zone to ").append(activator).append("'s hand."); game.getGameLog().add(GameLogEntryType.ZONE_CHANGE, sb.toString()); commandCards.add(movedCard); //add to list to reveal the commandzone cards } @@ -732,7 +732,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect { if (sa.hasParam("WithCountersType")) { CounterType cType = CounterType.getType(sa.getParam("WithCountersType")); int cAmount = AbilityUtils.calculateAmount(hostCard, sa.getParamOrDefault("WithCountersAmount", "1"), sa); - movedCard.addCounter(cType, cAmount, player, counterTable); + movedCard.addCounter(cType, cAmount, activator, counterTable); } if (sa.hasParam("ExileFaceDown") || sa.hasParam("FaceDown")) { @@ -744,7 +744,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect { movedCard.setForetoldCostByEffect(true); } // look at the exiled card - movedCard.addMayLookTemp(player); + movedCard.addMayLookTemp(activator); } // CR 400.7k @@ -759,7 +759,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect { if (sa.hasParam("WithCountersType")) { CounterType cType = CounterType.getType(sa.getParam("WithCountersType")); int cAmount = AbilityUtils.calculateAmount(hostCard, sa.getParamOrDefault("WithCountersAmount", "1"), sa); - meld.addCounter(cType, cAmount, player, counterTable); + meld.addCounter(cType, cAmount, activator, counterTable); } } if (gameCard.hasMergedCard()) { @@ -768,7 +768,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect { if (sa.hasParam("WithCountersType")) { CounterType cType = CounterType.getType(sa.getParam("WithCountersType")); int cAmount = AbilityUtils.calculateAmount(hostCard, sa.getParamOrDefault("WithCountersAmount", "1"), sa); - c.addCounter(cType, cAmount, player, counterTable); + c.addCounter(cType, cAmount, activator, counterTable); } } } @@ -819,7 +819,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect { //reveal command cards that changes zone from command zone to player's hand if (!commandCards.isEmpty()) { - game.getAction().reveal(commandCards, player, true, "Revealed cards in "); + game.getAction().reveal(commandCards, activator, true, "Revealed cards in "); } triggerList.triggerChangesZoneAll(game, sa); @@ -848,8 +848,10 @@ public class ChangeZoneEffect extends SpellAbilityEffect { // FCollection already does use set. pl.add(tgtC.getOwner()); } + if (pl.isEmpty()) { + pl.add(activator); + } } - for (final Player p : pl) { p.shuffle(sa); } 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 983068a1bd8..97120ea9097 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 @@ -491,7 +491,6 @@ public class DigEffect extends SpellAbilityEffect { } } } - } } } diff --git a/forge-game/src/main/java/forge/game/ability/effects/ManifestBaseEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ManifestBaseEffect.java index 3c158733713..3fc3347c51f 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ManifestBaseEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ManifestBaseEffect.java @@ -25,8 +25,7 @@ public abstract class ManifestBaseEffect extends SpellAbilityEffect { final Player activator = sa.getActivatingPlayer(); final Game game = source.getGame(); // Usually a number leaving possibility for X, Sacrifice X land: Manifest X creatures. - final int amount = sa.hasParam("Amount") ? AbilityUtils.calculateAmount(source, - sa.getParam("Amount"), sa) : 1; + final int amount = sa.hasParam("Amount") ? AbilityUtils.calculateAmount(source, sa.getParam("Amount"), sa) : 1; for (final Player p : getTargetPlayers(sa, "DefinedPlayer")) { CardCollection tgtCards; diff --git a/forge-gui/res/cardsfolder/t/temporary_truce.txt b/forge-gui/res/cardsfolder/t/temporary_truce.txt index 57378fe198f..01d35056c0c 100644 --- a/forge-gui/res/cardsfolder/t/temporary_truce.txt +++ b/forge-gui/res/cardsfolder/t/temporary_truce.txt @@ -4,7 +4,7 @@ Types:Sorcery A:SP$ Draw | Defined$ Player | Upto$ True | NumCards$ 2 | SubAbility$ DBRepeat | AILogic$ GainLife | SpellDescription$ Each player may draw up to two cards. For each card less than two a player draws this way, that player gains 2 life. SVar:DBRepeat:DB$ RepeatEach | RepeatPlayers$ Player | RepeatSubAbility$ DBGainLife | StackDescription$ For each card less than two a player draws this way, that player gains 2 life. SVar:DBGainLife:DB$ GainLife | LifeAmount$ AFNotDrawnNum | Defined$ Player.IsRemembered -SVar:Y:Count$SVar$AFNotDrawnNum/NMinus.2 +SVar:Y:SVar$AFNotDrawnNum/NMinus.2 SVar:X:SVar$Y/Twice AI:RemoveDeck:All Oracle:Each player may draw up to two cards. For each card less than two a player draws this way, that player gains 2 life. diff --git a/forge-gui/res/cardsfolder/t/truce.txt b/forge-gui/res/cardsfolder/t/truce.txt index 5c7c108a184..2a91a8a5ecb 100644 --- a/forge-gui/res/cardsfolder/t/truce.txt +++ b/forge-gui/res/cardsfolder/t/truce.txt @@ -4,7 +4,7 @@ Types:Instant A:SP$ Draw | Defined$ Player | Upto$ True | NumCards$ 2 | SubAbility$ DBRepeat | AILogic$ GainLife | SpellDescription$ Each player may draw up to two cards. For each card less than two a player draws this way, that player gains 2 life. SVar:DBRepeat:DB$ RepeatEach | RepeatPlayers$ Player | RepeatSubAbility$ DBGainLife | StackDescription$ For each card less than two a player draws this way, that player gains 2 life. SVar:DBGainLife:DB$ GainLife | LifeAmount$ AFNotDrawnNum | Defined$ Player.IsRemembered -SVar:Y:Count$SVar$AFNotDrawnNum/NMinus.2 +SVar:Y:SVar$AFNotDrawnNum/NMinus.2 SVar:X:SVar$Y/Twice AI:RemoveDeck:All Oracle:Each player may draw up to two cards. For each card less than two a player draws this way, that player gains 2 life.