gui: fixed miss playable mark for emblems and other objects from command zone (example: momir emblem)

This commit is contained in:
Oleg Agafonov 2023-06-17 17:32:02 +04:00
parent 7a33ca812c
commit 94dfbdfed4
4 changed files with 39 additions and 11 deletions

View file

@ -59,7 +59,7 @@ public final class CardsViewUtil {
} else if (commandObject instanceof CommanderView) { } else if (commandObject instanceof CommanderView) {
cardView = (CommanderView) commandObject; cardView = (CommanderView) commandObject;
} else { } else {
continue; throw new IllegalStateException("ERROR, unsupported commander object type: " + commandObject.getClass().getSimpleName());
} }
cards.put(commandObject.getId(), cardView); cards.put(commandObject.getId(), cardView);
} }

View file

@ -241,6 +241,10 @@ public class CardView extends SimpleCardView {
if (cardView.cardIcons != null) { if (cardView.cardIcons != null) {
cardView.cardIcons.forEach(icon -> this.cardIcons.add(icon.copy())); cardView.cardIcons.forEach(icon -> this.cardIcons.add(icon.copy()));
} }
this.playableStats = cardView.playableStats.copy();
this.isChoosable = cardView.isChoosable;
this.isSelected = cardView.isSelected;
} }
/** /**
@ -698,6 +702,10 @@ public class CardView extends SimpleCardView {
this.cardNumber = ""; this.cardNumber = "";
this.imageNumber = 0; this.imageNumber = 0;
this.rarity = Rarity.COMMON; this.rarity = Rarity.COMMON;
this.playableStats = emblem.playableStats.copy();
this.isChoosable = emblem.isChoosable();
this.isSelected = emblem.isSelected();
} }
public CardView(DungeonView dungeon) { public CardView(DungeonView dungeon) {
@ -716,6 +724,10 @@ public class CardView extends SimpleCardView {
this.cardNumber = ""; this.cardNumber = "";
this.imageNumber = 0; this.imageNumber = 0;
this.rarity = Rarity.COMMON; this.rarity = Rarity.COMMON;
this.playableStats = dungeon.playableStats.copy();
this.isChoosable = dungeon.isChoosable();
this.isSelected = dungeon.isSelected();
} }
public CardView(PlaneView plane) { public CardView(PlaneView plane) {
@ -735,6 +747,10 @@ public class CardView extends SimpleCardView {
this.cardNumber = ""; this.cardNumber = "";
this.imageNumber = 0; this.imageNumber = 0;
this.rarity = Rarity.COMMON; this.rarity = Rarity.COMMON;
this.playableStats = plane.playableStats.copy();
this.isChoosable = plane.isChoosable();
this.isSelected = plane.isSelected();
} }
public CardView(Designation designation, StackAbility stackAbility) { public CardView(Designation designation, StackAbility stackAbility) {
@ -754,6 +770,7 @@ public class CardView extends SimpleCardView {
this.cardNumber = ""; this.cardNumber = "";
this.imageNumber = 0; this.imageNumber = 0;
this.rarity = Rarity.COMMON; this.rarity = Rarity.COMMON;
// no playable/chooseable marks for designations
} }
public CardView(boolean empty) { public CardView(boolean empty) {

View file

@ -13,7 +13,6 @@ import mage.game.command.emblems.MomirEmblem;
import mage.target.TargetPlayer; import mage.target.TargetPlayer;
import mage.view.GameView; import mage.view.GameView;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.mage.test.serverside.base.CardTestCommander4Players; import org.mage.test.serverside.base.CardTestCommander4Players;
@ -25,8 +24,6 @@ import java.util.UUID;
public class PlayableEmblemsTest extends CardTestCommander4Players { public class PlayableEmblemsTest extends CardTestCommander4Players {
@Test @Test
@Ignore
// TODO: must fix, GUI don't have playable mark for emblems due different object ids in playable ability and emblem
public void test_EmblemMustBePlayableInGUI() { public void test_EmblemMustBePlayableInGUI() {
// possible bug: different emblem's id in commander zone and playable list // possible bug: different emblem's id in commander zone and playable list
Ability ability = new SimpleActivatedAbility(new GetEmblemTargetPlayerEffect(new MomirEmblem()), new ManaCostsImpl<>("")); Ability ability = new SimpleActivatedAbility(new GetEmblemTargetPlayerEffect(new MomirEmblem()), new ManaCostsImpl<>(""));
@ -61,7 +58,7 @@ public class PlayableEmblemsTest extends CardTestCommander4Players {
.findFirst() .findFirst()
.orElse(null); .orElse(null);
Assert.assertNotNull(needObjectId); Assert.assertNotNull(needObjectId);
Assert.assertTrue("commander must be playable", gameView.getCanPlayObjects().containsObject(needObjectId)); Assert.assertTrue("commander must be playable in GUI", gameView.getCanPlayObjects().containsObject(needObjectId));
// non playable commander // non playable commander
needObjectId = game.getCommandersIds(playerA, CommanderCardType.COMMANDER_OR_OATHBREAKER, false) needObjectId = game.getCommandersIds(playerA, CommanderCardType.COMMANDER_OR_OATHBREAKER, false)
@ -70,7 +67,7 @@ public class PlayableEmblemsTest extends CardTestCommander4Players {
.findFirst() .findFirst()
.orElse(null); .orElse(null);
Assert.assertNotNull(needObjectId); Assert.assertNotNull(needObjectId);
Assert.assertFalse("commander must not be playable", gameView.getCanPlayObjects().containsObject(needObjectId)); Assert.assertFalse("commander must not be playable in GUI", gameView.getCanPlayObjects().containsObject(needObjectId));
// playable emblem // playable emblem
needObjectId = game.getState().getCommand() needObjectId = game.getState().getCommand()
@ -82,7 +79,15 @@ public class PlayableEmblemsTest extends CardTestCommander4Players {
.findFirst() .findFirst()
.orElse(null); .orElse(null);
Assert.assertNotNull(needObjectId); Assert.assertNotNull(needObjectId);
Assert.assertFalse("emblem must be playable", gameView.getCanPlayObjects().containsObject(needObjectId)); Ability currentAbility = playerA.getPlayable(game, true)
.stream()
.filter(a -> a.toString().startsWith("{X}, Discard"))
.findFirst()
.orElse(null);
Assert.assertNotNull(currentAbility);
Assert.assertEquals("source id must be same", currentAbility.getSourceId(), needObjectId);
Assert.assertEquals("source object must be same", currentAbility.getSourceObject(game), game.getObject(needObjectId));
Assert.assertTrue("emblem must be playable in GUI", gameView.getCanPlayObjects().containsObject(needObjectId));
}); });
setStrictChooseMode(true); setStrictChooseMode(true);

View file

@ -4104,10 +4104,13 @@ public abstract class PlayerImpl implements Player, Serializable {
} }
/** /**
* Creates a list of card ids that are currently playable.<br> * Creates a list of card ids that are currently playable.
* Used to mark the playable cards in GameView Also contains number of * <br>
* playable abilities for that object (it's just info, server decides to * Used to mark the playable cards in GameView
* show choose dialog or not) * Also contains number of playable abilities for that object
* <br>
* GUI only feature for the users, all real logic processing by server side
* in getPlayable and other places
* *
* @param game * @param game
* @return A Set of cardIds that are playable and amount of playable * @return A Set of cardIds that are playable and amount of playable
@ -4137,6 +4140,9 @@ public abstract class PlayerImpl implements Player, Serializable {
if (spell != null) { if (spell != null) {
putToPlayableObjects(playableObjects, spell.getId(), ability); putToPlayableObjects(playableObjects, spell.getId(), ability);
} }
} else {
// TODO: is it an error or a normal use case?
throw new IllegalStateException("Wrong code usage: ability without source id");
} }
} }
return new PlayableObjectsList(playableObjects); return new PlayableObjectsList(playableObjects);