- Reverting r29415-29422 for now because the UTF-8 characters prove to be problematic for the player unless they are transparent enough when searching for cards and typing card names (including the deck editor).

- Before having to revert these changes I managed to get the game to recognize both accented and unaccented card names in decks and for the purposes of card picture file names. However, I was not successful in implementing the similar level of transparency in the deck editor and in the card search box (e.g. "Add Card To Hand" - that type of thing).
- To continue working on this project, feel free to revert this commit locally and update the functionality to be more transparent and intuitive for the end user.
This commit is contained in:
Agetian
2015-05-17 16:44:30 +00:00
parent 9f15e72a4f
commit 46f17edad0
69 changed files with 160 additions and 226 deletions

View File

@@ -42,7 +42,6 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
// need this to obtain cardReference by name+set+artindex
private final ListMultimap<String, PaperCard> allCardsByName = Multimaps.newListMultimap(new TreeMap<String,Collection<PaperCard>>(String.CASE_INSENSITIVE_ORDER), CollectionSuppliers.<PaperCard>arrayLists());
private final Map<String, PaperCard> uniqueCardsByName = new TreeMap<String, PaperCard>(String.CASE_INSENSITIVE_ORDER);
private final Map<String, String> accentedCardNameEquivalents = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
private final Map<String, CardRules> rulesByName;
private static Map<String, String> artPrefs = new HashMap<String, String>();
@@ -166,7 +165,7 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
for (CardRules cr : rulesByName.values()) {
if (!allCardsByName.containsKey(cr.getName())) {
System.err.println(String.format("The card %s was not assigned to any set. Adding it to UNKNOWN set... to fix see res/editions/ folder. ", cr.getName()));
System.err.println("The card " + cr.getName() + " was not assigned to any set. Adding it to UNKNOWN set... to fix see res/cardeditions/ folder. ");
addCard(new PaperCard(cr, CardEdition.UNKNOWN.getCode(), CardRarity.Special, 1));
}
}
@@ -185,13 +184,6 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
uniqueCardsByName.put(kv.getKey(), getFirstWithImage(kv.getValue()));
allCards.addAll(kv.getValue());
}
for (String name : allCardsByName.keySet()) {
if (StringUtils.containsAny(name, "áàâéèêúùûíìîóòô")) {
String equivName = StringUtils.replaceChars(name, "áàâéèêúùûíìîóòô", "aaaeeeuuuiiiooo");
accentedCardNameEquivalents.put(equivName, name);
}
}
}
private static PaperCard getFirstWithImage(final Collection<PaperCard> cards) {
@@ -547,15 +539,6 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
return new PaperCard(CardRules.getUnsupportedCardNamed(request.cardName), cE.getCode(), cR, 1);
}
public String getEquivalentCardName(String name) {
boolean hasSetInfo = name.indexOf('|') != -1;
String cardName = !hasSetInfo ? name : StringUtils.substring(name, 0, name.indexOf('|'));
String setInfo = !hasSetInfo ? "" : StringUtils.substring(name, name.indexOf("|"));
return accentedCardNameEquivalents.containsKey(cardName) ? String.format("%s%s", accentedCardNameEquivalents.get(cardName), setInfo) :
String.format("%s%s", name, setInfo);
}
private final Editor editor = new Editor();
public Editor getEditor() { return editor; }
public class Editor {
@@ -620,6 +603,5 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
public void setImmediateReindex(boolean immediateReindex) {
this.immediateReindex = immediateReindex;
}
}
}

View File

