images: added The Ring image support (part of #12274, #12899);

images: fixed miss dungeon image in choose dungeon dialog (part of #12274);
This commit is contained in:
Oleg Agafonov 2024-09-21 18:41:53 +04:00
parent 7d1ab71092
commit f7d702d5df
9 changed files with 50 additions and 23 deletions

View file

@ -313,7 +313,7 @@ public class PickChoiceDialog extends MageDialog {
// as card name
cardInfo.init(item.getHint(), this.bigCard, this.gameId);
} else if (item.getHintType() == ChoiceHintType.CARD_DUNGEON) {
// as card name
// as dungeon name
CardView cardView = new CardView(new DungeonView(Dungeon.createDungeon(item.getHint(), true)));
cardInfo.init(cardView, this.bigCard, this.gameId);
} else if (item.getHintType() == ChoiceHintType.GAME_OBJECT) {

View file

@ -33,6 +33,7 @@ public enum TokenRepository {
public static final String XMAGE_IMAGE_NAME_NIGHT = "Night";
public static final String XMAGE_IMAGE_NAME_THE_MONARCH = "The Monarch";
public static final String XMAGE_IMAGE_NAME_RADIATION = "Radiation";
public static final String XMAGE_IMAGE_NAME_THE_RING = "The Ring";
public static final String XMAGE_IMAGE_NAME_HELPER_EMBLEM = "Helper Emblem";
private static final Logger logger = Logger.getLogger(TokenRepository.class);
@ -306,6 +307,9 @@ public enum TokenRepository {
// Radiation (for trigger)
res.add(createXmageToken(XMAGE_IMAGE_NAME_RADIATION, 1, "https://api.scryfall.com/cards/tpip/22/en?format=image"));
// The Ring
res.add(createXmageToken(XMAGE_IMAGE_NAME_THE_RING, 1, "https://api.scryfall.com/cards/tltr/H13/en?format=image"));
// Helper emblem (for global card hints)
// use backface for it
res.add(createXmageToken(XMAGE_IMAGE_NAME_HELPER_EMBLEM, 1, "https://upload.wikimedia.org/wikipedia/en/a/aa/Magic_the_gathering-card_back.jpg"));

View file

@ -583,11 +583,10 @@ public abstract class GameImpl implements Game {
if (emblem != null) {
return emblem;
}
TheRingEmblem newEmblem = new TheRingEmblem(playerId);
// TODO: add image info
state.addCommandObject(newEmblem);
return newEmblem;
}
@ -1966,16 +1965,13 @@ public abstract class GameImpl implements Game {
@Override
public void addEmblem(Emblem emblem, MageObject sourceObject, UUID toPlayerId) {
Emblem newEmblem = emblem.copy();
newEmblem.setSourceObject(sourceObject);
newEmblem.setSourceObjectAndInitImage(sourceObject);
newEmblem.setControllerId(toPlayerId);
newEmblem.assignNewId();
newEmblem.getAbilities().newId();
for (Ability ability : newEmblem.getAbilities()) {
ability.setSourceId(newEmblem.getId());
}
// image info setup in setSourceObject
state.addCommandObject(newEmblem);
}
@ -1997,17 +1993,15 @@ public abstract class GameImpl implements Game {
}
}
Plane newPlane = plane.copy();
newPlane.setSourceObject();
newPlane.setSourceObjectAndInitImage();
newPlane.setControllerId(toPlayerId);
newPlane.assignNewId();
newPlane.getAbilities().newId();
for (Ability ability : newPlane.getAbilities()) {
ability.setSourceId(newPlane.getId());
}
// image info setup in setSourceObject
state.addCommandObject(newPlane);
informPlayers("You have planeswalked to " + newPlane.getLogName());
// Fire off the planeswalked event
@ -2028,7 +2022,6 @@ public abstract class GameImpl implements Game {
@Override
public Dungeon addDungeon(Dungeon dungeon, UUID playerId) {
dungeon.setControllerId(playerId);
dungeon.setSourceObject();
state.addCommandObject(dungeon);
return dungeon;
}

View file

@ -1239,6 +1239,11 @@ public class GameState implements Serializable, Copyable<GameState> {
this.isPlaneChase = isPlaneChase;
}
/**
* Add object to command zone.
* <p>
* Warning, all object data must be initialized before adding, including image info
*/
public void addCommandObject(CommandObject commandObject) {
getCommand().add(commandObject);
setZone(commandObject.getId(), Zone.COMMAND);

View file

@ -154,24 +154,35 @@ public class Dungeon extends CommandObjectImpl {
}
public static Dungeon createDungeon(String name, boolean isNameMustExists) {
Dungeon res;
switch (name) {
case "Tomb of Annihilation":
return new TombOfAnnihilationDungeon();
res = new TombOfAnnihilationDungeon();
break;
case "Lost Mine of Phandelver":
return new LostMineOfPhandelverDungeon();
res = new LostMineOfPhandelverDungeon();
break;
case "Dungeon of the Mad Mage":
return new DungeonOfTheMadMageDungeon();
res = new DungeonOfTheMadMageDungeon();
break;
default:
if (isNameMustExists) {
throw new UnsupportedOperationException("A dungeon should have been chosen");
} else {
return null;
}
res = null;
}
}
public void setSourceObject() {
// choose set code due source
// source don't have source, so image data can be initialized immediately
if (res != null) {
res.setSourceObjectAndInitImage();
}
return res;
}
public void setSourceObjectAndInitImage() {
// image
TokenInfo foundInfo = TokenRepository.instance.findPreferredTokenInfoForClass(this.getClass().getName(), null);
if (foundInfo != null) {
this.setExpansionSetCode(foundInfo.getSetCode());

View file

@ -19,7 +19,6 @@ import mage.constants.SubType;
import mage.constants.SuperType;
import mage.game.Game;
import mage.game.events.ZoneChangeEvent;
import mage.util.CardUtil;
import mage.util.SubTypes;
import java.util.Collections;
@ -59,7 +58,7 @@ public abstract class Emblem extends CommandObjectImpl {
return frameStyle;
}
public void setSourceObject(MageObject sourceObject) {
public void setSourceObjectAndInitImage(MageObject sourceObject) {
this.sourceObject = sourceObject;
// choose set code due source

View file

@ -65,7 +65,7 @@ public abstract class Plane extends CommandObjectImpl {
return frameStyle;
}
public void setSourceObject() {
public void setSourceObjectAndInitImage() {
this.sourceObject = null;
// choose set code due source

View file

@ -94,7 +94,7 @@ public final class EmblemOfCard extends Emblem {
}
@Override
public void setSourceObject(MageObject sourceObject) {
public void setSourceObjectAndInitImage(MageObject sourceObject) {
this.sourceObject = sourceObject;
// super method would try and fail to find the emblem image here
// (not sure why that would be setSoureObject's job; we get our image during construction)

View file

@ -12,6 +12,8 @@ import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.common.DrawDiscardControllerEffect;
import mage.abilities.effects.common.LoseLifeOpponentsEffect;
import mage.abilities.effects.common.SacrificeTargetEffect;
import mage.cards.repository.TokenInfo;
import mage.cards.repository.TokenRepository;
import mage.constants.*;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledPermanent;
@ -41,6 +43,19 @@ public final class TheRingEmblem extends Emblem {
public TheRingEmblem(UUID controllerId) {
super("The Ring");
this.setControllerId(controllerId);
// ring don't have source, so image can be initialized immediately
TokenInfo foundInfo = TokenRepository.instance.findPreferredTokenInfoForXmage(TokenRepository.XMAGE_IMAGE_NAME_THE_RING, null);
if (foundInfo != null) {
this.setExpansionSetCode(foundInfo.getSetCode());
this.setUsesVariousArt(false);
this.setCardNumber("");
this.setImageFileName(""); // use default
this.setImageNumber(foundInfo.getImageNumber());
} else {
// how-to fix: add emblem to the tokens-database TokenRepository->loadXmageTokens
throw new IllegalArgumentException("Wrong code usage: can't find xmage token info for: " + TokenRepository.XMAGE_IMAGE_NAME_THE_RING);
}
}
private TheRingEmblem(final TheRingEmblem card) {