merge latest trunk

This commit is contained in:
myk
2013-03-08 10:27:40 +00:00
10 changed files with 99 additions and 397 deletions

5
.gitattributes vendored
View File

@@ -1215,6 +1215,7 @@ res/cardsfolder/b/bottled_cloister.txt -text
res/cardsfolder/b/bottomless_pit.txt svneol=native#text/plain
res/cardsfolder/b/bottomless_vault.txt svneol=native#text/plain
res/cardsfolder/b/bouncing_beebles.txt svneol=native#text/plain
res/cardsfolder/b/bound_determined.txt -text
res/cardsfolder/b/bound_in_silence.txt svneol=native#text/plain
res/cardsfolder/b/boundless_realms.txt -text
res/cardsfolder/b/bounteous_kirin.txt svneol=native#text/plain
@@ -4904,6 +4905,7 @@ res/cardsfolder/h/hisokas_defiance.txt svneol=native#text/plain
res/cardsfolder/h/hisokas_guard.txt svneol=native#text/plain
res/cardsfolder/h/hissing_iguanar.txt svneol=native#text/plain
res/cardsfolder/h/hissing_miasma.txt svneol=native#text/plain
res/cardsfolder/h/hit_run.txt -text
res/cardsfolder/h/hive_mind.txt -text
res/cardsfolder/h/hivestone.txt svneol=native#text/plain
res/cardsfolder/h/hivis_of_the_scale.txt svneol=native#text/plain
@@ -8636,6 +8638,7 @@ res/cardsfolder/r/riptide_pilferer.txt svneol=native#text/plain
res/cardsfolder/r/riptide_replicator.txt -text
res/cardsfolder/r/riptide_shapeshifter.txt -text svneol=unset#text/plain
res/cardsfolder/r/riptide_survivor.txt svneol=native#text/plain
res/cardsfolder/r/rise_fall.txt -text
res/cardsfolder/r/rise_from_the_grave.txt svneol=native#text/plain
res/cardsfolder/r/rise_of_the_hobgoblins.txt svneol=native#text/plain
res/cardsfolder/r/risen_sanctuary.txt -text
@@ -13244,7 +13247,6 @@ res/quest/world/shandalar/duels/Winged[!!-~]Stallion[!!-~]3.dck -text
res/quest/world/shandalar/duels/Witch[!!-~]2.dck -text
res/quest/world/shandalar/duels/Witch[!!-~]3.dck -text
res/quest/world/worlds.txt -text
res/reprintSetInfo.py svneol=native#text/x-python
res/sealed/ArabianExtended.sealed -text
res/sealed/GtcGuildBoros.sealed -text
res/sealed/GtcGuildDimir.sealed -text
@@ -13267,7 +13269,6 @@ res/sealed/RtRPromoIzzet.sealed -text
res/sealed/RtRPromoRakdos.sealed -text
res/sealed/RtRPromoSelesnya.sealed -text
res/sealed/juzamjedi.sealed -text
res/setInfoScript.py svneol=native#text/x-python
res/skins/dark_ascension/bg_match.jpg -text
res/skins/dark_ascension/bg_splash.png -text
res/skins/dark_ascension/bg_texture.jpg -text

View File

@@ -10,8 +10,6 @@ A new quest world by Serrasmurf based on Ravinca has been added.
An effort is being made to implement the split cards (e.g. Fire/Ice) in Forge. The initial effort to add support for split cards may be considered complete and the relevant branch has reen reintegrated to trunk. Expect some rough edges and incompatibilities along the way.
The "Scale Image Larger" option in the preferences should be fixed. It should no longer continue to scale images larger when it is disabled.
The fat packs should now be available for purchase in the quest mode card shop.
Information for non-card items in spell shop are now shown in the card details panel.

View File

