gui: fixed that faced-down permanents don't show acquired characteristics like color from Painter's Servant (part of #11873)

This commit is contained in:
Oleg Agafonov 2024-02-29 09:50:18 +04:00
parent 734e2fae0f
commit 7696839724
3 changed files with 78 additions and 10 deletions

View file

@ -353,12 +353,15 @@ public class CardView extends SimpleCardView {
this.fillEmptyWithImageInfo(game, card, true);
// can show face up card name for controller or game end
// TODO: add exception on non empty name of the faced-down card here
String visibleName = CardUtil.getCardNameForGUI(showHiddenFaceDownData ? sourceName : "", this.imageFileName);
this.name = visibleName;
this.displayName = visibleName;
this.displayFullName = visibleName;
this.alternateName = visibleName;
// TODO: remove workaround - all actual characteristics must get from a card -- same as normal card do
// TODO: must use same code in all zones
// workaround to add PT, creature type and face up ability text (for stack and battlefield zones only)
// in other zones it has only face down status/name
if (sourceCard instanceof Spell
@ -366,6 +369,9 @@ public class CardView extends SimpleCardView {
this.power = Integer.toString(card.getPower().getValue());
this.toughness = Integer.toString(card.getToughness().getValue());
this.cardTypes = new ArrayList<>(card.getCardType());
this.color = card.getColor(null);
this.superTypes = new ArrayList<>(card.getSuperType());
this.subTypes = card.getSubtype().copy();
this.rules = new ArrayList<>(card.getRules());
// additional rules for stack (example: morph ability text)
@ -507,6 +513,8 @@ public class CardView extends SimpleCardView {
// FACE UP INFO
if (showFaceUp) {
// TODO: extract characteristics setup to shared code (same for face down and normal cards)
// PT, card types/subtypes/super/color/rules
this.power = Integer.toString(card.getPower().getValue());
this.toughness = Integer.toString(card.getToughness().getValue());
this.cardTypes = new ArrayList<>(card.getCardType(game));

View file

@ -4,6 +4,9 @@ import mage.cards.Card;
import mage.constants.*;
import mage.filter.Filter;
import mage.game.permanent.Permanent;
import mage.view.GameView;
import mage.view.PermanentView;
import mage.view.PlayerView;
import org.junit.Assert;
import org.junit.Test;
import org.mage.test.player.TestPlayer;
@ -1224,4 +1227,69 @@ public class MorphTest extends CardTestPlayerBase {
assertPowerToughness(playerA, EmptyNames.FACE_DOWN_CREATURE.toString(), 2, 3);
}
private void assertMorphedFaceDownColor(String info, String needColor) {
Permanent permanent = currentGame.getBattlefield().getAllPermanents()
.stream()
.filter(Permanent::isMorphed)
.findFirst()
.orElse(null);
Assert.assertNotNull(info + ", server side: can't find morphed permanent", permanent);
Assert.assertEquals(info + ", server side: wrong name", EmptyNames.FACE_DOWN_CREATURE.toString(), permanent.getName());
Assert.assertEquals(info + ", server side: wrong color", needColor, permanent.getColor(currentGame).toString());
// client side - controller
GameView gameView = getGameView(playerA);
PermanentView permanentView = gameView.getMyPlayer().getBattlefield().values()
.stream()
.filter(PermanentView::isMorphed)
.findFirst()
.orElse(null);
Assert.assertNotNull(info + ", client side - controller: can't find morphed permanent", permanentView);
Assert.assertEquals(info + ", client side - controller: wrong name", "Morph: Zoetic Cavern", permanentView.getName());
Assert.assertEquals(info + ", client side - controller: wrong color", needColor, permanentView.getColor().toString());
// client side - opponent
gameView = getGameView(playerB);
PlayerView playerView = gameView.getPlayers().stream().filter(p -> p.getName().equals(playerA.getName())).findFirst().orElse(null);
Assert.assertNotNull(playerView);
permanentView = playerView.getBattlefield().values()
.stream()
.filter(PermanentView::isMorphed)
.findFirst()
.orElse(null);
Assert.assertNotNull(info + ", client side - opponent: can't find morphed permanent", permanentView);
Assert.assertEquals(info + ", client side - opponent: wrong name", "Morph", permanentView.getName());
Assert.assertEquals(info + ", client side - opponent: wrong color", needColor, permanentView.getColor().toString());
}
@Test
public void test_Morph_MustGetColor() {
// Morph {2}
addCard(Zone.HAND, playerA, "Zoetic Cavern");
addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
//
// As Painter's Servant enters the battlefield, choose a color.
// All cards that aren't on the battlefield, spells, and permanents are the chosen color in addition to their other colors.
addCard(Zone.HAND, playerA, "Painter's Servant"); // {2}
addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
// prepare face down
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Zoetic Cavern using Morph");
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA);
runCode("face down before color", 1, PhaseStep.PRECOMBAT_MAIN, playerA, (info, player, game) -> {
assertMorphedFaceDownColor(info, "");
});
// add effect with new green color for a face down
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Painter's Servant");
setChoice(playerA, "Green");
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA);
runCode("face down with G color", 1, PhaseStep.PRECOMBAT_MAIN, playerA, (info, player, game) -> {
assertMorphedFaceDownColor(info, "G");
});
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
execute();
}
}

View file

@ -167,9 +167,7 @@ public class TokenImagesTest extends CardTestPlayerBase {
// collect real client stats
Map<String, List<PermanentView>> realClientStats = new LinkedHashMap<>();
GameView gameView = new GameView(currentGame.getState(), currentGame, playerA.getId(), null);
PlayerView playerView = gameView.getPlayers().stream().filter(p -> p.getName().equals(playerA.getName())).findFirst().orElse(null);
Assert.assertNotNull(playerView);
playerView.getBattlefield().values()
gameView.getMyPlayer().getBattlefield().values()
.stream()
.filter(card -> card.getName().equals(tokenName))
.filter(CardView::isToken)
@ -277,13 +275,7 @@ public class TokenImagesTest extends CardTestPlayerBase {
.collect(Collectors.toSet());
GameView gameView = new GameView(currentGame.getState(), currentGame, playerA.getId(), null);
PlayerView playerView = gameView.getPlayers()
.stream()
.filter(p -> p.getName().equals(playerA.getName()))
.findFirst()
.orElse(null);
Assert.assertNotNull(playerView);
Set<Integer> clientStats = playerView.getBattlefield().values()
Set<Integer> clientStats = gameView.getMyPlayer().getBattlefield().values()
.stream()
.filter(card -> card.getName().equals(tokenOrCardName))
.sorted(Comparator.comparing(CardView::getExpansionSetCode))