[AFR] added dungeon support in image/card view, images download, Card Viewer, verify tests;

This commit is contained in:
Oleg Agafonov 2021-08-21 20:29:33 +04:00
parent 654ee7791c
commit 2b2a2d085a
8 changed files with 107 additions and 25 deletions

View file

@ -318,6 +318,33 @@ public class MageBook extends JComponent {
} }
} }
// dungeons
List<CardDownloadData> allDungeons = getTokenCardUrls();
for (CardDownloadData dungeon : allDungeons) {
if (dungeon.getSet().equals(currentSet)) {
try {
String className = dungeon.getName();
if (dungeon.getTokenClassName() != null && dungeon.getTokenClassName().length() > 0) {
if (dungeon.getTokenClassName().toLowerCase(Locale.ENGLISH).matches(".*dungeon.*")) {
className = dungeon.getTokenClassName();
className = "mage.game.command.dungeons." + className;
}
} else {
continue;
}
Class<?> c = Class.forName(className);
Constructor<?> cons = c.getConstructor();
Object newDungeon = cons.newInstance();
if (newDungeon instanceof Dungeon) {
((Dungeon) newDungeon).setExpansionSetCodeForImage(currentSet);
res.add(newDungeon);
}
} catch (ClassNotFoundException | InvocationTargetException | IllegalArgumentException | IllegalAccessException | InstantiationException | SecurityException | NoSuchMethodException ex) {
// Swallow exception
}
}
}
return res; return res;
} }

View file

@ -550,7 +550,6 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements
CardDownloadData card = new CardDownloadData(params[3], set, "0", false, type, "", "", true); CardDownloadData card = new CardDownloadData(params[3], set, "0", false, type, "", "", true);
card.setTokenClassName(tokenClassName); card.setTokenClassName(tokenClassName);
list.add(card); list.add(card);
// logger.debug("Token: " + set + "/" + card.getName() + " type: " + type);
} else if (params[1].toLowerCase(Locale.ENGLISH).equals("generate") && params[2].startsWith("EMBLEM:")) { } else if (params[1].toLowerCase(Locale.ENGLISH).equals("generate") && params[2].startsWith("EMBLEM:")) {
String set = params[2].substring(7); String set = params[2].substring(7);
CardDownloadData card = new CardDownloadData("Emblem " + params[3], set, "0", false, type, "", "", true, fileName); CardDownloadData card = new CardDownloadData("Emblem " + params[3], set, "0", false, type, "", "", true, fileName);
@ -571,6 +570,11 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements
CardDownloadData card = new CardDownloadData(params[3], set, "0", false, type, "", "", true, fileName); CardDownloadData card = new CardDownloadData(params[3], set, "0", false, type, "", "", true, fileName);
card.setTokenClassName(tokenClassName); card.setTokenClassName(tokenClassName);
list.add(card); list.add(card);
} else if (params[1].toLowerCase(Locale.ENGLISH).equals("generate") && params[2].startsWith("DUNGEON:")) {
String set = params[2].substring(8);
CardDownloadData card = new CardDownloadData(params[3], set, "0", false, type, "", "", true, fileName);
card.setTokenClassName(tokenClassName);
list.add(card);
} else { } else {
logger.error("wrong line format in tokens file: " + line); logger.error("wrong line format in tokens file: " + line);
} }

View file

@ -181,6 +181,11 @@
|Generate|TOK:AER|Gremlin|||GremlinToken| |Generate|TOK:AER|Gremlin|||GremlinToken|
|Generate|TOK:AER|Ragavan|||RagavanToken| |Generate|TOK:AER|Ragavan|||RagavanToken|
# Dungeons
|Generate|DUNGEON:AFR|Tomb of Annihilation|||TombOfAnnihilationDungeon|
|Generate|DUNGEON:AFR|Lost Mine of Phandelver|||LostMineOfPhandelverDungeon|
|Generate|DUNGEON:AFR|Dungeon of the Mad Mage|||DungeonOfTheMadMageDungeon|
# AKH # AKH
|Generate|TOK:AKH|Beast|||BeastToken3| |Generate|TOK:AKH|Beast|||BeastToken3|
|Generate|TOK:AKH|Cat|||CatToken2| |Generate|TOK:AKH|Cat|||CatToken2|

View file

