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) {
cardView = (CommanderView) commandObject;
} else {
continue;
throw new IllegalStateException("ERROR, unsupported commander object type: " + commandObject.getClass().getSimpleName());
}
cards.put(commandObject.getId(), cardView);
}

View file

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

View file

@ -13,7 +13,6 @@ import mage.game.command.emblems.MomirEmblem;
import mage.target.TargetPlayer;
import mage.view.GameView;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestCommander4Players;
@ -25,8 +24,6 @@ import java.util.UUID;
public class PlayableEmblemsTest extends CardTestCommander4Players {
@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() {
// possible bug: different emblem's id in commander zone and playable list
Ability ability = new SimpleActivatedAbility(new GetEmblemTargetPlayerEffect(new MomirEmblem()), new ManaCostsImpl<>(""));
@ -61,7 +58,7 @@ public class PlayableEmblemsTest extends CardTestCommander4Players {
.findFirst()
.orElse(null);
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
needObjectId = game.getCommandersIds(playerA, CommanderCardType.COMMANDER_OR_OATHBREAKER, false)
@ -70,7 +67,7 @@ public class PlayableEmblemsTest extends CardTestCommander4Players {
.findFirst()
.orElse(null);
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
needObjectId = game.getState().getCommand()
@ -82,7 +79,15 @@ public class PlayableEmblemsTest extends CardTestCommander4Players {
.findFirst()
.orElse(null);
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);

View file

@ -4104,10 +4104,13 @@ public abstract class PlayerImpl implements Player, Serializable {
}
/**
* Creates a list of card ids that are currently playable.<br>
* Used to mark the playable cards in GameView Also contains number of
* playable abilities for that object (it's just info, server decides to
* show choose dialog or not)
* Creates a list of card ids that are currently playable.
* <br>
* Used to mark the playable cards in GameView
* 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
* @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) {
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);