mirror of
https://github.com/magefree/mage.git
synced 2025-12-26 05:22:02 -08:00
* UI: multiple improves for adventure/split cards:
* Split cards shows left and right mana cost (in deck editor, hand, etc); * Adventure cards shows adventure and normal cost (in deck editor, hand, etc); * Adventure cards shows adventure spell name in deck editor's list; * Fixed missing loading cursor in deck editor searching;
This commit is contained in:
parent
c4ad761ebb
commit
339c419d4b
18 changed files with 311 additions and 102 deletions
|
|
@ -2,6 +2,8 @@ package mage.cards.mock;
|
|||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.costs.mana.ManaCost;
|
||||
import mage.abilities.costs.mana.ManaCosts;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.repository.CardInfo;
|
||||
|
|
@ -11,15 +13,24 @@ import org.apache.log4j.Logger;
|
|||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Mock card for GUI (deck editor and panels)
|
||||
*
|
||||
* @author North
|
||||
*/
|
||||
public class MockCard extends CardImpl {
|
||||
|
||||
static public String ADVENTURE_NAME_SEPARATOR = " // ";
|
||||
|
||||
// Needs to be here, as it is normally calculated from the
|
||||
// PlaneswalkerEntersWithLoyaltyAbility of the card... but the MockCard
|
||||
// only has MockAbilities.
|
||||
private int startingLoyalty;
|
||||
|
||||
// mana cost extra info for multiple mana drawing
|
||||
protected ManaCosts<ManaCost> manaCostLeft;
|
||||
protected ManaCosts<ManaCost> manaCostRight;
|
||||
protected String adventureSpellName;
|
||||
|
||||
public MockCard(CardInfo card) {
|
||||
super(null, card.getName());
|
||||
this.cardNumber = card.getCardNumber();
|
||||
|
|
@ -33,7 +44,9 @@ public class MockCard extends CardImpl {
|
|||
|
||||
this.usesVariousArt = card.usesVariousArt();
|
||||
|
||||
this.manaCost = new ManaCostsImpl(join(card.getManaCosts()));
|
||||
this.manaCostLeft = new ManaCostsImpl(join(card.getManaCosts(CardInfo.ManaCostSide.LEFT)));
|
||||
this.manaCostRight = new ManaCostsImpl(join(card.getManaCosts(CardInfo.ManaCostSide.RIGHT)));
|
||||
this.manaCost = new ManaCostsImpl(join(card.getManaCosts(CardInfo.ManaCostSide.ALL)));
|
||||
|
||||
this.color = card.getColor();
|
||||
|
||||
|
|
@ -49,6 +62,10 @@ public class MockCard extends CardImpl {
|
|||
this.secondSideCard = new MockCard(CardRepository.instance.findCardWPreferredSet(card.getSecondSideName(), card.getSetCode(), false));
|
||||
}
|
||||
|
||||
if (card.isAdventureCard()) {
|
||||
this.adventureSpellName = card.getAdventureSpellName();
|
||||
}
|
||||
|
||||
if (this.isPlaneswalker()) {
|
||||
String startingLoyaltyString = card.getStartingLoyalty();
|
||||
if (startingLoyaltyString.isEmpty()) {
|
||||
|
|
@ -82,6 +99,32 @@ public class MockCard extends CardImpl {
|
|||
return new MockCard(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ManaCosts<ManaCost> getManaCost() {
|
||||
return manaCost;
|
||||
}
|
||||
|
||||
public ManaCosts<ManaCost> getManaCost(CardInfo.ManaCostSide manaCostSide) {
|
||||
switch (manaCostSide) {
|
||||
case LEFT:
|
||||
return manaCostLeft;
|
||||
case RIGHT:
|
||||
return manaCostRight;
|
||||
default:
|
||||
case ALL:
|
||||
return manaCost;
|
||||
}
|
||||
}
|
||||
|
||||
public String getFullName(boolean showSecondName) {
|
||||
if (adventureSpellName != null) {
|
||||
return getName() + ADVENTURE_NAME_SEPARATOR + adventureSpellName;
|
||||
} else {
|
||||
return getName();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private MageInt mageIntFromString(String value) {
|
||||
try {
|
||||
int intValue = Integer.parseInt(value);
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@ public class MockSplitCard extends SplitCard {
|
|||
public MockSplitCard(CardInfo card) {
|
||||
super(null, new CardSetInfo(card.getName(), card.getSetCode(), card.getCardNumber(), card.getRarity()),
|
||||
card.getTypes().toArray(new CardType[0]),
|
||||
join(card.getManaCosts()),
|
||||
"",
|
||||
join(card.getManaCosts(CardInfo.ManaCostSide.LEFT)),
|
||||
join(card.getManaCosts(CardInfo.ManaCostSide.RIGHT)),
|
||||
getSpellAbilityType(card));
|
||||
this.expansionSetCode = card.getSetCode();
|
||||
this.power = mageIntFromString(card.getPower());
|
||||
|
|
|
|||
|
|
@ -1,11 +1,8 @@
|
|||
|
||||
package mage.cards.repository;
|
||||
|
||||
import com.j256.ormlite.field.DataType;
|
||||
import com.j256.ormlite.field.DatabaseField;
|
||||
import com.j256.ormlite.table.DatabaseTable;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import mage.ObjectColor;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.SpellAbility;
|
||||
|
|
@ -18,6 +15,9 @@ import mage.util.CardUtil;
|
|||
import mage.util.SubTypeList;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author North
|
||||
*/
|
||||
|
|
@ -27,6 +27,11 @@ public class CardInfo {
|
|||
private static final int MAX_RULE_LENGTH = 750;
|
||||
|
||||
private static final String SEPARATOR = "@@@";
|
||||
|
||||
public static final String SPLIT_MANA_SEPARATOR_SHORT = "*";
|
||||
public static final String SPLIT_MANA_SEPARATOR_FULL = "{" + SPLIT_MANA_SEPARATOR_SHORT + "}";
|
||||
public static final String SPLIT_MANA_SEPARATOR_RENDER = " / ";
|
||||
|
||||
@DatabaseField(indexName = "name_index")
|
||||
protected String name;
|
||||
@DatabaseField(indexName = "setCode_cardNumber_index")
|
||||
|
|
@ -89,6 +94,14 @@ public class CardInfo {
|
|||
protected String flipCardName;
|
||||
@DatabaseField
|
||||
protected String secondSideName;
|
||||
@DatabaseField
|
||||
protected boolean adventureCard;
|
||||
@DatabaseField
|
||||
protected String adventureSpellName;
|
||||
|
||||
public enum ManaCostSide {
|
||||
LEFT, RIGHT, ALL
|
||||
}
|
||||
|
||||
public CardInfo() {
|
||||
}
|
||||
|
|
@ -116,6 +129,11 @@ public class CardInfo {
|
|||
this.secondSideName = secondSide.getName();
|
||||
}
|
||||
|
||||
if (card instanceof AdventureCard) {
|
||||
this.adventureCard = true;
|
||||
this.adventureSpellName = ((AdventureCard) card).getSpellCard().getName();
|
||||
}
|
||||
|
||||
this.frameStyle = card.getFrameStyle().toString();
|
||||
this.frameColor = card.getFrameColor(null).toString();
|
||||
this.variousArt = card.getUsesVariousArt();
|
||||
|
|
@ -128,7 +146,19 @@ public class CardInfo {
|
|||
this.setTypes(card.getCardType());
|
||||
this.setSubtypes(card.getSubtype(null).stream().map(SubType::toString).collect(Collectors.toList()));
|
||||
this.setSuperTypes(card.getSuperType());
|
||||
this.setManaCosts(card.getManaCost().getSymbols());
|
||||
|
||||
// mana cost can contains multiple cards (split left/right, card/adventure)
|
||||
if (card instanceof SplitCard) {
|
||||
List<String> manaCostLeft = ((SplitCard) card).getLeftHalfCard().getManaCost().getSymbols();
|
||||
List<String> manaCostRight = ((SplitCard) card).getRightHalfCard().getManaCost().getSymbols();
|
||||
this.setManaCosts(CardUtil.concatManaSymbols(SPLIT_MANA_SEPARATOR_FULL, manaCostLeft, manaCostRight));
|
||||
} else if (card instanceof AdventureCard) {
|
||||
List<String> manaCostLeft = ((AdventureCard) card).getSpellCard().getManaCost().getSymbols(); // Spell from left like MTGA
|
||||
List<String> manaCostRight = card.getManaCost().getSymbols();
|
||||
this.setManaCosts(CardUtil.concatManaSymbols(SPLIT_MANA_SEPARATOR_FULL, manaCostLeft, manaCostRight));
|
||||
} else {
|
||||
this.setManaCosts(card.getManaCost().getSymbols());
|
||||
}
|
||||
|
||||
int length = 0;
|
||||
List<String> rulesList = new ArrayList<>();
|
||||
|
|
@ -236,12 +266,27 @@ public class CardInfo {
|
|||
return sb.toString();
|
||||
}
|
||||
|
||||
private List<String> parseList(String list) {
|
||||
private List<String> parseList(String list, ManaCostSide manaCostSide) {
|
||||
if (list.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return Arrays.asList(list.split(SEPARATOR));
|
||||
List<String> res = new ArrayList<>();
|
||||
boolean leftSide = true;
|
||||
for (String s : list.split(SEPARATOR)) {
|
||||
if (s.equals(SPLIT_MANA_SEPARATOR_FULL)) {
|
||||
leftSide = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (manaCostSide.equals(ManaCostSide.ALL)
|
||||
|| (manaCostSide.equals(ManaCostSide.LEFT) && leftSide)
|
||||
|| (manaCostSide.equals(ManaCostSide.RIGHT) && !leftSide)) {
|
||||
res.add(s);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
public final Set<CardType> getTypes() {
|
||||
|
|
@ -267,8 +312,8 @@ public class CardInfo {
|
|||
return convertedManaCost;
|
||||
}
|
||||
|
||||
public final List<String> getManaCosts() {
|
||||
return parseList(manaCosts);
|
||||
public final List<String> getManaCosts(ManaCostSide manaCostSide) {
|
||||
return parseList(manaCosts, manaCostSide);
|
||||
}
|
||||
|
||||
public final void setManaCosts(List<String> manaCosts) {
|
||||
|
|
@ -288,7 +333,7 @@ public class CardInfo {
|
|||
}
|
||||
|
||||
public final List<String> getRules() {
|
||||
return parseList(rules);
|
||||
return parseList(rules, ManaCostSide.ALL);
|
||||
}
|
||||
|
||||
public final void setRules(List<String> rules) {
|
||||
|
|
@ -388,4 +433,12 @@ public class CardInfo {
|
|||
public String getSecondSideName() {
|
||||
return secondSideName;
|
||||
}
|
||||
|
||||
public boolean isAdventureCard() {
|
||||
return adventureCard;
|
||||
}
|
||||
|
||||
public String getAdventureSpellName() {
|
||||
return adventureSpellName;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,9 +33,9 @@ public enum CardRepository {
|
|||
private static final String JDBC_URL = "jdbc:h2:file:./db/cards.h2;AUTO_SERVER=TRUE";
|
||||
private static final String VERSION_ENTITY_NAME = "card";
|
||||
// raise this if db structure was changed
|
||||
private static final long CARD_DB_VERSION = 51;
|
||||
private static final long CARD_DB_VERSION = 52;
|
||||
// raise this if new cards were added to the server
|
||||
private static final long CARD_CONTENT_VERSION = 227;
|
||||
private static final long CARD_CONTENT_VERSION = 228;
|
||||
private Dao<CardInfo, Object> cardDao;
|
||||
private Set<String> classNames;
|
||||
private RepositoryEventSource eventSource = new RepositoryEventSource();
|
||||
|
|
@ -458,7 +458,7 @@ public enum CardRepository {
|
|||
|
||||
public List<CardInfo> findCardsCaseInsensitive(String name) {
|
||||
try {
|
||||
String sqlName = name.toLowerCase(Locale.ENGLISH).replaceAll("\'", "\'\'");
|
||||
String sqlName = name.toLowerCase(Locale.ENGLISH).replaceAll("'", "''");
|
||||
GenericRawResults<CardInfo> rawResults = cardDao.queryRaw(
|
||||
"select * from " + CardRepository.VERSION_ENTITY_NAME + " where lower(name) = '" + sqlName + '\'',
|
||||
cardDao.getRawRowMapper());
|
||||
|
|
|
|||
|
|
@ -1,18 +1,19 @@
|
|||
|
||||
package mage.filter.predicate.other;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
|
||||
import mage.cards.AdventureCard;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.SplitCard;
|
||||
import mage.cards.mock.MockCard;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.SuperType;
|
||||
import mage.filter.predicate.Predicate;
|
||||
import mage.game.Game;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Special predicate to search cards in deck editor
|
||||
*
|
||||
* @author North
|
||||
*/
|
||||
|
|
@ -41,20 +42,29 @@ public class CardTextPredicate implements Predicate<Card> {
|
|||
}
|
||||
|
||||
if (text.isEmpty() && isUnique) {
|
||||
boolean found = !seenCards.keySet().contains(input.getName());
|
||||
boolean found = !seenCards.containsKey(input.getName());
|
||||
seenCards.put(input.getName(), true);
|
||||
return found;
|
||||
}
|
||||
|
||||
// first check in card name
|
||||
if (inNames && input.getName().toLowerCase(Locale.ENGLISH).contains(text.toLowerCase(Locale.ENGLISH))) {
|
||||
if (isUnique && seenCards.keySet().contains(input.getName())) {
|
||||
return false;
|
||||
if (inNames) {
|
||||
String fullName = input.getName();
|
||||
if (input instanceof MockCard) {
|
||||
fullName = ((MockCard) input).getFullName(true);
|
||||
} else if (input instanceof AdventureCard) {
|
||||
fullName = input.getName() + MockCard.ADVENTURE_NAME_SEPARATOR + ((AdventureCard) input).getSpellCard().getName();
|
||||
}
|
||||
if (isUnique) {
|
||||
seenCards.put(input.getName(), true);
|
||||
|
||||
if (fullName.toLowerCase(Locale.ENGLISH).contains(text.toLowerCase(Locale.ENGLISH))) {
|
||||
if (isUnique && seenCards.containsKey(input.getName())) {
|
||||
return false;
|
||||
}
|
||||
if (isUnique) {
|
||||
seenCards.put(input.getName(), true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//separate by spaces
|
||||
|
|
@ -109,7 +119,7 @@ public class CardTextPredicate implements Predicate<Card> {
|
|||
}
|
||||
}
|
||||
|
||||
if (found && isUnique && seenCards.keySet().contains(input.getName())) {
|
||||
if (found && isUnique && seenCards.containsKey(input.getName())) {
|
||||
found = false;
|
||||
}
|
||||
if (!found) {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,5 @@
|
|||
package mage.util;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import mage.MageObject;
|
||||
import mage.Mana;
|
||||
import mage.abilities.Ability;
|
||||
|
|
@ -21,6 +15,15 @@ import mage.game.permanent.Permanent;
|
|||
import mage.game.permanent.token.Token;
|
||||
import mage.util.functions.CopyTokenFunction;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author nantuko
|
||||
*/
|
||||
|
|
@ -29,10 +32,10 @@ public final class CardUtil {
|
|||
private static final String SOURCE_EXILE_ZONE_TEXT = "SourceExileZone";
|
||||
|
||||
static final String[] numberStrings = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
|
||||
"ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty"};
|
||||
"ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty"};
|
||||
|
||||
static final String[] ordinalStrings = {"first", "second", "third", "fourth", "fifth", "sixth", "seventh", "eightth", "ninth",
|
||||
"tenth", "eleventh", "twelfth", "thirteenth", "fourteenth", "fifteenth", "sixteenth", "seventeenth", "eighteenth", "nineteenth", "twentieth"};
|
||||
"tenth", "eleventh", "twelfth", "thirteenth", "fourteenth", "fifteenth", "sixteenth", "seventeenth", "eighteenth", "nineteenth", "twentieth"};
|
||||
|
||||
public static final SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS");
|
||||
|
||||
|
|
@ -147,8 +150,8 @@ public final class CardUtil {
|
|||
*
|
||||
* @param spellAbility
|
||||
* @param manaCostsToReduce costs to reduce
|
||||
* @param convertToGeneric colored mana does reduce generic mana if no
|
||||
* appropriate colored mana is in the costs included
|
||||
* @param convertToGeneric colored mana does reduce generic mana if no
|
||||
* appropriate colored mana is in the costs included
|
||||
*/
|
||||
public static void adjustCost(SpellAbility spellAbility, ManaCosts<ManaCost> manaCostsToReduce, boolean convertToGeneric) {
|
||||
ManaCosts<ManaCost> previousCost = spellAbility.getManaCostsToPay();
|
||||
|
|
@ -333,7 +336,7 @@ public final class CardUtil {
|
|||
*
|
||||
* @param number number to convert to text
|
||||
* @param forOne if the number is 1, this string will be returnedinstead of
|
||||
* "one".
|
||||
* "one".
|
||||
* @return
|
||||
*/
|
||||
public static String numberToText(int number, String forOne) {
|
||||
|
|
@ -418,7 +421,7 @@ public final class CardUtil {
|
|||
/**
|
||||
* Creates and saves a (card + zoneChangeCounter) specific exileId.
|
||||
*
|
||||
* @param game the current game
|
||||
* @param game the current game
|
||||
* @param source source ability
|
||||
* @return the specific UUID
|
||||
*/
|
||||
|
|
@ -453,9 +456,9 @@ public final class CardUtil {
|
|||
* be specific to a permanent instance. So they won't match, if a permanent
|
||||
* was e.g. exiled and came back immediately.
|
||||
*
|
||||
* @param text short value to describe the value
|
||||
* @param text short value to describe the value
|
||||
* @param cardId id of the card
|
||||
* @param game the game
|
||||
* @param game the game
|
||||
* @return
|
||||
*/
|
||||
public static String getCardZoneString(String text, UUID cardId, Game game) {
|
||||
|
|
@ -609,9 +612,9 @@ public final class CardUtil {
|
|||
/**
|
||||
* Checks if a card had a given ability depending their historic cardState
|
||||
*
|
||||
* @param ability the ability that is checked
|
||||
* @param ability the ability that is checked
|
||||
* @param cardState the historic cardState (from LKI)
|
||||
* @param cardId the id of the card
|
||||
* @param cardId the id of the card
|
||||
* @param game
|
||||
* @return
|
||||
*/
|
||||
|
|
@ -630,4 +633,13 @@ public final class CardUtil {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static List<String> concatManaSymbols(String delimeter, List<String> mana1, List<String> mana2) {
|
||||
List<String> res = new ArrayList<>(mana1);
|
||||
if (res.size() > 0 && mana2.size() > 0 && delimeter != null && !delimeter.isEmpty()) {
|
||||
res.add(delimeter);
|
||||
}
|
||||
res.addAll(mana2);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue