mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-15 18:28:00 +00:00
Fix ChangeZone* not always shuffling (#4976)
* Support nicknames for non-rebranded * Fix ChangeZone* not always shuffling
This commit is contained in:
@@ -30,6 +30,8 @@ import forge.item.PaperCard;
|
|||||||
import forge.util.CollectionSuppliers;
|
import forge.util.CollectionSuppliers;
|
||||||
import forge.util.Lang;
|
import forge.util.Lang;
|
||||||
import forge.util.TextUtil;
|
import forge.util.TextUtil;
|
||||||
|
import forge.util.lang.LangEnglish;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
@@ -371,6 +373,11 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void buildRenamedCards() {
|
private void buildRenamedCards() {
|
||||||
|
Lang lang = Lang.getInstance();
|
||||||
|
if (lang == null) {
|
||||||
|
// for some tests
|
||||||
|
lang = new LangEnglish();
|
||||||
|
}
|
||||||
// for now just check Universes Within
|
// for now just check Universes Within
|
||||||
for (CardInSet cis : editions.get("SLX").getCards()) {
|
for (CardInSet cis : editions.get("SLX").getCards()) {
|
||||||
String orgName = alternateName.get(cis.name);
|
String orgName = alternateName.get(cis.name);
|
||||||
@@ -382,7 +389,10 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
|
|||||||
renamedMain.setName(renamedMain.getAltName());
|
renamedMain.setName(renamedMain.getAltName());
|
||||||
renamedMain.setAltName(null);
|
renamedMain.setAltName(null);
|
||||||
// TODO this could mess up some "named ..." cardname literals but there's no printing like that currently
|
// 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);
|
facesByName.put(renamedMain.getName(), renamedMain);
|
||||||
CardFace renamedOther = null;
|
CardFace renamedOther = null;
|
||||||
if (org.getOtherPart() != null) {
|
if (org.getOtherPart() != null) {
|
||||||
@@ -390,7 +400,10 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
|
|||||||
orgName = renamedOther.getName();
|
orgName = renamedOther.getName();
|
||||||
renamedOther.setName(renamedOther.getAltName());
|
renamedOther.setName(renamedOther.getAltName());
|
||||||
renamedOther.setAltName(null);
|
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);
|
facesByName.put(renamedOther.getName(), renamedOther);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,12 +36,11 @@ public class ChangeZoneAllEffect extends SpellAbilityEffect {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void resolve(SpellAbility sa) {
|
public void resolve(SpellAbility sa) {
|
||||||
final Card source = sa.getHostCard();
|
|
||||||
|
|
||||||
if (!checkValidDuration(sa.getParam("Duration"), sa)) {
|
if (!checkValidDuration(sa.getParam("Duration"), sa)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final Card source = sa.getHostCard();
|
||||||
final ZoneType destination = ZoneType.smartValueOf(sa.getParam("Destination"));
|
final ZoneType destination = ZoneType.smartValueOf(sa.getParam("Destination"));
|
||||||
final List<ZoneType> origin = ZoneType.listValueOf(sa.getParam("Origin"));
|
final List<ZoneType> origin = ZoneType.listValueOf(sa.getParam("Origin"));
|
||||||
|
|
||||||
@@ -239,13 +238,11 @@ public class ChangeZoneAllEffect extends SpellAbilityEffect {
|
|||||||
addUntilCommand(sa, untilHostLeavesPlayCommand(triggerList, sa));
|
addUntilCommand(sa, untilHostLeavesPlayCommand(triggerList, sa));
|
||||||
}
|
}
|
||||||
|
|
||||||
// if Shuffle parameter exists, and any amount of cards were owned by
|
// CR 701.20d If an effect would cause a player to shuffle a set of objects into a library,
|
||||||
// that player, then shuffle that library
|
// that library is shuffled even if there are no objects in that set.
|
||||||
if (sa.hasParam("Shuffle")) {
|
if (sa.hasParam("Shuffle")) {
|
||||||
for (Player p : game.getPlayers()) {
|
for (Player p : tgtPlayers) {
|
||||||
if (Iterables.any(cards, CardPredicates.isOwner(p))) {
|
p.shuffle(sa);
|
||||||
p.shuffle(sa);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -450,9 +450,9 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
*/
|
*/
|
||||||
private void changeKnownOriginResolve(final SpellAbility sa) {
|
private void changeKnownOriginResolve(final SpellAbility sa) {
|
||||||
CardCollectionView tgtCards = getTargetCards(sa);
|
CardCollectionView tgtCards = getTargetCards(sa);
|
||||||
final Player player = sa.getActivatingPlayer();
|
final Player activator = sa.getActivatingPlayer();
|
||||||
final Card hostCard = sa.getHostCard();
|
final Card hostCard = sa.getHostCard();
|
||||||
final Game game = player.getGame();
|
final Game game = activator.getGame();
|
||||||
final CardCollection commandCards = new CardCollection();
|
final CardCollection commandCards = new CardCollection();
|
||||||
|
|
||||||
ZoneType destination = ZoneType.smartValueOf(sa.getParam("Destination"));
|
ZoneType destination = ZoneType.smartValueOf(sa.getParam("Destination"));
|
||||||
@@ -464,7 +464,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
int libraryPosition = sa.hasParam("LibraryPosition") ?
|
int libraryPosition = sa.hasParam("LibraryPosition") ?
|
||||||
AbilityUtils.calculateAmount(hostCard, sa.getParam("LibraryPosition"), sa) : 0;
|
AbilityUtils.calculateAmount(hostCard, sa.getParam("LibraryPosition"), sa) : 0;
|
||||||
if (sa.hasParam("DestinationAlternative")) {
|
if (sa.hasParam("DestinationAlternative")) {
|
||||||
Pair<ZoneType, Integer> pair = handleAltDest(sa, hostCard, destination, libraryPosition, player);
|
Pair<ZoneType, Integer> pair = handleAltDest(sa, hostCard, destination, libraryPosition, activator);
|
||||||
destination = pair.getKey();
|
destination = pair.getKey();
|
||||||
libraryPosition = pair.getValue();
|
libraryPosition = pair.getValue();
|
||||||
}
|
}
|
||||||
@@ -503,7 +503,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
final boolean shuffle = sa.hasParam("Shuffle") && "True".equals(sa.getParam("Shuffle"));
|
final boolean shuffle = sa.hasParam("Shuffle") && "True".equals(sa.getParam("Shuffle"));
|
||||||
boolean combatChanged = false;
|
boolean combatChanged = false;
|
||||||
|
|
||||||
Player chooser = player;
|
Player chooser = activator;
|
||||||
if (sa.hasParam("Chooser")) {
|
if (sa.hasParam("Chooser")) {
|
||||||
chooser = AbilityUtils.getDefinedPlayers(hostCard, sa.getParam("Chooser"), sa).get(0);
|
chooser = AbilityUtils.getDefinedPlayers(hostCard, sa.getParam("Chooser"), sa).get(0);
|
||||||
}
|
}
|
||||||
@@ -588,11 +588,11 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
if (sa.hasParam("WithCountersType")) {
|
if (sa.hasParam("WithCountersType")) {
|
||||||
CounterType cType = CounterType.getType(sa.getParam("WithCountersType"));
|
CounterType cType = CounterType.getType(sa.getParam("WithCountersType"));
|
||||||
int cAmount = AbilityUtils.calculateAmount(hostCard, sa.getParamOrDefault("WithCountersAmount", "1"), sa);
|
int cAmount = AbilityUtils.calculateAmount(hostCard, sa.getParamOrDefault("WithCountersAmount", "1"), sa);
|
||||||
gameCard.addEtbCounter(cType, cAmount, player);
|
gameCard.addEtbCounter(cType, cAmount, activator);
|
||||||
}
|
}
|
||||||
if (sa.hasParam("GainControl")) {
|
if (sa.hasParam("GainControl")) {
|
||||||
final String g = sa.getParam("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);
|
AbilityUtils.getDefinedPlayers(hostCard, g, sa).get(0);
|
||||||
if (newController != null) {
|
if (newController != null) {
|
||||||
if (newController != gameCard.getController()) {
|
if (newController != gameCard.getController()) {
|
||||||
@@ -615,7 +615,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
if (!list.isEmpty()) {
|
if (!list.isEmpty()) {
|
||||||
Map<String, Object> params = Maps.newHashMap();
|
Map<String, Object> params = Maps.newHashMap();
|
||||||
params.put("Attach", gameCard);
|
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
|
// 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
|
// 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()) {
|
if (!list.isEmpty()) {
|
||||||
Map<String, Object> params = Maps.newHashMap();
|
Map<String, Object> params = Maps.newHashMap();
|
||||||
params.put("Attach", gameCard);
|
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);
|
gameCard.attachToEntity(attachedTo, sa);
|
||||||
}
|
}
|
||||||
else { // When it should enter the battlefield attached to an illegal player it fails
|
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())) {
|
if (ZoneType.Hand.equals(destination) && ZoneType.Command.equals(originZone.getZoneType())) {
|
||||||
StringBuilder sb = new StringBuilder();
|
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());
|
game.getGameLog().add(GameLogEntryType.ZONE_CHANGE, sb.toString());
|
||||||
commandCards.add(movedCard); //add to list to reveal the commandzone cards
|
commandCards.add(movedCard); //add to list to reveal the commandzone cards
|
||||||
}
|
}
|
||||||
@@ -732,7 +732,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
if (sa.hasParam("WithCountersType")) {
|
if (sa.hasParam("WithCountersType")) {
|
||||||
CounterType cType = CounterType.getType(sa.getParam("WithCountersType"));
|
CounterType cType = CounterType.getType(sa.getParam("WithCountersType"));
|
||||||
int cAmount = AbilityUtils.calculateAmount(hostCard, sa.getParamOrDefault("WithCountersAmount", "1"), sa);
|
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")) {
|
if (sa.hasParam("ExileFaceDown") || sa.hasParam("FaceDown")) {
|
||||||
@@ -744,7 +744,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
movedCard.setForetoldCostByEffect(true);
|
movedCard.setForetoldCostByEffect(true);
|
||||||
}
|
}
|
||||||
// look at the exiled card
|
// look at the exiled card
|
||||||
movedCard.addMayLookTemp(player);
|
movedCard.addMayLookTemp(activator);
|
||||||
}
|
}
|
||||||
|
|
||||||
// CR 400.7k
|
// CR 400.7k
|
||||||
@@ -759,7 +759,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
if (sa.hasParam("WithCountersType")) {
|
if (sa.hasParam("WithCountersType")) {
|
||||||
CounterType cType = CounterType.getType(sa.getParam("WithCountersType"));
|
CounterType cType = CounterType.getType(sa.getParam("WithCountersType"));
|
||||||
int cAmount = AbilityUtils.calculateAmount(hostCard, sa.getParamOrDefault("WithCountersAmount", "1"), sa);
|
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()) {
|
if (gameCard.hasMergedCard()) {
|
||||||
@@ -768,7 +768,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
if (sa.hasParam("WithCountersType")) {
|
if (sa.hasParam("WithCountersType")) {
|
||||||
CounterType cType = CounterType.getType(sa.getParam("WithCountersType"));
|
CounterType cType = CounterType.getType(sa.getParam("WithCountersType"));
|
||||||
int cAmount = AbilityUtils.calculateAmount(hostCard, sa.getParamOrDefault("WithCountersAmount", "1"), sa);
|
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
|
//reveal command cards that changes zone from command zone to player's hand
|
||||||
if (!commandCards.isEmpty()) {
|
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);
|
triggerList.triggerChangesZoneAll(game, sa);
|
||||||
@@ -848,8 +848,10 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
// FCollection already does use set.
|
// FCollection already does use set.
|
||||||
pl.add(tgtC.getOwner());
|
pl.add(tgtC.getOwner());
|
||||||
}
|
}
|
||||||
|
if (pl.isEmpty()) {
|
||||||
|
pl.add(activator);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final Player p : pl) {
|
for (final Player p : pl) {
|
||||||
p.shuffle(sa);
|
p.shuffle(sa);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -491,7 +491,6 @@ public class DigEffect extends SpellAbilityEffect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,8 +25,7 @@ public abstract class ManifestBaseEffect extends SpellAbilityEffect {
|
|||||||
final Player activator = sa.getActivatingPlayer();
|
final Player activator = sa.getActivatingPlayer();
|
||||||
final Game game = source.getGame();
|
final Game game = source.getGame();
|
||||||
// Usually a number leaving possibility for X, Sacrifice X land: Manifest X creatures.
|
// Usually a number leaving possibility for X, Sacrifice X land: Manifest X creatures.
|
||||||
final int amount = sa.hasParam("Amount") ? AbilityUtils.calculateAmount(source,
|
final int amount = sa.hasParam("Amount") ? AbilityUtils.calculateAmount(source, sa.getParam("Amount"), sa) : 1;
|
||||||
sa.getParam("Amount"), sa) : 1;
|
|
||||||
|
|
||||||
for (final Player p : getTargetPlayers(sa, "DefinedPlayer")) {
|
for (final Player p : getTargetPlayers(sa, "DefinedPlayer")) {
|
||||||
CardCollection tgtCards;
|
CardCollection tgtCards;
|
||||||
|
|||||||
@@ -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.
|
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: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: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
|
SVar:X:SVar$Y/Twice
|
||||||
AI:RemoveDeck:All
|
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.
|
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.
|
||||||
|
|||||||
@@ -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.
|
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: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: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
|
SVar:X:SVar$Y/Twice
|
||||||
AI:RemoveDeck:All
|
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.
|
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.
|
||||||
|
|||||||
Reference in New Issue
Block a user