GUI: introduced default card hints:

* refactor: added helper emblems instead rad counter's inherent emblems (use initGameDefaultHelperEmblems to define new card hints or other fake objects);
* refactor: added card hints support for emblems, planes and other command objects;
* GUI: added storm counter as default card hint (use hints tool to see it, closes #12360);
This commit is contained in:
Oleg Agafonov 2024-07-27 09:40:41 +04:00
parent 83823acec7
commit 521a0f6e32
36 changed files with 234 additions and 144 deletions

View file

@ -821,7 +821,7 @@ public class CardView extends SimpleCardView {
this.mageObjectType = MageObjectType.EMBLEM;
Emblem emblem = (Emblem) object;
this.rarity = Rarity.SPECIAL;
this.rules = new ArrayList<>(emblem.getAbilities().getRules(emblem.getName()));
this.rules = new ArrayList<>(emblem.getAbilities().getRules(game, emblem));
} else if (object instanceof Dungeon) {
this.mageObjectType = MageObjectType.DUNGEON;
Dungeon dungeon = (Dungeon) object;
@ -834,14 +834,14 @@ public class CardView extends SimpleCardView {
this.frameStyle = FrameStyle.M15_NORMAL;
// Display in landscape/rotated/on its side
this.rotate = true;
this.rules = new ArrayList<>(plane.getAbilities().getRules(plane.getName()));
this.rules = new ArrayList<>(plane.getAbilities().getRules(game, plane));
} else if (object instanceof Designation) {
this.mageObjectType = MageObjectType.DESIGNATION;
Designation designation = (Designation) object;
this.rarity = Rarity.SPECIAL;
this.frameStyle = FrameStyle.M15_NORMAL;
// Display in landscape/rotated/on its side
this.rules = new ArrayList<>(designation.getAbilities().getRules(designation.getName()));
this.rules = new ArrayList<>(designation.getAbilities().getRules(game, designation));
}
if (this.rarity == null && object instanceof StackAbility) {
StackAbility stackAbility = (StackAbility) object;
@ -1106,7 +1106,7 @@ public class CardView extends SimpleCardView {
this.name = token.getName();
this.displayName = token.getName();
this.displayFullName = token.getName();
this.rules = new ArrayList<>(token.getAbilities().getRules(this.name));
this.rules = new ArrayList<>(token.getAbilities().getRules(game, token));
this.power = token.getPower().toString();
this.toughness = token.getToughness().toString();
this.loyalty = "";

View file

@ -107,26 +107,22 @@ public class CardsView extends LinkedHashMap<UUID, CardView> {
isCard = true;
}
if (sourceObject instanceof Emblem) {
// Emblems are not normally OUTSIDE, except the special Radiation Emblem from rad counters.
abilityView = new AbilityView(ability, sourceObject.getName(), new CardView(new EmblemView((Emblem) sourceObject)));
// emblems are not normally OUTSIDE, except the helper emblems like Radiation
abilityView = new AbilityView(ability, sourceObject.getName(), new CardView(new EmblemView((Emblem) sourceObject, game)));
abilityView.setName(sourceObject.getName());
}
break;
case COMMAND:
sourceObject = game.getObject(ability.getSourceId());
if (sourceObject instanceof Emblem) {
// Card sourceCard = (Card) ((Emblem) sourceObject).getSourceObject();
// if (sourceCard == null) {
// throw new IllegalArgumentException("Source card for emblem not found.");
// }
abilityView = new AbilityView(ability, sourceObject.getName(), new CardView(new EmblemView((Emblem) sourceObject)));
abilityView = new AbilityView(ability, sourceObject.getName(), new CardView(new EmblemView((Emblem) sourceObject, game)));
abilityView.setName(sourceObject.getName());
// abilityView.setExpansionSetCode(sourceCard.getExpansionSetCode());
} else if (sourceObject instanceof Dungeon) {
abilityView = new AbilityView(ability, sourceObject.getName(), new CardView(new DungeonView((Dungeon) sourceObject)));
abilityView.setName(sourceObject.getName());
} else if (sourceObject instanceof Plane) {
abilityView = new AbilityView(ability, sourceObject.getName(), new CardView(new PlaneView((Plane) sourceObject)));
abilityView = new AbilityView(ability, sourceObject.getName(), new CardView(new PlaneView((Plane) sourceObject, game)));
abilityView.setName(sourceObject.getName());
}
break;

View file

@ -1,5 +1,6 @@
package mage.view;
import mage.game.Game;
import mage.game.command.Emblem;
import mage.game.command.emblems.EmblemOfCard;
import mage.players.PlayableObjectStats;
@ -23,13 +24,13 @@ public class EmblemView implements CommandObjectView, Serializable {
protected List<String> rules;
protected PlayableObjectStats playableStats = new PlayableObjectStats();
public EmblemView(Emblem emblem) {
public EmblemView(Emblem emblem, Game game) {
this.id = emblem.getId();
this.name = emblem.getName();
this.imageFileName = emblem.getImageFileName();
this.imageNumber = emblem.getImageNumber();
this.expansionSetCode = emblem.getExpansionSetCode();
this.rules = emblem.getAbilities().getRules(emblem.getName());
this.rules = emblem.getAbilities().getRules(game, emblem);
if (emblem instanceof EmblemOfCard) {
cardNumber = emblem.getCardNumber();
usesVariousArt = ((EmblemOfCard) emblem).getUsesVariousArt();

View file

@ -44,6 +44,7 @@ public class GameView implements Serializable {
private final List<PlayerView> players = new ArrayList<>();
private UUID myPlayerId = null; // null for watcher
private final CardsView myHand = new CardsView();
private final CardsView myHelperEmblems = new CardsView();
private PlayableObjectsList canPlayObjects;
private final Map<String, SimpleCardsView> opponentHands = new HashMap<>();
private final Map<String, SimpleCardsView> watchedHands = new HashMap<>();
@ -75,6 +76,11 @@ public class GameView implements Serializable {
createdForPlayer = player;
this.myPlayerId = player.getId();
this.myHand.putAll(new CardsView(game, player.getHand().getCards(game), createdForPlayerId));
state.getHelperEmblems().stream()
.filter(emblem -> emblem.isControlledBy(player.getId()))
.forEach(emblem -> {
this.myHelperEmblems.put(emblem.getId(), new CardView(new EmblemView(emblem, game)));
});
}
}
for (StackObject stackObject : state.getStack()) {
@ -112,7 +118,7 @@ public class GameView implements Serializable {
stack.put(stackObject.getId(), new StackAbilityView(game, (StackAbility) stackObject, token.getName(), token, new CardView(token, game)));
checkPaid(stackObject.getId(), (StackAbility) stackObject);
} else if (object instanceof Emblem) {
CardView cardView = new CardView(new EmblemView((Emblem) object));
CardView cardView = new CardView(new EmblemView((Emblem) object, game));
// Card sourceCard = (Card) ((Emblem) object).getSourceObject();
stackObject.setName(object.getName());
// ((StackAbility) stackObject).setExpansionSetCode(sourceCard.getExpansionSetCode());
@ -126,7 +132,7 @@ public class GameView implements Serializable {
new StackAbilityView(game, (StackAbility) stackObject, object.getName(), object, cardView));
checkPaid(stackObject.getId(), ((StackAbility) stackObject));
} else if (object instanceof Plane) {
CardView cardView = new CardView(new PlaneView((Plane) object));
CardView cardView = new CardView(new PlaneView((Plane) object, game));
stackObject.setName(object.getName());
stack.put(stackObject.getId(),
new StackAbilityView(game, (StackAbility) stackObject, object.getName(), object, cardView));
@ -239,6 +245,10 @@ public class GameView implements Serializable {
return myHand;
}
public CardsView getMyHelperEmblems() {
return myHelperEmblems;
}
public PlayerView getMyPlayer() {
if (this.myPlayerId == null) {
return null;

View file

@ -1,5 +1,6 @@
package mage.view;
import mage.game.Game;
import mage.game.command.Plane;
import mage.players.PlayableObjectStats;
@ -20,13 +21,13 @@ public class PlaneView implements CommandObjectView, Serializable {
protected List<String> rules;
protected PlayableObjectStats playableStats = new PlayableObjectStats();
public PlaneView(Plane plane) {
public PlaneView(Plane plane, Game game) {
this.id = plane.getId();
this.name = plane.getName();
this.imageFileName = plane.getImageFileName();
this.imageNumber = plane.getImageNumber();
this.expansionSetCode = plane.getExpansionSetCode();
this.rules = plane.getAbilities().getRules(plane.getName());
this.rules = plane.getAbilities().getRules(game, plane);
}
@Override

View file

@ -40,6 +40,7 @@ public class PlayerView implements Serializable {
private final CardsView graveyard = new CardsView();
private final CardsView exile = new CardsView();
private final CardsView sideboard = new CardsView();
private final CardsView helperCards = new CardsView();
private final Map<UUID, PermanentView> battlefield = new LinkedHashMap<>();
private final CardView topCard;
private final UserData userData;
@ -120,7 +121,7 @@ public class PlayerView implements Serializable {
if (commandObject instanceof Emblem) {
Emblem emblem = (Emblem) commandObject;
if (emblem.getControllerId().equals(this.playerId)) {
commandList.add(new EmblemView(emblem));
commandList.add(new EmblemView(emblem, game));
}
} else if (commandObject instanceof Dungeon) {
Dungeon dungeon = (Dungeon) commandObject;
@ -130,7 +131,7 @@ public class PlayerView implements Serializable {
} else if (commandObject instanceof Plane) {
Plane plane = (Plane) commandObject;
// Planes are universal and all players can see them.
commandList.add(new PlaneView(plane));
commandList.add(new PlaneView(plane, game));
} else if (commandObject instanceof Commander) {
Commander commander = (Commander) commandObject;
if (commander.getControllerId().equals(this.playerId)) {