@@ -63,20 +63,9 @@ public class CardPool extends ItemPool<PaperCard> {
// NOTE: ART indices are "1" -based
public void add(String cardName, String setCode, final int artIndex, final int amount) {
PaperCard cp = StaticData.instance().getCommonCards().getCard(cardName, setCode, artIndex);
String equivName = StaticData.instance().getCommonCards().getEquivalentCardName(cardName);
if (cp == null && !cardName.equals(equivName)) {
// try the equivalent card name
cp = StaticData.instance().getCommonCards().getCard(equivName, setCode, artIndex);
}
boolean isCommonCard = cp != null;
if (!isCommonCard) {
cp = StaticData.instance().getVariantCards().getCard(cardName, setCode);
if (cp == null && !cardName.equals(equivName)) {
// try the equivalent card name
cp = StaticData.instance().getVariantCards().getCard(equivName, setCode, artIndex);
}
}
boolean artIndexExplicitlySet = artIndex > 0 || Character.isDigit(cardName.charAt(cardName.length()-1)) && cardName.charAt(cardName.length()-2) == CardDb.NameSetSeparator;

View File

@@ -8,14 +8,15 @@ import forge.card.CardDb;
import forge.card.CardRules;
import forge.card.CardSplitType;
import forge.item.PaperCard;
import forge.util.Base64Coder;
public class ImageUtil {
public static float getNearestHQSize(final float baseSize, final float actualSize) {
public static float getNearestHQSize(float baseSize, float actualSize) {
//get nearest power of actualSize to baseSize so that the image renders good
return Math.round(actualSize) * (float)Math.pow(2, Math.round(Math.log(baseSize / actualSize) / Math.log(2)));
return (float)Math.round(actualSize) * (float)Math.pow(2, (double)Math.round(Math.log((double)(baseSize / actualSize)) / Math.log(2)));
}
public static PaperCard getPaperCardFromImageKey(final String key) {
public static PaperCard getPaperCardFromImageKey(String key) {
if ( key == null ) {
return null;
}
@@ -27,46 +28,45 @@ public class ImageUtil {
return cp;
}
public static String getImageRelativePath(final PaperCard cp, final boolean backFace, final boolean includeSet, final boolean isDownloadUrl) {
public static String getImageRelativePath(PaperCard cp, boolean backFace, boolean includeSet, boolean isDownloadUrl) {
final String nameToUse = cp == null ? null : getNameToUse(cp, backFace);
if (nameToUse == null) {
return null;
}
final StringBuilder s = new StringBuilder();
final CardRules card = cp.getRules();
final String edition = cp.getEdition();
StringBuilder s = new StringBuilder();
CardRules card = cp.getRules();
String edition = cp.getEdition();
s.append(toMWSFilename(nameToUse));
final int cntPictures;
final boolean hasManyPictures;
final CardDb db = !card.isVariant() ? StaticData.instance().getCommonCards() : StaticData.instance().getVariantCards();
if (includeSet) {
cntPictures = db.getPrintCount(card.getName(), edition);
cntPictures = db.getPrintCount(card.getName(), edition);
hasManyPictures = cntPictures > 1;
} else {
// without set number of pictures equals number of urls provided in Svar:Picture
final String urls = card.getPictureUrl(backFace);
String urls = card.getPictureUrl(backFace);
cntPictures = StringUtils.countMatches(urls, "\\") + 1;
// raise the art index limit to the maximum of the sets this card was printed in
final int maxCntPictures = db.getMaxPrintCount(card.getName());
int maxCntPictures = db.getMaxPrintCount(card.getName());
hasManyPictures = maxCntPictures > 1;
}
int artIdx = cp.getArtIndex() - 1;
if (hasManyPictures) {
if ( cntPictures <= artIdx ) {
if ( cntPictures <= artIdx ) // prevent overflow
artIdx = cntPictures == 0 ? 0 : artIdx % cntPictures;
}
s.append(artIdx + 1);
}
// for whatever reason, MWS-named plane cards don't have the ".full" infix
if (!card.getType().isPlane() && !card.getType().isPhenomenon()) {
s.append(".full");
}
final String fname;
if (isDownloadUrl) {
s.append(".jpg");
@@ -74,51 +74,43 @@ public class ImageUtil {
} else {
fname = s.toString();
}
if (includeSet) {
final String editionAliased = isDownloadUrl ? StaticData.instance().getEditions().getCode2ByCode(edition) : ImageKeys.getSetFolder(edition);
String editionAliased = isDownloadUrl ? StaticData.instance().getEditions().getCode2ByCode(edition) : ImageKeys.getSetFolder(edition);
return String.format("%s/%s", editionAliased, fname);
} else {
return fname;
}
}
public static boolean hasBackFacePicture(final PaperCard cp) {
final CardSplitType cst = cp.getRules().getSplitType();
return cst == CardSplitType.Transform || cst == CardSplitType.Flip;
public static boolean hasBackFacePicture(PaperCard cp) {
CardSplitType cst = cp.getRules().getSplitType();
return cst == CardSplitType.Transform || cst == CardSplitType.Flip;
}
public static String getNameToUse(final PaperCard cp, final boolean backFace) {
public static String getNameToUse(PaperCard cp, boolean backFace) {
final CardRules card = cp.getRules();
final String nameToUse;
if (backFace) {
if (hasBackFacePicture(cp)) {
nameToUse = card.getOtherPart().getName();
} else {
if (backFace ) {
if ( hasBackFacePicture(cp) )
return card.getOtherPart().getName();
else
return null;
}
} else if (CardSplitType.Split == cp.getRules().getSplitType()) {
nameToUse = card.getMainPart().getName() + card.getOtherPart().getName();
} else if(CardSplitType.Split == cp.getRules().getSplitType()) {
return card.getMainPart().getName() + card.getOtherPart().getName();
} else {
nameToUse = cp.getName();
return cp.getName();
}
return formatName(nameToUse);
}
private static String formatName(final String name) {
return StringUtils.replaceChars(name, "áàâéèêúùûíìîóòô", "aaaeeeuuuiiiooo");
}
public static String getImageKey(final PaperCard cp, final boolean backFace, final boolean includeSet) {
public static String getImageKey(PaperCard cp, boolean backFace, boolean includeSet) {
return getImageRelativePath(cp, backFace, includeSet, false);
}
public static String getDownloadUrl(final PaperCard cp, final boolean backFace) {
public static String getDownloadUrl(PaperCard cp, boolean backFace) {
return getImageRelativePath(cp, backFace, true, true);
}
public static String toMWSFilename(final String in) {
}
public static String toMWSFilename(String in) {
final StringBuffer out = new StringBuffer();
char c;
for (int i = 0; i < in.length(); i++) {

View File

@@ -140,7 +140,7 @@ public final class SResizingUtil {
existingComponents.add(c);
}
// This is the core of the pixel-perfect layout. To avoid ±1 px errors on borders
// This is the core of the pixel-perfect layout. To avoid <EFBFBD>1 px errors on borders
// from rounding individual panels, the intermediate values (exactly accurate, in %)
// for width and height are rounded based on comparison to other panels in the
// layout. This is to avoid errors such as:

View File

@@ -8,31 +8,6 @@ Forge Beta: #-#-2015 ver 1.5.39
Release Notes
-------------
- Special characters in card names -
Many cards with special characters in their names, most notably those whose name
contains "Lim-Dûl", have been fixed to contain those characters. Your deck
files will be updated automatically if you load them in deck editor and save
them, there should be no need for manual intervention. The full list of cards is
as follows:
- Dandân
- Déjà Vu
- El Hallâj
- Ghazbán Ogre
- Ifh-Bíff Efreet
- Junún Efreet
- Juzám Djinn
- Khabál Ghoul
- Legions of Lim-Dûl
- Lim-Dûl the Necromancer
- Lim-Dûl's Cohort
- Lim-Dûl's Hex
- Lim-Dûl's High Guard
- Lim-Dûl's Paladin
- Lim-Dûl's Vault
- Márton Stromgald
- Oath of Lim-Dûl
- Séance
- Morph/Manifest images -
Forge now supports proper images for face-down creatures. In order to correctly
use these images, it's necessary to remove a file in your picture directory

View File

@@ -1,4 +1,4 @@
Name:Dandân
Name:Dandan
ManaCost:U U
Types:Creature Fish
PT:4/1
@@ -7,4 +7,4 @@ T:Mode$ Always | TriggerZones$ Battlefield | IsPresent$ Island.YouCtrl | Present
SVar:TrigSac:AB$Sacrifice | Cost$ 0 | Defined$ Self
SVar:NeedsToPlay:Island.YouCtrl
SVar:Picture:http://resources.wizards.com/magic/cards/tsb/en-us/card106631.jpg
Oracle:Dandân can't attack unless defending player controls an Island.\nWhen you control no Islands, sacrifice Dandân.
Oracle:Dandan can't attack unless defending player controls an Island.\nWhen you control no Islands, sacrifice Dandan.

View File

@@ -1,4 +1,4 @@
Name:Déjà Vu
Name:Deja Vu
ManaCost:2 U
Types:Sorcery
A:SP$ ChangeZone | Cost$ 2 U | Origin$ Graveyard | Destination$ Hand | TgtPrompt$ Choose target sorcery card in your graveyard | ValidTgts$ Sorcery.YouCtrl | SpellDescription$ Return target sorcery card from your graveyard to your hand.

View File

@@ -1,4 +1,4 @@
Name:El-Hajjâj
Name:El-Hajjaj
ManaCost:1 B B
Types:Creature Human Wizard
PT:1/1
@@ -7,4 +7,4 @@ SVar:TrigGain:AB$GainLife | Cost$ 0 | Defined$ You | LifeAmount$ X | References$
SVar:X:TriggerCount$DamageAmount
SVar:HasCombatEffect:TRUE
SVar:Picture:http://www.wizards.com/global/images/magic/general/el_hajjaj.jpg
Oracle:Whenever El-Hajjâj deals damage, you gain that much life.
Oracle:Whenever El-Hajjaj deals damage, you gain that much life.

View File

@@ -1,4 +1,4 @@
Name:Ghazbán Ogre
Name:Ghazban Ogre
ManaCost:G
Types:Creature Ogre
PT:2/2
@@ -6,4 +6,4 @@ T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | A
SVar:TrigOppControl:AB$ GainControl | Cost$ 0 | Defined$ Self | NewController$ Player.withMostLife
SVar:RemAIDeck:True
SVar:Picture:http://www.wizards.com/global/images/magic/general/ghazban_ogre.jpg
Oracle:At the beginning of your upkeep, if a player has more life than each other player, the player with the most life gains control of Ghazbán Ogre.
Oracle:At the beginning of your upkeep, if a player has more life than each other player, the player with the most life gains control of Ghazban Ogre.

View File

@@ -1,8 +1,8 @@
Name:Ifh-Bíff Efreet
Name:Ifh-Biff Efreet
ManaCost:2 G G
Types:Creature Efreet
PT:3/3
K:Flying
A:AB$ DamageAll | Cost$ G | NumDmg$ 1 | ValidCards$ Creature.withFlying | ValidPlayers$ Each | ValidDescription$ each creature with flying and each player. | AnyPlayer$ True | SpellDescription$ CARDNAME deals 1 damage to each creature with flying and each player. Any player may activate this ability.
SVar:Picture:http://resources.wizards.com/magic/cards/an/en-us/card947.jpg
Oracle:Flying\n{G}: Ifh-Bíff Efreet deals 1 damage to each creature with flying and each player. Any player may activate this ability.
Oracle:Flying\n{G}: Ifh-Biff Efreet deals 1 damage to each creature with flying and each player. Any player may activate this ability.

View File

@@ -1,8 +1,8 @@
Name:Junún Efreet
Name:Junun Efreet
ManaCost:1 B B
Types:Creature Efreet
PT:3/3
K:Flying
K:At the beginning of your upkeep, sacrifice CARDNAME unless you pay B B
SVar:Picture:http://www.wizards.com/global/images/magic/general/junun_efreet.jpg
Oracle:Flying\nAt the beginning of your upkeep, sacrifice Junún Efreet unless you pay {B}{B}.
Oracle:Flying\nAt the beginning of your upkeep, sacrifice Junun Efreet unless you pay {B}{B}.

View File

@@ -1,8 +1,8 @@
Name:Juzám Djinn
Name:Juzam Djinn
ManaCost:2 B B
Types:Creature Djinn
PT:5/5
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigDealDamage | TriggerDescription$ At the beginning of your upkeep, CARDNAME deals 1 damage to you.
SVar:TrigDealDamage:AB$DealDamage | Cost$ 0 | Defined$ You | NumDmg$ 1
SVar:Picture:http://resources.wizards.com/magic/cards/an/en-us/card922.jpg
Oracle:At the beginning of your upkeep, Juzám Djinn deals 1 damage to you.
Oracle:At the beginning of your upkeep, Juzam Djinn deals 1 damage to you.

View File

@@ -1,4 +1,4 @@
Name:Khabál Ghoul
Name:Khabal Ghoul
ManaCost:2 B
Types:Creature Zombie
PT:1/1
@@ -6,4 +6,4 @@ T:Mode$ Phase | Phase$ End of Turn | TriggerZones$ Battlefield | Execute$ TrigPu
SVar:TrigPutCounter:AB$PutCounter | Cost$ 0 | Defined$ Self | CounterType$ P1P1 | CounterNum$ X | References$ X
SVar:X:Count$ThisTurnEntered_Graveyard_from_Battlefield_Creature
SVar:Picture:http://www.wizards.com/global/images/magic/general/khabal_ghoul.jpg
Oracle:At the beginning of each end step, put a +1/+1 counter on Khabál Ghoul for each creature that died this turn.
Oracle:At the beginning of each end step, put a +1/+1 counter on Khabal Ghoul for each creature that died this turn.

View File

@@ -1,4 +1,4 @@
Name:Legions of Lim-Dûl
Name:Legions of Lim-Dul
ManaCost:1 B B
Types:Creature Zombie
PT:2/3

View File

@@ -1,4 +1,4 @@
Name:Lim-Dûl the Necromancer
Name:Lim-Dul the Necromancer
ManaCost:5 B B
Types:Legendary Creature Human Wizard
PT:4/4

View File

@@ -1,4 +1,4 @@
Name:Lim-Dûl's Cohort
Name:Lim-Dul's Cohort
ManaCost:1 B B
Types:Creature Zombie
PT:2/3
@@ -7,4 +7,4 @@ T:Mode$ AttackerBlockedByCreature | ValidCard$ Card.Self | ValidBlocker$ Creatur
SVar:TrigBlocks:AB$Pump | Cost$ 0 | Defined$ TriggeredAttacker | KW$ HIDDEN CARDNAME can't be regenerated.
SVar:TrigBlocked:AB$Pump | Cost$ 0 | Defined$ TriggeredBlocker | KW$ HIDDEN CARDNAME can't be regenerated.
SVar:Picture:http://www.wizards.com/global/images/magic/general/lim_duls_cohort.jpg
Oracle:Whenever Lim-Dûl's Cohort blocks or becomes blocked by a creature, that creature can't be regenerated this turn.
Oracle:Whenever Lim-Dul's Cohort blocks or becomes blocked by a creature, that creature can't be regenerated this turn.

View File

@@ -1,4 +1,4 @@
Name:Lim-Dûl's Hex
Name:Lim-Dul's Hex
ManaCost:1 B
Types:Enchantment
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigRepeat | TriggerDescription$ At the beginning of your upkeep, for each player, CARDNAME deals 1 damage to that player unless he or she pays {B} or {3}.
@@ -7,4 +7,4 @@ SVar:DBChoose:DB$ GenericChoice | Defined$ Player.IsRemembered | Choices$ PayB,P
SVar:PayB:DB$ DealDamage | Defined$ Player.IsRemembered | NumDmg$ 1 | UnlessCost$ B | UnlessPayer$ Player.IsRemembered | SpellDescription$ CARDNAME deals 1 damage to you unless you pay {B}
SVar:Pay3:DB$ DealDamage | Defined$ Player.IsRemembered | NumDmg$ 1 | UnlessCost$ 3 | UnlessPayer$ Player.IsRemembered | SpellDescription$ CARDNAME deals 1 damage to you unless you pay {3}
SVar:Picture:http://www.wizards.com/global/images/magic/general/lim_duls_hex.jpg
Oracle:At the beginning of your upkeep, for each player, Lim-Dûl's Hex deals 1 damage to that player unless he or she pays {B} or {3}.
Oracle:At the beginning of your upkeep, for each player, Lim-Dul's Hex deals 1 damage to that player unless he or she pays {B} or {3}.

View File

@@ -1,8 +1,8 @@
Name:Lim-Dûl's High Guard
Name:Lim-Dul's High Guard
ManaCost:1 B B
Types:Creature Skeleton
PT:2/1
K:First Strike
A:AB$ Regenerate | Cost$ 1 B | SpellDescription$ Regenerate CARDNAME.
SVar:Picture:http://www.wizards.com/global/images/magic/general/lim_duls_high_guard.jpg
Oracle:First strike\n{1}{B}: Regenerate Lim-Dûl's High Guard.
Oracle:First strike\n{1}{B}: Regenerate Lim-Dul's High Guard.

View File

@@ -1,4 +1,4 @@
Name:Lim-Dûl's Paladin
Name:Lim-Dul's Paladin
ManaCost:2 B R
Types:Creature Human Knight
PT:0/3
@@ -16,4 +16,4 @@ SVar:DBLoseLife:DB$ LoseLife | Defined$ DefendingPlayer | LifeAmount$ 4
SVar:X:Remembered$Amount
SVar:RemAIDeck:True
SVar:Picture:http://www.wizards.com/global/images/magic/general/lim_duls_paladin.jpg
Oracle:Trample\nAt the beginning of your upkeep, you may discard a card. If you don't, sacrifice Lim-Dûl's Paladin and draw a card.\nWhenever Lim-Dûl's Paladin becomes blocked, it gets +6/+3 until end of turn.\nWhenever Lim-Dûl's Paladin attacks and isn't blocked, it assigns no combat damage to defending player this turn and that player loses 4 life.
Oracle:Trample\nAt the beginning of your upkeep, you may discard a card. If you don't, sacrifice Lim-Dul's Paladin and draw a card.\nWhenever Lim-Dul's Paladin becomes blocked, it gets +6/+3 until end of turn.\nWhenever Lim-Dul's Paladin attacks and isn't blocked, it assigns no combat damage to defending player this turn and that player loses 4 life.

View File

@@ -1,4 +1,4 @@
Name:Lim-Dûl's Vault
Name:Lim-Dul's Vault
ManaCost:U B
Types:Instant
A:SP$ Dig | Cost$ U B | DigNum$ 5 | NoMove$ True | SubAbility$ DBRepeat | RememberRevealed$ True | StackDescription$ SpellDescription | SpellDescription$ Look at the top five cards of your library. As many times as you choose, you may pay 1 life, put those cards on the bottom of your library in any order, then look at the top five cards of your library. Then shuffle your library and put the last cards you looked at this way on top of it in any order.

View File

@@ -1,4 +1,4 @@
Name:Márton Stromgald
Name:Marton Stromgald
ManaCost:2 R R
Types:Legendary Creature Human Knight
PT:1/1
@@ -9,4 +9,4 @@ T:Mode$ Blocks | ValidCard$ Card.Self | Triggerzones$ Battlefield | Execute$ Tri
SVar:TrigPumpBlock:AB$ PumpAll | Cost$ 0 | ValidCards$ Creature.blocking+Other | NumAtt$ Y | NumDef$ Y | References$ Y
SVar:Y:Count$Valid Creature.blocking+Other
SVar:Picture:http://www.wizards.com/global/images/magic/general/marton_stromgald.jpg
Oracle:Whenever Márton Stromgald attacks, other attacking creatures get +1/+1 until end of turn for each attacking creature other than Márton Stromgald.\nWhenever Márton Stromgald blocks, other blocking creatures get +1/+1 until end of turn for each blocking creature other than Márton Stromgald.
Oracle:Whenever Marton Stromgald attacks, other attacking creatures get +1/+1 until end of turn for each attacking creature other than Marton Stromgald.\nWhenever Marton Stromgald blocks, other blocking creatures get +1/+1 until end of turn for each blocking creature other than Marton Stromgald.

View File

@@ -1,4 +1,4 @@
Name:Oath of Lim-Dûl
Name:Oath of Lim-Dul
ManaCost:3 B
Types:Enchantment
T:Mode$ LifeLost | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigLimDulSac | TriggerDescription$ Whenever you lose life, for each 1 life you lost, sacrifice a permanent other than CARDNAME unless you discard a card. (Damage dealt to you causes you to lose life.)
@@ -8,4 +8,4 @@ A:AB$ Draw | Cost$ B B | NumCards$ 1 | SpellDescription$ Draw a card.
SVar:X:TriggerCount$LifeAmount
SVar:RemAIDeck:True
SVar:Picture:http://www.wizards.com/global/images/magic/general/oath_of_lim_dul.jpg
Oracle:Whenever you lose life, for each 1 life you lost, sacrifice a permanent other than Oath of Lim-Dûl unless you discard a card. (Damage dealt to you causes you to lose life.)\n{B}{B}: Draw a card.
Oracle:Whenever you lose life, for each 1 life you lost, sacrifice a permanent other than Oath of Lim-Dul unless you discard a card. (Damage dealt to you causes you to lose life.)\n{B}{B}: Draw a card.

View File

@@ -1,4 +1,4 @@
Name:Séance
Name:Seance
ManaCost:2 W W
Types:Enchantment
T:Mode$ Phase | Phase$ Upkeep | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigExile | TriggerDescription$ At the beginning of each upkeep, you may exile target creature card from your graveyard. If you do, put a token onto the batttlefield that's a copy of that card except it's a Spirit in addition to its other types. Exile it at the beginning of the next end step.

View File

@@ -15,34 +15,34 @@ Name=ArabianExtended
1 City in a Bottle|ARN
1 City of Brass|ARN
1 Dancing Scimitar|ARN
1 Dandân|ARN
1 Dandan|ARN
1 Desert|ARN
1 Desert Nomads|ARN
1 Desert Twister|ARN
1 Diamond Valley|ARN
1 Drop of Honey|ARN
1 Ebony Horse|ARN
1 El-Hajjâj|ARN
1 El-Hajjaj|ARN
1 Elephant Graveyard|ARN
1 Erg Raiders|ARN
1 Erhnam Djinn|ARN
1 Fishliver Oil|ARN
1 Flying Carpet|ARN
1 Flying Men|ARN
1 Ghazbán Ogre|ARN
1 Ghazban Ogre|ARN
1 Giant Tortoise|ARN
1 Hasran Ogress|ARN
1 Hurr Jackal|ARN
1 Ifh-Bíff Efreet|ARN
1 Ifh-Biff Efreet|ARN
1 Island Fish Jasconius|ARN
1 Island of Wak-Wak|ARN
1 Jandor's Ring|ARN
1 Jandor's Saddlebags|ARN
1 Jeweled Bird|ARN
1 Jihad|ARN
1 Junún Efreet|ARN
1 Juzám Djinn|ARN
1 Khabál Ghoul|ARN
1 Junun Efreet|ARN
1 Juzam Djinn|ARN
1 Khabal Ghoul|ARN
1 King Suleiman|ARN
1 Kird Ape|ARN
1 Library of Alexandria|ARN
@@ -89,7 +89,7 @@ Name=ArabianExtended
1 Telim'Tor's Edict|MIR
1 Unfulfilled Desires|MIR
1 Drifting Djinn|USG
1 El-Hajjâj|3ED
1 El-Hajjaj|3ED
1 Emberwilde Caliph|MIR
1 Island Fish Jasconius|3ED
1 Mijae Djinn|3ED

View File

@@ -103,10 +103,10 @@ R Lake of the Dead
C Lat-Nam's Legacy
C Lat-Nam's Legacy
R Library of Lat-Nam
C Lim-Dûl's High Guard
C Lim-Dûl's High Guard
U Lim-Dûl's Paladin
U Lim-Dûl's Vault
C Lim-Dul's High Guard
C Lim-Dul's High Guard
U Lim-Dul's Paladin
U Lim-Dul's Vault
R Lodestone Bauble
R Lord of Tresserhorn
C Martyrdom

View File

@@ -28,14 +28,14 @@ U City of Brass
C Cuombajj Witches
U Cyclone
R Dancing Scimitar
C Dandân
C Dandan
C Desert
C Desert Nomads
U Desert Twister
U Diamond Valley
R Drop of Honey
R Ebony Horse
R El-Hajjâj
R El-Hajjaj
R Elephant Graveyard
C Erg Raiders
C Erg Raiders
@@ -45,23 +45,23 @@ C Fishliver Oil
C Fishliver Oil
U Flying Carpet
C Flying Men
C Ghazbán Ogre
C Ghazban Ogre
C Giant Tortoise
C Giant Tortoise
R Guardian Beast
C Hasran Ogress
C Hasran Ogress
C Hurr Jackal
R Ifh-Bíff Efreet
R Ifh-Biff Efreet
R Island Fish Jasconius
R Island of Wak-Wak
R Jandor's Ring
R Jandor's Saddlebags
U Jeweled Bird
R Jihad
R Junún Efreet
R Juzám Djinn
U Khabál Ghoul
R Junun Efreet
R Juzam Djinn
U Khabal Ghoul
R King Suleiman
C Kird Ape
U Library of Alexandria

View File

@@ -43,7 +43,7 @@ R Cyclone
C D'Avenant Archer
R Dakkon Blackblade
R Dance of Many
C Dandân
C Dandan
C Divine Offering
C Emerald Dragonfly
U Enchantment Alteration
@@ -56,7 +56,7 @@ C Flash Flood
C Fountain of Youth
R Gabriel Angelfire
R Gauntlets of Chaos
C Ghazbán Ogre
C Ghazban Ogre
C Giant Slug
U Goblin Artisans
C Goblin Digging Team

View File

@@ -202,7 +202,7 @@ C Hull Breach
M Jeleva, Nephalia's Scourge
U Jund Charm
U Leafdrake Roost
U Lim-Dûl's Vault
U Lim-Dul's Vault
M Marath, Will of the Wild
M Mayael the Anima
U Naya Charm

View File

@@ -127,7 +127,7 @@ C Saving Grasp
C Scorch the Fields
C Scorned Villager
C Screeching Skaab
R Séance
R Seance
U Secrets of the Dead
U Shattered Perception
C Shriekgeist

View File

@@ -98,7 +98,7 @@ U Cursed Land
C D'Avenant Archer
R Dance of Many
R Dancing Scimitar
C Dandân
C Dandan
C Dark Maze
C Dark Ritual
C Death Speakers
@@ -172,7 +172,7 @@ U Fyndhorn Elder
R Game of Chaos
C Gaseous Form
R Gauntlets of Chaos
C Ghazbán Ogre
C Ghazban Ogre
C Giant Growth
C Giant Spider
C Giant Strength

View File

@@ -111,7 +111,7 @@ C Dwarven Warriors
U Earth Elemental
R Earthquake
R Ebony Horse
R El-Hajjâj
R El-Hajjaj
R Elder Land Wurm
U Elven Riders
R Elvish Archers
@@ -188,7 +188,7 @@ R Jade Monolith
R Jandor's Saddlebags
R Jayemdae Tome
C Jump
U Junún Efreet
U Junun Efreet
U Karma
U Keldon Warlord
U Killer Bees

View File

@@ -213,19 +213,19 @@ R Land Cap
U Lapis Lazuli Talisman
C Lava Burst
R Lava Tubes
C Legions of Lim-Dûl
C Legions of Lim-Dul
U Leshrac's Rite
U Leshrac's Sigil
R Lhurgoyf
R Lightning Blow
C Lim-Dûl's Cohort
U Lim-Dûl's Hex
C Lim-Dul's Cohort
U Lim-Dul's Hex
R Lost Order of Jarkeld
U Lure
U Maddening Wind
R Magus of the Unseen
U Malachite Talisman
R Márton Stromgald
R Marton Stromgald
U Melee
U Melting
R Mercenaries
@@ -255,7 +255,7 @@ R Naked Singularity
U Nature's Lore
R Necropotence
C Norritt
R Oath of Lim-Dûl
R Oath of Lim-Dul
U Onyx Talisman
U Orcish Cannoneers
C Orcish Conscripts

View File

@@ -50,7 +50,7 @@ R Dakmor Sorceress
U Dark Offering
R Deathcoil Wurm
U Deep Wood
C Déjà Vu
C Deja Vu
R Denizen of the Deep
R Earthquake
R Exhaustion

View File

@@ -54,7 +54,7 @@ R Cruel Tutor
U Deep Wood
U Deep-Sea Serpent
U Defiant Stand
C Déjà Vu
C Deja Vu
U Desert Drake
R Devastation
C Devoted Hero

View File

@@ -88,7 +88,7 @@ U Earth Elemental
C Earthbind
R Earthquake
R Ebony Horse
R El-Hajjâj
R El-Hajjaj
R Elvish Archers
U Energy Flux
C Erg Raiders

View File

@@ -23,7 +23,7 @@ S Cockatrice
S Consecrate Land
S Conspiracy
S Craw Giant
S Dandân
S Dandan
S Darkness
S Dauthi Slayer
S Defiant Vanguard

View File

@@ -144,7 +144,7 @@ U Knight of the Holy Nimbus
U Krosan Grip
R Liege of the Pit
C Lightning Axe
R Lim-Dûl the Necromancer
R Lim-Dul the Necromancer
R Living End
U Locket of Yesterdays
C Looter il-Kor

View File

@@ -51,8 +51,8 @@ Deck Type=constructed
1 Illusionary Wall
1 Illusions of Grandeur
1 Imaginary Pet
1 Junún Efreet
1 Juzám Djinn
1 Junun Efreet
1 Juzam Djinn
1 Kezzerdrix
1 Kuro, Pitlord
1 Liege of the Pit

View File

@@ -19,7 +19,7 @@ Deck Type=constructed
1 Grasp of Darkness|SOM
1 Unholy Grotto|ONS
1 Spined Basher|ONS
1 Legions of Lim-Dûl|ICE
1 Legions of Lim-Dul|ICE
1 Stromgald Crusader|CSP
1 Dreg Reaver|ALA
1 Dross Crocodile|10E

View File

@@ -38,7 +38,7 @@ Deck Type=constructed
1 Feeding Frenzy|ONS
1 Spineless Thug|10E
1 Call to the Grave|SCG
1 Lim-Dûl the Necromancer|TSP
1 Lim-Dul the Necromancer|TSP
1 Lord of the Undead|PLS
1 Vengeful Dead|SCG
1 Grave Defiler|APC

View File

@@ -18,7 +18,7 @@ Deck Type=constructed
1 Inundate
2 Boomerang
2 Eye of Nowhere
1 Dandân
1 Dandan
4 Faerie Swarm
1 Manta Ray
2 Invisibility

View File

@@ -25,7 +25,7 @@ Deck Type=constructed
2 Concentrate
1 Kami of the Crescent Moon
1 Thalakos Seer
1 Dandân
1 Dandan
1 Manta Ray
1 Serpent of the Endless Sea
1 Amnesia

View File

@@ -26,7 +26,7 @@ Deck Type=constructed
4 Geralf's Mindcrusher
1 Grixis Slavedriver
4 Havengul Runebinder
1 Lim-Dûl the Necromancer
1 Lim-Dul the Necromancer
3 Lord of the Undead
1 Mikaeus, the Unhallowed
2 Relentless Skaabs

View File

@@ -10,7 +10,7 @@ Deck Type=constructed
Set=FUT
Image=fate_blaster.jpg
[main]
1 Dandân|TSB
1 Dandan|TSB
1 Uthden Troll|TSB
2 Barbed Shocker|TSP
2 Sage of Epityr|TSP

View File

@@ -13,7 +13,7 @@ Image=snowscape.jpg
1 Arcum's Weathervane|ICE
2 Drift of the Dead|ICE
1 Gangrenous Zombies|ICE
2 Legions of Lim-Dûl|ICE
2 Legions of Lim-Dul|ICE
2 Essence Flare|ICE
1 Iceberg|ICE
2 Mistfolk|ICE

View File

@@ -15,7 +15,7 @@ Water Wurm
[Group MaxCnt=4 Percentage=10]
Stonybrook Banneret
Dandân
Dandan
Hammerhead Shark
[/Group]
@@ -59,4 +59,4 @@ Slipstream Serpent
Zhou Yu, Chief Commander
[/Group]
End
End

View File

@@ -32,7 +32,7 @@ Dross Prowler
Feeding Frenzy
Headless Horseman
Infectious Host
Lim-Dûl's Cohort
Lim-Dul's Cohort
Organ Grinder
Phyrexian Crusader
Rotlung Reanimator
@@ -82,9 +82,9 @@ Dripping Dead
Geth, Lord of the Vault
Grixis Slavedriver
Helldozer
Lim-Dûl the Necromancer
Lim-Dul the Necromancer
Tresserhorn Skyknight
Twisted Abomination
[/Group]
End
End

View File

@@ -25,7 +25,7 @@ Deck Type=constructed
2 Dwarven Miner|MIR
2 Gorilla Shaman|ALL
4 Icequake|ICE
4 Juzám Djinn|ARN
4 Juzam Djinn|ARN
4 Knight of Stromgald|ICE
4 Mishra's Factory|ATQ
4 Mox Jet|LEB

View File

@@ -8,7 +8,7 @@ Description=Akongo plays John's Meta-Weenie PCL deck.
Deck Type=constructed
[main]
11 Forest|MIR
4 Ghazbán Ogre|ARN
4 Ghazban Ogre|ARN
4 Giant Growth|LEB
3 Granger Guildmage|MIR
4 Incinerate|MIR

View File

@@ -18,7 +18,7 @@ Deck Type=constructed
1 Fetid Horror|MIR
1 Gravebane Zombie|MIR
2 Hypnotic Specter|LEB
2 Junún Efreet|ARN
2 Junun Efreet|ARN
1 Kaervek's Hex|MIR
1 Mox Jet|LEB
1 Nocturnal Raid|MIR

View File

@@ -11,7 +11,7 @@ Card Reward=14% chosen card sets:5ED,MIR,VIS rules:green,creature rarity:C,U des
2 Berserk|LEB
16 Forest|MIR
4 Llanowar Elves|5ED
4 Ghazbán Ogre|ARN
4 Ghazban Ogre|ARN
4 Giant Growth|LEB
3 Harvest Wurm|WTH
2 Heart of Yavimaya|ALL

View File

@@ -19,7 +19,7 @@ Deck Type=constructed
1 Fork|LEB
4 Gemstone Mine|WTH
1 Ivory Tower|ATQ
1 Juzám Djinn|ARN
1 Juzam Djinn|ARN
1 Library of Alexandria|ARN
2 Lightning Bolt|LEB
4 Lotus Petal|TMP

View File

@@ -13,7 +13,7 @@ Deck Type=constructed
2 Emerald Charm|VIS
3 Fallow Wurm|WTH
16 Forest|MIR
3 Ghazbán Ogre|ARN
3 Ghazban Ogre|ARN
3 Giant Growth|5ED
4 Harvest Wurm|WTH
2 Heart of Yavimaya|ALL

View File

@@ -13,7 +13,7 @@ Deck Type=constructed
2 Desert Twister|ARN
24 Forest|MIR
4 Llanowar Elves|5ED
3 Ghazbán Ogre|ARN
3 Ghazban Ogre|ARN
3 Giant Growth|5ED
2 Hurricane|5ED
3 River Boa|VIS

View File

@@ -23,7 +23,7 @@ Deck Type=constructed
2 Greed|LEG
2 Howl from Beyond|LEB
4 Hypnotic Specter|4ED
2 Juzám Djinn|ARN
2 Juzam Djinn|ARN
2 Lord of the Pit|LEB
1 Mind Twist|LEB
1 Mox Jet|LEB

View File

@@ -7,7 +7,7 @@ Wins=30
Card Reward=33% chosen card sets:3ED,4ED,ARN,ATQ,DRK,LEG rules:green desc:a Green card;chosen card sets:3ED,4ED,ARN,ATQ,DRK,LEG rules:green desc:a Green card;3 green rares;50% 1 green rare
Credit Reward=250
HumanExtras=Concordant Crossroads
AIExtras=Ghazbán Ogre
AIExtras=Ghazban Ogre
[metadata]
Name=quest7
Title=Green Castle (Green)
@@ -23,7 +23,7 @@ Deck Type=constructed
22 Forest|4ED
1 Gaea's Avenger|ATQ
4 Gaea's Liege|4ED
2 Ifh-Bíff Efreet|ARN
2 Ifh-Biff Efreet|ARN
1 Island of Wak-Wak|ARN
1 Ivory Tower|ATQ
2 Jayemdae Tome|4ED

View File

@@ -10,7 +10,7 @@ Deck Type=constructed
2 Ashes to Ashes|DRK
2 City of Brass|CHR
3 Drain Life|2ED
2 El-Hajjâj|ARN
2 El-Hajjaj|ARN
2 Erg Raiders|ARN
6 Forest|2ED
2 Fungusaur|LEB

View File

@@ -11,7 +11,7 @@ Deck Type=constructed
4 Bayou|2ED
2 City of Brass|CHR
3 Drain Life|2ED
2 El-Hajjâj|ARN
2 El-Hajjaj|ARN
2 Erg Raiders|ARN
2 Forest|2ED
2 Giant Growth|2ED
@@ -19,7 +19,7 @@ Deck Type=constructed
2 Greed|LEG
4 Healing Salve|2ED
2 Hurricane|2ED
2 Juzám Djinn|ARN
2 Juzam Djinn|ARN
3 Onulet|ATQ
4 Plains|2ED
4 Savannah|2ED

View File

@@ -15,7 +15,7 @@ Deck Type=constructed
2 Energy Flux|ATQ
7 Forest|2ED
7 Island|2ED
2 Junún Efreet|ARN
2 Junun Efreet|ARN
2 Lord of the Pit|2ED
2 Mahamoti Djinn|2ED
2 Phantasmal Forces|2ED

View File

@@ -16,7 +16,7 @@ Deck Type=constructed
2 Erhnam Djinn|ARN
4 Forest|4ED
5 Island|4ED
1 Junún Efreet|ARN
1 Junun Efreet|ARN
2 Lord of the Pit|2ED
2 Mahamoti Djinn|2ED
1 Phantasmal Forces|2ED

View File

@@ -14,7 +14,7 @@ Deck Type=constructed
3 Drudge Skeletons|4ED
3 Healing Salve|4ED
3 Holy Strength|4ED
2 Khabál Ghoul|ARN
2 Khabal Ghoul|ARN
2 Ornithopter|4ED
3 Osai Vultures|LEG
3 Pestilence|4ED

View File

@@ -13,7 +13,7 @@ Deck Type=constructed
2 Fellwar Stone|DRK
4 Hypnotic Specter|4ED
9 Island|4ED
2 Junún Efreet|ARN
2 Junun Efreet|ARN
2 Mana Drain|LEG
1 Mind Twist|LEB
2 Phantasmal Forces|LEB

View File

@@ -12,7 +12,7 @@ Deck Type=constructed
3 Bog Rats|DRK
3 Erg Raiders|ARN
2 Frozen Shade|LEB
2 Junún Efreet|ARN
2 Junun Efreet|ARN
2 Kormus Bell|LEB
4 Lord of the Pit|LEB
4 Mishra's Factory|ATQ

View File

@@ -10,7 +10,7 @@ Deck Type=constructed
4 Animate Dead|LEB
4 Black Knight|4ED
4 Erg Raiders|ARN
2 Khabál Ghoul|ARN
2 Khabal Ghoul|ARN
4 Lord of the Pit|LEB
4 Mishra's Factory|ATQ
4 Nether Shadow|LEB

View File

@@ -9,7 +9,7 @@ Deck Type=constructed
[main]
3 Counterspell|4ED
4 Creature Bond|LEB
4 Dandân|ARN
4 Dandan|ARN
4 Giant Tortoise|ARN
22 Island|4ED
2 Island Fish Jasconius|ARN

View File

@@ -9,7 +9,7 @@ Deck Type=constructed
[main]
4 Azure Drake|LEG
4 Counterspell|4ED
1 Dandân|ARN
1 Dandan|ARN
4 Giant Tortoise|ARN
26 Island|4ED
2 Island Fish Jasconius|ARN

View File

@@ -10,7 +10,7 @@ Deck Type=constructed
4 Bad Moon|2ED
4 Black Knight|2ED
2 Drudge Skeletons|2ED
3 El-Hajjâj|ARN
3 El-Hajjaj|ARN
2 Fear|LEB
2 Flying Carpet|ARN
2 Frozen Shade|LEB

View File

@@ -8,7 +8,7 @@ Description=Black hard-to-block creatures with special abilities.
Deck Type=constructed
[main]
3 Bad Moon|LEB
4 El-Hajjâj|ARN
4 El-Hajjaj|ARN
4 Fear|LEB
2 Frozen Shade|LEB
4 Hypnotic Specter|2ED

View File

@@ -1,18 +1,16 @@
package forge.limited;
import com.esotericsoftware.minlog.Log;
import forge.properties.ForgeConstants;
import forge.util.FileUtil;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import com.esotericsoftware.minlog.Log;
import forge.properties.ForgeConstants;
import forge.util.FileUtil;
/**
* ReadDraftRankings class.
*
*/
public class ReadDraftRankings {
@@ -32,23 +30,19 @@ public class ReadDraftRankings {
this.draftRankings = this.readFile(FileUtil.readFile(ForgeConstants.DRAFT_RANKINGS_FILE));
} // setup()
private static String getRankingCardName(final String name) {
return StringUtils.replaceChars(name.trim(), "-áàâéèêúùûíìîóòô", " aaaeeeuuuiiiooo").replaceAll("[^A-Za-z ]", "");
}
/**
* <p>
* readFile.
* </p>
*
*
* @param file
* a {@link java.io.File} object.
* @return a {@link java.util.Map} object.
*/
private Map<String, Map<String, Integer>> readFile(final List<String> lines) {
private Map<String, Map<String, Integer>> readFile(List<String> lines) {
final Map<String, Map<String, Integer>> map = new HashMap<String, Map<String, Integer>>();
for (final String line : lines) {
for (String line : lines) {
// stop reading if end of file or blank line is read
if (line == null || line.length() == 0) {
break;
@@ -59,7 +53,7 @@ public class ReadDraftRankings {
}
final String[] s = line.split("\\|");
final String rankStr = s[0].trim().substring(1);
final String name = getRankingCardName(s[1]);
final String name = s[1].trim().replaceAll("-", " ").replaceAll("[^A-Za-z ]", "");
// final String rarity = s[2].trim();
final String edition = s[3].trim();
@@ -74,7 +68,7 @@ public class ReadDraftRankings {
} else {
setSizes.put(edition, rank);
}
} catch (final NumberFormatException nfe) {
} catch (NumberFormatException nfe) {
Log.warn("NumberFormatException: " + nfe.getMessage());
}
}
@@ -84,24 +78,26 @@ public class ReadDraftRankings {
/**
* Get the relative ranking for the given card name in the given edition.
*
*
* @param cardName
* the card name
* @param edition
* the card's edition
* @return ranking
*/
public Double getRanking(final String cardName, final String edition) {
public Double getRanking(String cardName, String edition) {
Double rank = null;
if (draftRankings.containsKey(edition)) {
final String safeName = getRankingCardName(cardName);
String safeName = cardName.replaceAll("-", " ").replaceAll("[^A-Za-z ]", "");
// If a card has no ranking, don't try to look it up --BBU
if (draftRankings.get(edition).get(safeName) == null) {
// System.out.println("WARNING! " + safeName + " NOT found in " + edition);
return null;
}
return Double.valueOf(draftRankings.get(edition).get(safeName).doubleValue() / setSizes.get(edition).doubleValue());
rank = (double) draftRankings.get(edition).get(safeName) / (double) setSizes.get(edition);
}
return null;
return rank;
}
}