@@ -122,18 +122,22 @@ if __name__ == '__main__':
cardName = firstLine[5:]
altName = None
previousLines = []
previousLines.append(firstLine)
validLines = []
validLines.append(firstLine)
for line in cardfile.readlines():
if line[:8] != "SetInfo:" and line[:8] != "SVar:Rar":
previousLines.append(line.strip())
# Just in case SVar:Rar is used as a legitimate SVar
if not line.startswith("SetInfo:") and not line.startswith("SVar:Rarity:"):
validLines.append(line.strip())
if line[:5] == "Name:":
if line.startswith("Name:"):
altName = line[5:].strip()
cardfile.close()
print (cardName, altName, fileName)
if not cardName in mtgDataCards and not altName is None:
cardName = altName
@@ -141,6 +145,11 @@ if __name__ == '__main__':
if not setCodeToForge[e] is None:
validLines.append( "SetInfo:{} {}".format(setCodeToForge[e], mtgDataCards[cardName][e]) )
if previousLines == validLines:
continue
print (cardName, altName, fileName)
toWrite = "\n".join(validLines)
cardfile = open(os.path.join(root, fileName), 'w')

View File

@@ -0,0 +1,24 @@
Name:Bound
ManaCost:3 B G
AlternateMode: Split
Types:Instant
A:SP$ Sacrifice | Cost$ 3 B G | SacValid$ Creature | RememberSacrificed$ True | SubAbility$ DBReturnChoose | SpellDescription$ Sacrifice a creature. Return up to X cards from your graveyard to your hand, where X is the number of colors that creature was. Exile this card.
SVar:DBReturnChoose:DB$ ChooseCard | Defined$ You | Choices$ Card.YouOwn | ChoiceZone$ Graveyard | Amount$ X | References$ X | SubAbility$ DBReturn
SVar:DBReturn:DB$ ChangeZone | Origin$ Graveyard | Destination$ Hand | Defined$ ChosenCard | SubAbility$ ExileSelf
SVar:ExileSelf:DB$ ChangeZone | Origin$ Stack | Destination$ Exile | Defined$ Self | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
SVar:X:RememberedLKI$CardNumColors
SVar:Picture:http://www.wizards.com/global/images/magic/general/bounddetermined.jpg
Oracle:Sacrifice a creature. Return up to X cards from your graveyard to your hand, where X is the number of colors that creature was. Exile this card.
ALTERNATE
Name:Determined
ManaCost:U G
Types:Instant
A:SP$ Effect | Cost$ U G | StaticAbilities$ STCantbeCountered | SubAbility$ DBDraw | SpellDescription$ Other spells you control can't be countered by spells or abilities this turn. Draw a card.
SVar:STCantbeCountered:Mode$ Continuous | EffectZone$ Command | AffectedZone$ Stack | Affected$ Card.YouCtrl | AddHiddenKeyword$ CARDNAME can't be countered. | Description$ Other spells you control can't be countered by spells or abilities this turn.
SVar:DBDraw:DB$ Draw | Defined$ You | NumCards$ 1
Oracle:Other spells you control can't be countered by spells or abilities this turn.\nDraw a card.
SetInfo:DIS Rare

View File

@@ -0,0 +1,21 @@
Name:Hit
ManaCost:1 B R
AlternateMode: Split
Types:Instant
A:SP$ Sacrifice | Cost$ 1 B R | ValidTgts$ Player | SacValid$ Creature,Artifact | SacMessage$ Creature or Artifact | RememberSacrificed$ True | SubAbility$ DBDmg | SpellDescription$ Target player sacrifices an artifact or creature. Hit deals damage to that player equal to that permanent's converted mana cost.
SVar:DBDmg:DB$ DealDamage | NumDmg$ X | References$ X | Defined$ Targeted | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
SVar:X:Remembered$CardManaCost
SVar:Picture:http://www.wizards.com/global/images/magic/general/hitrun.jpg
Oracle:Target player sacrifices an artifact or creature. Hit deals damage to that player equal to that permanent's converted mana cost.
ALTERNATE
Name:Run
ManaCost:3 R G
Types:Instant
A:SP$ PumpAll | Cost$ 3 R G | ValidCards$ Creature.attacking+YouCtrl | NumAtt$ +Y | References$ Y | SpellDescription$ Attacking creatures you control get +1/+0 until end of turn for each other attacking creature.
SVar:Y:Count$Valid Creature.attacking/Minus.1
Oracle:Attacking creatures you control get +1/+0 until end of turn for each other attacking creature.
SetInfo:DIS Uncommon