@ -19,6 +19,7 @@ import mage.constants.CardType;
import mage.constants.Rarity; import mage.constants.Rarity;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.SuperType; import mage.constants.SuperType;
import mage.game.command.Dungeon;
import mage.game.command.Plane; import mage.game.command.Plane;
import mage.game.draft.DraftCube; import mage.game.draft.DraftCube;
import mage.game.draft.RateCard; import mage.game.draft.RateCard;
@ -1188,6 +1189,47 @@ public class VerifyCardDataTest {
} }
} }
@Test
public void test_checkMissingDungeonsData() {
Collection<String> errorsList = new ArrayList<>();
Reflections reflections = new Reflections("mage.");
Set<Class<? extends Dungeon>> dungeonClassesList = reflections.getSubTypesOf(Dungeon.class);
// 1. correct class name
for (Class<? extends Dungeon> dungeonClass : dungeonClassesList) {
if (!dungeonClass.getName().endsWith("Dungeon")) {
String className = extractShortClass(dungeonClass);
errorsList.add("Error: dungeon class must ends with Dungeon: " + className + " from " + dungeonClass.getName());
}
}
// 2. correct package
for (Class<? extends Dungeon> dungeonClass : dungeonClassesList) {
String fullClass = dungeonClass.getName();
if (!fullClass.startsWith("mage.game.command.dungeons.")) {
String className = extractShortClass(dungeonClass);
errorsList.add("Error: dungeon must be stored in mage.game.command.dungeons package: " + className + " from " + dungeonClass.getName());
}
}
// 3. correct constructor
for (Class<? extends Dungeon> dungeonClass : dungeonClassesList) {
String className = extractShortClass(dungeonClass);
Dungeon dungeon;
try {
dungeon = (Dungeon) createNewObject(dungeonClass);
} catch (Throwable e) {
errorsList.add("Error: can't create dungeon with default constructor: " + className + " from " + dungeonClass.getName());
}
}
printMessages(errorsList);
if (errorsList.size() > 0) {
Assert.fail("Found dungeon errors: " + errorsList.size());
}
}
private void check(Card card, int cardIndex, boolean skipWarning) { private void check(Card card, int cardIndex, boolean skipWarning) {
MtgJsonCard ref = MtgJsonService.cardFromSet(card.getExpansionSetCode(), card.getName(), card.getCardNumber()); MtgJsonCard ref = MtgJsonService.cardFromSet(card.getExpansionSetCode(), card.getName(), card.getCardNumber());
if (ref != null) { if (ref != null) {

View file

@ -21,9 +21,9 @@ import mage.constants.Outcome;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.SuperType; import mage.constants.SuperType;
import mage.game.Game; import mage.game.Game;
import mage.game.command.dungeons.DungeonOfTheMadMage; import mage.game.command.dungeons.DungeonOfTheMadMageDungeon;
import mage.game.command.dungeons.LostMineOfPhandelver; import mage.game.command.dungeons.LostMineOfPhandelverDungeon;
import mage.game.command.dungeons.TombOfAnnihilation; import mage.game.command.dungeons.TombOfAnnihilationDungeon;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeEvent; import mage.game.events.ZoneChangeEvent;
import mage.players.Player; import mage.players.Player;
@ -56,7 +56,7 @@ public class Dungeon implements CommandObject {
private MageObject copyFrom; // copied card INFO (used to call original adjusters) private MageObject copyFrom; // copied card INFO (used to call original adjusters)
private FrameStyle frameStyle; private FrameStyle frameStyle;
private final Abilities<Ability> abilites = new AbilitiesImpl<>(); private final Abilities<Ability> abilites = new AbilitiesImpl<>();
private final String expansionSetCodeForImage; private String expansionSetCodeForImage;
private final List<DungeonRoom> dungeonRooms = new ArrayList<>(); private final List<DungeonRoom> dungeonRooms = new ArrayList<>();
private DungeonRoom currentRoom = null; private DungeonRoom currentRoom = null;
@ -141,11 +141,11 @@ public class Dungeon implements CommandObject {
public static Dungeon createDungeon(String name) { public static Dungeon createDungeon(String name) {
switch (name) { switch (name) {
case "Tomb of Annihilation": case "Tomb of Annihilation":
return new TombOfAnnihilation(); return new TombOfAnnihilationDungeon();
case "Lost Mine of Phandelver": case "Lost Mine of Phandelver":
return new LostMineOfPhandelver(); return new LostMineOfPhandelverDungeon();
case "Dungeon of the Mad Mage": case "Dungeon of the Mad Mage":
return new DungeonOfTheMadMage(); return new DungeonOfTheMadMageDungeon();
default: default:
throw new UnsupportedOperationException("A dungeon should have been chosen"); throw new UnsupportedOperationException("A dungeon should have been chosen");
} }
@ -322,6 +322,10 @@ public class Dungeon implements CommandObject {
return expansionSetCodeForImage; return expansionSetCodeForImage;
} }
public void setExpansionSetCodeForImage(String expansionSetCodeForImage) {
this.expansionSetCodeForImage = expansionSetCodeForImage;
}
@Override @Override
public int getZoneChangeCounter(Game game) { public int getZoneChangeCounter(Game game) {
return 1; return 1;

View file

@ -26,9 +26,9 @@ import mage.target.common.TargetCreaturePermanent;
/** /**
* @author TheElk801 * @author TheElk801
*/ */
public class DungeonOfTheMadMage extends Dungeon { public class DungeonOfTheMadMageDungeon extends Dungeon {
public DungeonOfTheMadMage() { public DungeonOfTheMadMageDungeon() {
super("Dungeon of the Mad Mage", "AFR"); super("Dungeon of the Mad Mage", "AFR");
// (1) Yawning Portal You gain 1 life. ( 2) // (1) Yawning Portal You gain 1 life. ( 2)
DungeonRoom yawningPortal = new DungeonRoom("Yawning Portal", new GainLifeEffect(1)); DungeonRoom yawningPortal = new DungeonRoom("Yawning Portal", new GainLifeEffect(1));
@ -86,12 +86,12 @@ public class DungeonOfTheMadMage extends Dungeon {
this.addRoom(madWizardsLair); this.addRoom(madWizardsLair);
} }
private DungeonOfTheMadMage(final DungeonOfTheMadMage dungeon) { private DungeonOfTheMadMageDungeon(final DungeonOfTheMadMageDungeon dungeon) {
super(dungeon); super(dungeon);
} }
public DungeonOfTheMadMage copy() { public DungeonOfTheMadMageDungeon copy() {
return new DungeonOfTheMadMage(this); return new DungeonOfTheMadMageDungeon(this);
} }
} }

View file

@ -18,9 +18,9 @@ import mage.target.common.TargetCreaturePermanent;
/** /**
* @author TheElk801 * @author TheElk801
*/ */
public class LostMineOfPhandelver extends Dungeon { public class LostMineOfPhandelverDungeon extends Dungeon {
public LostMineOfPhandelver() { public LostMineOfPhandelverDungeon() {
super("Lost Mine of Phandelver", "AFR"); super("Lost Mine of Phandelver", "AFR");
// (1) Cave Entrance Scry 1. ( 2a or 2b) // (1) Cave Entrance Scry 1. ( 2a or 2b)
DungeonRoom caveEntrance = new DungeonRoom( DungeonRoom caveEntrance = new DungeonRoom(
@ -75,12 +75,12 @@ public class LostMineOfPhandelver extends Dungeon {
this.addRoom(templeOfDumathoin); this.addRoom(templeOfDumathoin);
} }
private LostMineOfPhandelver(final LostMineOfPhandelver dungeon) { private LostMineOfPhandelverDungeon(final LostMineOfPhandelverDungeon dungeon) {
super(dungeon); super(dungeon);
} }
@Override @Override
public LostMineOfPhandelver copy() { public LostMineOfPhandelverDungeon copy() {
return new LostMineOfPhandelver(this); return new LostMineOfPhandelverDungeon(this);
} }
} }

View file

@ -28,7 +28,7 @@ import java.util.*;
/** /**
* @author TheElk801 * @author TheElk801
*/ */
public final class TombOfAnnihilation extends Dungeon { public final class TombOfAnnihilationDungeon extends Dungeon {
static final FilterControlledPermanent filter static final FilterControlledPermanent filter
= new FilterControlledPermanent("an artifact, a creature, or a land"); = new FilterControlledPermanent("an artifact, a creature, or a land");
@ -41,7 +41,7 @@ public final class TombOfAnnihilation extends Dungeon {
)); ));
} }
public TombOfAnnihilation() { public TombOfAnnihilationDungeon() {
super("Tomb of Annihilation", "AFR"); super("Tomb of Annihilation", "AFR");
// (1) Trapped Entry Each player loses 1 life. ( 2a or 2b) // (1) Trapped Entry Each player loses 1 life. ( 2a or 2b)
DungeonRoom trappedEntry = new DungeonRoom("Trapped Entry", new LoseLifeAllPlayersEffect(1)); DungeonRoom trappedEntry = new DungeonRoom("Trapped Entry", new LoseLifeAllPlayersEffect(1));
@ -71,12 +71,12 @@ public final class TombOfAnnihilation extends Dungeon {
this.addRoom(cradleOfTheDeathGod); this.addRoom(cradleOfTheDeathGod);
} }
private TombOfAnnihilation(final TombOfAnnihilation dungeon) { private TombOfAnnihilationDungeon(final TombOfAnnihilationDungeon dungeon) {
super(dungeon); super(dungeon);
} }
public TombOfAnnihilation copy() { public TombOfAnnihilationDungeon copy() {
return new TombOfAnnihilation(this); return new TombOfAnnihilationDungeon(this);
} }
} }
@ -169,7 +169,7 @@ class OublietteTarget extends TargetControlledPermanent {
CardType.CREATURE, CardType.CREATURE,
CardType.LAND CardType.LAND
); );
private static final FilterControlledPermanent filter = TombOfAnnihilation.filter.copy(); private static final FilterControlledPermanent filter = TombOfAnnihilationDungeon.filter.copy();
static { static {
filter.setMessage("an artifact, a creature, and a land"); filter.setMessage("an artifact, a creature, and a land");
@ -245,7 +245,7 @@ class SandfallCellEffect extends OneShotEffect {
if (player == null) { if (player == null) {
continue; continue;
} }
TargetPermanent target = new TargetPermanent(0, 1, TombOfAnnihilation.filter, true); TargetPermanent target = new TargetPermanent(0, 1, TombOfAnnihilationDungeon.filter, true);
player.choose(Outcome.PreventDamage, target, source.getSourceId(), game); player.choose(Outcome.PreventDamage, target, source.getSourceId(), game);
map.put(playerId, game.getPermanent(target.getFirstTarget())); map.put(playerId, game.getPermanent(target.getFirstTarget()));
} }