From ad22b9bb4dae6d99225b0af4d188ac1e49900ca4 Mon Sep 17 00:00:00 2001 From: Adam Goldsmith Date: Sat, 5 Aug 2017 14:22:44 -0400 Subject: [PATCH] Merge SVG creation and JSON creation means more simple code, but somewhat harder to test --- SotMDeckBuilder.py | 144 +++++++++++++++++++-------------------------- 1 file changed, 62 insertions(+), 82 deletions(-) diff --git a/SotMDeckBuilder.py b/SotMDeckBuilder.py index ae44df2..f8e535f 100755 --- a/SotMDeckBuilder.py +++ b/SotMDeckBuilder.py @@ -63,42 +63,72 @@ def makeSVG(base, properties): "file://" + bundle_dir + "/" + properties["art"]) return tree -def addCardToBase(svg, baseImg, baseX, cardNum): +def makeCardJson(nickname, description, cardID, outJson=None): + card = CARD_JSON_TEMPLATE.copy() + card.update({"Nickname": nickname, + "Description": description, + "CardID": 100 + cardID}) + if outJson is not None: + outJson['ObjectStates'][0]['DeckIDs'].append(100 + cardID) + outJson['ObjectStates'][0]['ContainedObjects'].append(card) + return card + +def makeDoubleSidedCardJson(nickname, descriptionFront, + descriptionBack, cardID, outJson): + cardBack = makeCardJson(nickname, descriptionBack, cardID + 1) + + card = makeCardJson(nickname, descriptionFront, cardID, outJson) + card.update({"States": {"2": cardBack}}) + return card + +def addCardToBase(svg, baseImg, cardsPerRow, cardNum): for e in svg.findall('{http://www.w3.org/2000/svg}g'): e.set("transform", "{} translate({} {})".format( e.get("transform", ""), - str((cardNum % baseX) * CARD_WIDTH), - str(int(cardNum / baseX) * CARD_HEIGHT))) + str((cardNum % cardsPerRow) * CARD_WIDTH), + str(int(cardNum / cardsPerRow) * CARD_HEIGHT))) baseImg.getroot().append(svg.getroot()) -def makeFace(baseImage, baseX, cardNum, deckType, cardFile, card): +def makeFace(outSVG, cardsPerRow, cardNum, deckType, cardFile, card): path = os.path.join(bundle_dir, "images", deckType, cardFile) fig = makeSVG(path, card) - addCardToBase(fig, baseImage, baseX, cardNum) + addCardToBase(fig, outSVG, cardsPerRow, cardNum) -def makeDoubleSidedFace(baseImage, baseX, cardNum, deckType, cardFile, +def makeDoubleSidedFace(outSVG, cardsPerRow, cardNum, deckType, cardFile, cardFront, cardBack): - makeFace(baseImage, baseX, cardNum, deckType, cardFile, cardFront) - makeFace(baseImage, baseX, cardNum + 1, deckType, cardFile, cardBack) + makeFace(outSVG, cardsPerRow, cardNum, deckType, cardFile, cardFront) + makeFace(outSVG, cardsPerRow, cardNum + 1, deckType, cardFile, cardBack) -def makeFaces(deckJson, outfile): - baseX = math.ceil(math.sqrt(len(deckJson['deck']) + len(deckJson['character']) * 2)) - baseImage = etree.ElementTree( - etree.Element('svg', attrib={'width': str(baseX * CARD_WIDTH) + "pt", - 'height': str(baseX * CARD_HEIGHT) + "pt", +def makeCards(deckJson, outfile): + # number of cards in x and y direction + cardsPerRow = math.ceil(math.sqrt(len(deckJson['deck']) + len(deckJson['character']) * 2)) + outSVG = etree.ElementTree( + etree.Element('svg', attrib={'width': str(cardsPerRow * CARD_WIDTH) + "pt", + 'height': str(cardsPerRow * CARD_HEIGHT) + "pt", 'version': "1.2", 'xmlns': "http://www.w3.org/2000/svg"})) deckType = deckJson["type"] + with open(bundle_dir + "/templates/deck.json") as f: + outJson = json.load(f) + outJson['ObjectStates'][0]['CustomDeck']['1'].update( + {"NumWidth": cardsPerRow, + "NumHeight": cardsPerRow, + #"FaceURL": "http://adamgoldsmith.name/public/SotM/" + outfile + ".png", + "FaceURL": "file://" + os.getcwd() + "/" + outfile + ".png", + "BackURL": "http://cloud-3.steamusercontent.com/ugc/156906385556221451/CE2C3AFE1759790CB0B532FFD636D05A99EC91F4/"}) + cardNum = 0 # Make a card for each hero character card if deckType == "hero": for card in deckJson['character']: - makeFace(baseImage, baseX, cardNum, deckType, "charFront.svg", card) + makeDoubleSidedCardJson(card['name'], "Active", + "Incapacitated", cardNum, outJson) + makeFace(outSVG, cardsPerRow, cardNum, deckType, "charFront.svg", card) cardNum += 1 - makeFace(baseImage, baseX, cardNum, deckType, "charBack.svg", card) + makeFace(outSVG, cardsPerRow, cardNum, deckType, "charBack.svg", card) cardNum += 1 # Make a character and instructions card for each villain card @@ -108,88 +138,39 @@ def makeFaces(deckJson, outfile): front["name"] = card["name"] back = card["back"] back["name"] = card["name"] - makeDoubleSidedFace(baseImage, baseX, cardNum, deckType, - "character.svg", front, back) - cardNum += 2 - makeDoubleSidedFace(baseImage, baseX, cardNum, deckType, - "instructions.svg", front, back) - cardNum += 2 - - - # Make a card for each card - for card in deckJson['deck']: - makeFace(baseImage, baseX, cardNum, deckType, "card.svg", card) - cardNum += 1 - - baseImage.write(outfile + ".svg") - command = ["inkscape", "-z", - "-f", outfile + ".svg", - "-w", str(baseX * CARD_WIDTH * 5), - "-e", outfile + ".png"] - print("To regenerate PNG after editing SVG, run:\n " + " ".join(command)) - subprocess.run(command) - return baseX - -def makeCardJson(nickname, description, cardID, outJson=None): - card = CARD_JSON_TEMPLATE.copy() - card.update({"Nickname": nickname, - "Description": description, - "CardID": cardID}) - if outJson is not None: - outJson['ObjectStates'][0]['DeckIDs'].append(cardID) - outJson['ObjectStates'][0]['ContainedObjects'].append(card) - return card - -def makeDoubleSidedCardJson(nickname, descriptionFront, - descriptionBack, cardID, outJson): - cardBack = makeCardJson(nickname, descriptionBack, cardID + 1) - - card = makeCardJson(nickname, descriptionFront, cardID, outJson) - card.update({ "States": {"2": cardBack}}) - return card - -def makeJson(deckJson, imgWidth, outfile): - with open(bundle_dir + "/templates/deck.json") as f: - outJson = json.load(f) - - # number of cards in x and y direction - outJson['ObjectStates'][0]['CustomDeck']['1'].update( - {"NumWidth": imgWidth, - "NumHeight": imgWidth, - #"FaceURL": "http://adam-desktop.dyn.wpi.edu:8000/" + outfile + ".png", - "FaceURL": "file://" + os.getcwd() + "/" + outfile + ".png", - "BackURL": "http://cloud-3.steamusercontent.com/ugc/156906385556221451/CE2C3AFE1759790CB0B532FFD636D05A99EC91F4/"}) - - # decks start at (10 * deck id) - cardNum = 100 - - if deckJson["type"] == "hero": - for card in deckJson['character']: - # character card - makeDoubleSidedCardJson(card['name'], "Active", - "Incapacitated", cardNum, outJson) - cardNum += 2 - - elif deckJson["type"] == "villain": - for card in deckJson['character']: # character card makeDoubleSidedCardJson(card['name'], "Front", "Back", cardNum, outJson) + makeDoubleSidedFace(outSVG, cardsPerRow, cardNum, deckType, + "character.svg", front, back) cardNum += 2 # instructions card makeDoubleSidedCardJson(card['name'] + " instructions", "Front", "Back", cardNum, outJson) + makeDoubleSidedFace(outSVG, cardsPerRow, cardNum, deckType, + "instructions.svg", front, back) cardNum += 2 + # Make a card for each normal card for card in deckJson['deck']: for i in range(0, card.get('count', 1)): - # normal cards makeCardJson(card['name'], card.get('keywords', ""), cardNum, outJson) + makeFace(outSVG, cardsPerRow, cardNum, deckType, "card.svg", card) cardNum += 1 + # write SVG and convert to PNG + outSVG.write(outfile + ".svg") + command = ["inkscape", "-z", + "-f", outfile + ".svg", + "-w", str(cardsPerRow * CARD_WIDTH * 5), + "-e", outfile + ".png"] + print("To regenerate PNG after editing SVG, run:\n " + " ".join(command)) + subprocess.run(command) + + # Write TTS deck json with open(outfile + ".json", "w") as f: json.dump(outJson, f) @@ -205,5 +186,4 @@ if __name__ == '__main__': with open(inputJson) as f: deckJson = json.load(f) - imgWidth = makeFaces(deckJson, outfile) - makeJson(deckJson, imgWidth, outfile) + makeCards(deckJson, outfile)