View File

@@ -0,0 +1,21 @@
Name:Rise
ManaCost:U B
AlternateMode: Split
Types:Sorcery
A:SP$ ChangeZone | Cost$ U B | ValidTgts$ Creature | TgtPrompt$ Select target creature in a graveyard | Origin$ Graveyard | Destination$ Hand | SubAbility$ DBChangeZone | SpellDescription$ Return target creature card from a graveyard and target creature on the battlefield to their owners' hands.
SVar:DBChangeZone:DB$ ChangeZone | ValidTgts$ Creature | TgtPrompt$ Select target creature on the battlefield | Origin$ Battlefield | Destination$ Hand | IsCurse$ True
SVar:Picture:http://www.wizards.com/global/images/magic/general/risefall.jpg
Oracle:Return target creature card from a graveyard and target creature on the battlefield to their owners' hands.
ALTERNATE
Name:Fall
ManaCost:B R
Types:Sorcery
A:SP$ Reveal | Cost$ B R | ValidTgts$ Player | IsCurse$ True | Random$ True | NumCards$ 2 | RememberRevealed$ True | SubAbility$ DBDiscard | SpellDescription$ Target player reveals two cards at random from his or her hand, then discards each nonland card revealed this way.
SVar:DBDiscard:DB$ Discard | Mode$ Defined | Defined$ Targeted | DefinedCards$ ValidHand Card.nonLand+IsRemembered | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
Oracle:Target player reveals two cards at random from his or her hand, then discards each nonland card revealed this way.
SetInfo:DDH Uncommon
SetInfo:DIS Uncommon

View File

@@ -1,116 +0,0 @@
#!/usr/bin/env python
# This script grabs the list of all cards in a set and clears out the setInfo
# After running this script, re-run setInfoScript to fill in the slots
# Run this Script with a command line argument, as below
# $ python reprintSetInfo.py <SetAbbr>
# $ python reprintSetInfo.py M12
from httplib import HTTP
from urlparse import urlparse
from urllib import urlopen
import sys
import os
class SetInfo:
def __init__(self, set, rarity, image):
self.set = set
self.rarity = rarity
self.image = image
class Card:
def __init__(self, name, cleanName):
self.name = name
self.cleanName = cleanName
self.hasSet = False
self.sets = {}
def clean(name):
return name.replace(' ','_').replace('\'','').replace('-','_').replace('"','').replace(',','').lower()
def getCardsInSet():
html = urlopen('http://magiccards.info/query?q=e:'+setAbbr+'&v=olist').read()
start = html.find('<th><b>Card name</b></th>')
end = html.find('</table>', start)
block = html[start:end]
while True:
nameIndex = block.find('.html">')
if nameIndex == -1:
break
nameEnd = block.find('<',nameIndex)
name = block[nameIndex+7:nameEnd]
# Add name to array
nameList.append(clean(name)+'.txt')
block = block[nameEnd:]
return
folder = "cardsfolder"
err = open('reprintSetInfo.log','w')
# THIS NEEDS TO BE UPDATED TO THE SET YOU WANT TO UPDATE
# SOME ARE THREE LETTER ABBR. BUT SOME ARE JUST TWO. CHECK BEFORE YOU RUN!
print "Using Set: " + sys.argv[1]
setAbbr = sys.argv[1]
cardDict = {}
setStr = 'SetInfo:'
oracleStr = 'Oracle:'
nameList = []
getCardsInSet()
for fileName in nameList:
# Join new folder convention cardsfolder/<char>/<cardName>
filePath = os.path.join(folder, fileName[0].lower(), fileName)
print filePath
# if file doesn't exist continue
if not os.path.isfile(filePath):
continue
file = open(filePath)
cleanName = fileName.replace('.txt', '')
line = file.readline().strip()
# Handle name and creation
name = line.replace('Name:','')
card = Card(name, cleanName)
cardDict[cleanName] = card
card.lines = line + '\n'
# Start parsing the rest of the data file
line = file.readline().strip()
while line != 'End':
# Skip empty lines
if line == '':
line = file.readline().strip()
continue
# We really shouldn
if line == 'End':
break
# Skip SetInfo lines
if line.find(setStr) == -1 and line.find(oracleStr) == -1:
card.lines += line +'\n'
line = file.readline().strip()
file = open(filePath, 'w')
file.write(card.lines)
file.write('End')
file.close()
err.write(card.name + '... Updated\n')
err.close()

View File

@@ -1,267 +0,0 @@
#!/usr/bin/env python
# This python script is designed to handle the following: individual cards located in /res/cardsfolder
# Insert of SetInfo data into data files from magiccards.info
from httplib import HTTP
from urlparse import urlparse
from urllib import urlopen
import os,fnmatch
def getURL(url):
return urlopen(url).read()
class SetInfo:
def __init__(self, set, rarity, image):
self.set = set
self.rarity = rarity
self.image = image
class Card:
def __init__(self, name, cleanName):
self.name = name
self.cleanName = cleanName
self.hasSet = False
self.sets = {}
def initSets():
# Base Sets
allSets['Limited Edition Alpha'] = 'LEA'
allSets['Limited Edition Beta'] = 'LEB'
allSets['Unlimited Edition'] = '2ED'
allSets['Revised Edition'] = '3ED'
allSets['Fourth Edition'] = '4ED'
allSets['Fifth Edition'] = '5ED'
allSets['Classic Sixth Edition'] = '6ED'
allSets['Seventh Edition'] = '7ED'
allSets['Eighth Edition'] = '8ED'
allSets['Ninth Edition'] = '9ED'
allSets['Tenth Edition'] = '10E'
allSets['Magic 2010'] = 'M10'
allSets['Magic 2011'] = 'M11'
allSets['Magic 2012'] = 'M12'
allSets['Magic 2013'] = 'M13'
# Multiplayer Sets
allSets['Commander'] = 'COM'
allSets['Planechase 2012 Edition'] = 'PC2'
# Portal
allSets['Portal'] = 'POR'
allSets['Portal Second Age'] = 'PO2'
allSets['Portal Three Kingdoms'] = 'PTK'
# Starter
allSets['Starter 1999'] = 'S99'
allSets['Starter 2000'] = 'S00'
# Early Sets
allSets['Arabian Nights'] = 'ARN'
allSets['Antiquities'] = 'ATQ'
allSets['Legends'] = 'LEG'
allSets['The Dark'] = 'DRK'
allSets['Fallen Empires'] = 'FEM'
allSets['Homelands'] = 'HML'
allSets['Chronicles'] = 'CHR'
# Ice Age
allSets['Ice Age'] = 'ICE'
allSets['Alliances'] = 'ALL'
allSets['Coldsnap'] = 'CSP'
# Mirage
allSets['Mirage'] = 'MIR'
allSets['Visions'] = 'VIS'
allSets['Weatherlight'] = 'WTH'
# Rath Cycle
allSets['Tempest'] = 'TMP'
allSets['Stronghold'] = 'STH'
allSets['Exodus'] = 'EXO'
# Artifacts Cycle
allSets['Urza\'s Saga'] = 'USG'
allSets['Urza\'s Legacy'] = 'ULG'
allSets['Urza\'s Destiny'] = 'UDS'
# Masques
allSets['Mercadian Masques'] = 'MMQ'
allSets['Nemesis'] = 'NMS'
allSets['Prophecy'] = 'PCY'
# Invasion
allSets['Invasion'] = 'INV'
allSets['Planeshift'] = 'PLS'
allSets['Apocalypse'] = 'APC'
# Odyssey
allSets['Odyssey'] = 'ODY'
allSets['Torment'] = 'TOR'
allSets['Judgment'] = 'JUD'
# Onslaught
allSets['Onslaught'] = 'ONS'
allSets['Legions'] = 'LGN'
allSets['Scourge'] = 'SCG'
# Mirrodin
allSets['Mirrodin'] = 'MRD'
allSets['Darksteel'] = 'DST'
allSets['Fifth Dawn'] = '5DN'
# Kamigawa
allSets['Champions of Kamigawa'] = 'CHK'
allSets['Betrayers of Kamigawa'] = 'BOK'
allSets['Saviors of Kamigawa'] = 'SOK'
# Ravnica
allSets['Ravnica: City of Guilds'] = 'RAV'
allSets['Guildpact'] = 'GPT'
allSets['Dissension'] = 'DIS'
# Time Spiral
allSets['Time Spiral'] = 'TSP'
allSets['Time Spiral "Timeshifted"'] = 'TSB'
allSets['Planar Chaos'] = 'PLC'
allSets['Future Sight'] = 'FUT'
# Lorwyn
allSets['Lorwyn'] = 'LRW'
allSets['Morningtide'] = 'MOR'
# Shadowmoor
allSets['Shadowmoor'] = 'SHM'
allSets['Eventide'] = 'EVE'
# Alara
allSets['Shards of Alara'] = 'ALA'
allSets['Conflux'] = 'CFX'
allSets['Alara Reborn'] = 'ARB'
# Zendikar
allSets['Zendikar'] = 'ZEN'
allSets['Worldwake'] = 'WWK'
allSets['Rise of the Eldrazi'] = 'ROE'
# Scars of Mirrodin
allSets['Scars of Mirrodin'] = 'SOM'
allSets['Mirrodin Besieged'] = 'MBS'
allSets['New Phyrexia'] = 'NPH'
# Innistrad
allSets['Innistrad']='ISD'
allSets['Dark Ascension']='DKA'
allSets['Avacyn Restored']='AVR'
# Return to Ravnica
allSets['Return to Ravnica']='RTR'
allSets['Gatecrash']='GTC'
#allSets['Dragon\'s Maze']='DGM'
def addSets(card):
html = getURL('http://magiccards.info/query?q=!'+card.name)
start = html.find('<br><u><b>Editions:</b></u><br>')
end = html.find('<br><u><b>Languages:</b></u><br>', start)
block = html[start:end]
print card.name
for edition in allSets.keys():
edIndex = block.find('>'+edition+'<') # Portal/Mirrodin issue
if edIndex == -1:
edIndex = block.find('>'+edition+' (') # Single set issue
if edIndex == -1:
continue
# Scrape rarity
rarityIndex = block.find('(',edIndex)
rarity = block[rarityIndex+1:block.find(')',rarityIndex)]
raritySpace = rarity.find(' ')
if raritySpace != -1:
rarity = rarity[0:raritySpace] # For older cards
# What to do with TimeShifted cards?
if rarity == 'Special' and edition != 'Time Spiral "Timeshifted"':
continue
# Get setAbbreviation and setNumber
dataIndex = block.rfind('"/',0,edIndex)
data = block[dataIndex+2:edIndex-1] # 1 instead of 2 because of Portal/Mirrodin Issue
splitData = data.split('/')
setAbbr = splitData[0]
setNum = splitData[2].replace('.html', '')
if len(setNum) > 4:
# Setnum not available here for most recent set. Switch to the .jpg used on page
jpgIndex = html.find('.jpg')
data = html[html.rfind('scans/en/', 0, jpgIndex):jpgIndex]
# data = scans/en/[set]/[num]
splitData = data.split('/')
setAbbr = splitData[2]
setNum = splitData[3]
image = 'http://magiccards.info/scans/en/' + setAbbr + '/' + setNum + '.jpg'
card.sets[allSets[edition]] = SetInfo(allSets[edition], rarity, image)
return
#get master card list and drop into a dictionary
folder = "cardsfolder"
err = open('setInfoScript.log','w')
allSets = {}
initSets()
cardDict = {}
setStr = 'SetInfo:'
for root, dirnames, filenames in os.walk(folder):
for fileName in fnmatch.filter(filenames, '*.txt'):
if fileName.startswith('.'):
continue
# parse cardsfolder for Card Lines and Rarity/Picture SVars. Filling in any gaps
file = open(os.path.join(root, fileName))
cleanName = fileName.replace('.txt', '')
line = file.readline().strip()
# Handle name and creation
name = line.replace('Name:','')
card = Card(name.replace(' ','+'), cleanName) #This makes it work on Mac OS X. Will test Windows and FreeBSD when I can.
cardDict[cleanName] = card
card.lines = line + '\n'
# Start parsing the rest of the data file
for line in file.readlines():
line = line.strip()
# Skip empty lines
if line == '':
continue
if line.find(setStr) != -1:
info = line.replace('SetInfo:','')
parts = info.split('|')
card.hasSet = True
card.sets[parts[0]] = SetInfo(parts[0], parts[1], parts[2])
else:
card.lines += line +'\n'
if not card.hasSet:
addSets(card)
card.hasSet = True
file = open(os.path.join(root, fileName), 'w')
file.write(card.lines)
if card.hasSet:
for s in card.sets.values():
file.write('SetInfo:'+ s.set + '|' + s.rarity + '|' + s.image + '\n')
err.write(card.name + '... Updated\n')
file.close()
err.close()

View File

@@ -28,7 +28,18 @@ public class RevealEffect extends RevealEffectBase {
if (handChoices.size() > 0) {
final List<Card> revealed = new ArrayList<Card>();
if (sa.hasParam("Random")) {
revealed.add(Aggregates.random(handChoices));
if (sa.hasParam("NumCards")) {
final int num = AbilityUtils.calculateAmount(host, sa.getParam("NumCards"), sa);
final int revealnum = Math.min(handChoices.size(), num);
final List<Card> hand = new ArrayList<Card>(handChoices);
for (int i = 0; i < revealnum; i++) {
final Card random = Aggregates.random(hand);
revealed.add(random);
hand.remove(random);
}
} else {
revealed.add(Aggregates.random(handChoices));
}
GuiChoose.oneOrNone("Revealed card(s)", revealed);
} else {
List<Card> valid = new ArrayList<Card>(handChoices);
@@ -36,11 +47,11 @@ public class RevealEffect extends RevealEffectBase {
if (sa.hasParam("RevealValid")) {
valid = CardLists.getValidCards(valid, sa.getParam("RevealValid"), p, host);
}
if (sa.hasParam("AnyNumber")) {
if (anyNumber) {
max = valid.size();
}
else if (sa.hasParam("NumCards")) {
max = Math.min(valid.size(), AbilityUtils.calculateAmount(sa.getSourceCard(), sa.getParam("NumCards"), sa));
max = Math.min(valid.size(), AbilityUtils.calculateAmount(host, sa.getParam("NumCards"), sa));
}
//revealed.addAll(getRevealedList(sa.getActivatingPlayer(), valid, max, anyNumber));
revealed.addAll(getRevealedList(p, valid, max, anyNumber));

View File

@@ -69,8 +69,8 @@ public class QuestUtilUnlockSets {
for (CardEdition ed : getUnlockableEditions(qData)) {
int price = UNLOCK_COST;
if (mapPrices.containsKey(ed.getName() + " Booster Pack")) {
price = Math.max(new Double(60 * Math.pow(Math.sqrt(mapPrices.get(ed.getName()
+ " Booster Pack")), 1.65)).intValue(), UNLOCK_COST);
price = Math.max(new Double(30 * Math.pow(Math.sqrt(mapPrices.get(ed.getName()
+ " Booster Pack")), 1.70)).intValue(), UNLOCK_COST);
}
setPrices.add(ImmutablePair.of(ed, price));
}