diff --git a/card_db_src/en_us/sets_en_us.json b/card_db_src/en_us/sets_en_us.json index d0a4c882..d8a44dd4 100644 --- a/card_db_src/en_us/sets_en_us.json +++ b/card_db_src/en_us/sets_en_us.json @@ -14,6 +14,11 @@ "set_text": "There are strange things going on in your basement laboratories. They keep calling up for more barrels of quicksilver, or bits of your hair. Well it's all in the name of progress. They're looking for a way to turn lead into gold, or at least into something better than lead. That lead had just been too good of a bargain to pass up; you didn't think, where will I put all this lead, what am I going to do with this lead anyway. Well that will all be sorted out. They're also looking for a universal solvent. If they manage that one, you will take whatever they use to hold it in and build a castle out of it. A castle that can't be dissolved! Now that's progress.\nThis is the 3rd addition to Dominion.", "text_icon": "A" }, + "alchemy extras": { + "set_name": "Alchemy Extras", + "set_text": "", + "text_icon": "A" + }, "animals": { "set_name": "Animals", "set_text": "Dominion: Animals is a fan created expansion for the card game Dominion. It contains three new kingdom cards: \"Rabbits\", \"Yard dog\", and \"Gray Mustang\".\nSee https://boardgamegeek.com/boardgameexpansion/203184/animals-expansion-mini-fan-expansion-dominion.", @@ -50,12 +55,24 @@ "short_name": "Dominion", "text_icon": "D1" }, + "dominion1stEdition extras": { + "set_name": "Dominion 1st Edition Extras", + "set_text": "", + "short_name": "Dominion Extras", + "text_icon": "D1" + }, "dominion2ndEdition": { "set_name": "Dominion 2nd Edition", "set_text": "You are a monarch, like your parents before you, a ruler of a small pleasant kingdom of rivers and evergreens. Unlike your parents, however, you have hopes and dreams! You want a bigger and more pleasant kingdom, with more rivers and a wider variety of trees. You want a Dominion! In all directions lie fiefs, freeholds, and feodums. All are small bits of land, controlled by petty lords and verging on anarchy. You will bring civilization to these people, uniting them under your banner.\nBut wait! It must be something in the air; several other monarchs have had the exact same idea. You must race to get as much of the unclaimed land as possible, fending them off along the way. To do this you will hire minions, construct buildings, spruce up your castle, and fill the coffers of your treasury. Your parents wouldn't be proud, but your grandparents, on your mother's side, would be delighted.", "short_name": "Dominion", "text_icon": "D2" }, + "dominion2ndEdition extras": { + "set_name": "Dominion 2nd Edition Extras", + "set_text": "", + "short_name": "Dominion Extras", + "text_icon": "D2" + }, "dominion2ndEditionUpgrade": { "set_name": "Dominion 2nd Edition Upgrade", "set_text": "This contains the seven new kingdom cards introduced in the second edition of Dominion, thereby allowing owners of the first edition to obtain these new cards without needing to repurchase the entire game.", @@ -93,6 +110,12 @@ "short_name": "Intrigue", "text_icon": "I1" }, + "intrigue1stEdition extras": { + "set_name": "Intrigue 1st Edition Extras", + "set_text": "", + "short_name": "Intrigue Extras", + "text_icon": "I1" + }, "intrigue2ndEdition": { "set_name": "Intrigue 2nd Edition", "set_text": "Something's afoot. The steward smiles at you like he has a secret, or like he thinks you have a secret, or like you think he thinks you have a secret. There are secret plots brewing, you're sure of it. At the very least, there are yours. A passing servant murmurs, \"The eggs are on the plate.\" You frantically search your codebook for the translation before realizing he means that breakfast is ready. Excellent. Everything is going according to plan.\nDominion: Intrigue (Second Edition), an expansion for Dominion or Dominion (Second Edition), contains 26 Kingdom card types that can be used with the base game, while also adding rules for playing with up to eight players at two tables or for playing a single game with up to six players.\nDominion: Intrigue (Second Edition) replaces six Kingdom card types from the first edition with six new types of Kingdom cards, while also replacing the blank cards in that item with a seventh new Kingdom card; these new cards are also available on their own in the Dominion: Intrigue Update Pack. In addition, the rulebook has been rewritten, one card has had a mild functional change (Masquerade skips players with no cards in hand), and other cards have received updated wording while remaining functionally the same.", @@ -136,11 +159,21 @@ "set_text": "Ah, money. There's nothing like the sound of coins clinking in your hands. You vastly prefer it to the sound of coins clinking in someone else's hands, or the sound of coins just sitting there in a pile that no-one can quite reach without getting up. Getting up, that's all behind you now. Life has been good to you. Just ten years ago, you were tilling your own fields in a simple straw hat. Today, your kingdom stretches from sea to sea, and your straw hat is the largest the world has ever known. You also have the world's smallest dog, and a life-size statue of yourself made out of baklava. Sure, money can't buy happiness, but it can buy envy, anger, and also this kind of blank feeling. You still have problems - troublesome neighbors that must be conquered. But this time, you'll conquer them in style.\nThis is the 4th addition to the game of Dominion. It adds 25 new Kingdom cards to Dominion, plus 2 new Basic cards that let players keep building up past Gold and Province. The central theme is wealth; there are treasures with abilities, cards that interact with treasures, and powerful expensive cards.", "text_icon": "P" }, + "prosperity extras": { + "set_name": "Prosperity Extras", + "set_text": "", + "text_icon": "P" + }, "renaissance": { "set_name": "Renaissance", "set_text": "It's a momentous time. Art has been revolutionized by the invention of \"perspective,\" and also of \"funding.\" A picture used to be worth a dozen or so words; these new ones are more like a hundred. Oil paintings have gotten so realistic that you've hired an artist to do a portrait of you each morning, so you can make sure your hair is good. Busts have gotten better too; no more stopping at the shoulders, they go all the way to the ground. Science and medicine have advanced; there's no more superstition, now they know the perfect number of leeches to apply for each ailment. You have a clock accurate to within an hour, and a calendar accurate to within a week. Your physician heals himself, and your barber cuts his own hair. This is truly a golden age.\nThis is the 12th expansion to Dominion. It has 300 cards, with 25 new Kingdom cards. There are tokens that let you save coins and actions for later, Projects that grant abilities, and Artifacts to fight over.", "text_icon": "R" }, + "renaissance extras": { + "set_name": "Renaissance Extras", + "set_text": "", + "text_icon": "R" + }, "seaside": { "set_name": "Seaside", "set_text": "All you ask is a tall ship and a star to steer her by. And someone who knows how to steer ships using stars. You finally got some of those rivers you'd wanted, and they led to the sea. These are dangerous, pirate-infested waters, and you cautiously send rat-infested ships across them, to establish lucrative trade at far-off merchant-infested ports. First, you will take over some islands, as a foothold. The natives seem friendly enough, crying their peace cries, and giving you spears and poison darts before you are even close enough to accept them properly. When you finally reach those ports you will conquer them, and from there you will look for more rivers. One day, all the rivers will be yours.\nThis is the 2nd addition to Dominion. It adds 26 new Kingdom cards to Dominion. Its central theme is your next turn; there are cards that do something this turn and next, cards that set up your next turn, and other ways to step outside of the bounds of a normal turn.", diff --git a/card_db_src/sets_db.json b/card_db_src/sets_db.json index a39e20fd..62cf65a2 100644 --- a/card_db_src/sets_db.json +++ b/card_db_src/sets_db.json @@ -9,17 +9,6 @@ "set_text": "", "text_icon": "*" }, - "adventures extras": { - "edition": [ - "1", - "latest" - ], - "image": "adventures_set.png", - "no_randomizer": true, - "set_name": "*adventures extras*", - "set_text": "", - "text_icon": "*" - }, "alchemy": { "edition": [ "1", @@ -49,6 +38,7 @@ ], "image": "", "no_randomizer": true, + "has_extras": false, "set_name": "*base*", "set_text": "", "text_icon": "*" @@ -63,17 +53,6 @@ "set_text": "", "text_icon": "*" }, - "cornucopia extras": { - "edition": [ - "1", - "latest" - ], - "image": "cornucopia_set.png", - "no_randomizer": true, - "set_name": "*cornucopia extras*", - "set_text": "", - "text_icon": "*" - }, "dark ages": { "edition": [ "1", @@ -84,17 +63,6 @@ "set_text": "", "text_icon": "*" }, - "dark ages extras": { - "edition": [ - "1", - "latest" - ], - "image": "dark_ages_set.png", - "no_randomizer": true, - "set_name": "*dark ages extras*", - "set_text": "", - "text_icon": "*" - }, "dominion1stEdition": { "edition": [ "1" @@ -121,6 +89,8 @@ "1" ], "image": "dominion2ndEdition_set.png", + "has_extras": false, + "upgrades": "dominion1stEdition", "set_name": "*dominion2ndEditionUpgrade*", "set_text": "", "text_icon": "*" @@ -135,17 +105,6 @@ "set_text": "", "text_icon": "*" }, - "empires extras": { - "edition": [ - "1", - "latest" - ], - "image": "empires_set.png", - "no_randomizer": true, - "set_name": "*empires extras*", - "set_text": "", - "text_icon": "*" - }, "extras": { "edition": [ "1", @@ -153,6 +112,7 @@ ], "image": "", "no_randomizer": true, + "has_extras": false, "set_name": "*extras*", "set_text": "", "text_icon": "*" @@ -203,6 +163,8 @@ "1" ], "image": "intrigue2ndEdition_set.png", + "has_extras": false, + "upgrades": "intrigue1stEdition", "set_name": "*intrigue2ndEditionUpgrade*", "set_text": "", "text_icon": "*" @@ -217,17 +179,6 @@ "set_text": "", "text_icon": "*" }, - "menagerie extras": { - "edition": [ - "1", - "latest" - ], - "image": "menagerie_set.png", - "no_randomizer": true, - "set_name": "*menagerie extras*", - "set_text": "", - "text_icon": "*" - }, "nocturne": { "edition": [ "1", @@ -238,23 +189,13 @@ "set_text": "", "text_icon": "*" }, - "nocturne extras": { - "edition": [ - "1", - "latest" - ], - "image": "nocturne_set.png", - "no_randomizer": true, - "set_name": "*nocturne extras*", - "set_text": "", - "text_icon": "*" - }, "promo": { "edition": [ "1", "latest" ], "image": "promo_set.png", + "has_extras": false, "set_name": "*promo*", "set_text": "", "text_icon": "*" diff --git a/card_db_src/types_db.json b/card_db_src/types_db.json index 4d22cf7e..9daa995e 100644 --- a/card_db_src/types_db.json +++ b/card_db_src/types_db.json @@ -320,6 +320,8 @@ "Event" ], "card_type_image": "event.png", + "group_cost": "*", + "group_global_type": "Events", "defaultCardCount": 1, "tabCostHeightOffset": -1, "tabTextHeightOffset": 0 @@ -329,6 +331,7 @@ "Events" ], "card_type_image": "event.png", + "group_cost": "*", "defaultCardCount": 0, "tabCostHeightOffset": -1, "tabTextHeightOffset": 0 @@ -356,6 +359,8 @@ "Landmark" ], "card_type_image": "landmark.png", + "group_cost": "", + "group_global_type": "Landmarks", "defaultCardCount": 1, "tabCostHeightOffset": -1, "tabTextHeightOffset": 0 @@ -365,6 +370,7 @@ "Landmarks" ], "card_type_image": "landmark.png", + "group_cost": "", "defaultCardCount": 0, "tabCostHeightOffset": -1, "tabTextHeightOffset": 0 @@ -444,6 +450,8 @@ "Project" ], "card_type_image": "project.png", + "group_cost": "*", + "group_global_type": "Projects", "defaultCardCount": 1, "tabCostHeightOffset": -1, "tabTextHeightOffset": 0 @@ -453,6 +461,7 @@ "Projects" ], "card_type_image": "project.png", + "group_cost": "*", "defaultCardCount": 0, "tabCostHeightOffset": -1, "tabTextHeightOffset": 0 @@ -647,6 +656,8 @@ "Way" ], "card_type_image": "way.png", + "group_cost": "", + "group_global_type": "Ways", "defaultCardCount": 1, "tabCostHeightOffset": -1, "tabTextHeightOffset": 0 @@ -656,6 +667,7 @@ "Ways" ], "card_type_image": "way.png", + "group_cost": "", "defaultCardCount": 0, "tabCostHeightOffset": -1, "tabTextHeightOffset": 0 diff --git a/src/domdiv/card_db/cz/sets_cz.json b/src/domdiv/card_db/cz/sets_cz.json index b19d73c4..24aa544d 100644 --- a/src/domdiv/card_db/cz/sets_cz.json +++ b/src/domdiv/card_db/cz/sets_cz.json @@ -140,10 +140,5 @@ "set_name": "Menagerie", "text_icon": "M", "set_text": "Dominion, that’s what you’re trying to achieve. This time with animals! They each have a lesson to teach, whether it’s how to spit really far, or what kind of grass tastes the best. It’s a lot to keep track of, but you’re like an elephant: you remember everything. And you’re afraid of mice. You’ve taken up riding. Horses are intimidating; they say you can lead a horse to water, but you haven’t managed it. So you’re working your way up, starting with dogs. So far so good; the dog hasn’t bucked you off yet. Your menagerie got off to a poor start, with just a goat, two rats, and the advisor who suggested starting a menagerie. You couldn’t get that fox you wanted, but it was probably bad anyway. Now you’ve got some camels, which are just as useless for sewing as you’d been warned, and a turtle that can hold its breath for longer than anyone can stay interested. Soon the animal kingdom will be yours.\nThis is the 13th expansion to Dominion. It has 400 cards, with 30 new Kingdom cards. There are Horses that save a draw for later, Exile mats that cards can be sent to and rescued from, and Ways that give Actions another option. Events return." - }, - "menagerie extras": { - "set_name": "Menagerie Extras", - "text_icon": "M", - "set_text": "" } } diff --git a/src/domdiv/card_db/de/sets_de.json b/src/domdiv/card_db/de/sets_de.json index 295ee9e3..1f9bf7a0 100644 --- a/src/domdiv/card_db/de/sets_de.json +++ b/src/domdiv/card_db/de/sets_de.json @@ -140,10 +140,5 @@ "set_name": "Menagerie", "text_icon": "M", "set_text": "Dominion, that’s what you’re trying to achieve. This time with animals! They each have a lesson to teach, whether it’s how to spit really far, or what kind of grass tastes the best. It’s a lot to keep track of, but you’re like an elephant: you remember everything. And you’re afraid of mice. You’ve taken up riding. Horses are intimidating; they say you can lead a horse to water, but you haven’t managed it. So you’re working your way up, starting with dogs. So far so good; the dog hasn’t bucked you off yet. Your menagerie got off to a poor start, with just a goat, two rats, and the advisor who suggested starting a menagerie. You couldn’t get that fox you wanted, but it was probably bad anyway. Now you’ve got some camels, which are just as useless for sewing as you’d been warned, and a turtle that can hold its breath for longer than anyone can stay interested. Soon the animal kingdom will be yours.\nThis is the 13th expansion to Dominion. It has 400 cards, with 30 new Kingdom cards. There are Horses that save a draw for later, Exile mats that cards can be sent to and rescued from, and Ways that give Actions another option. Events return." - }, - "menagerie extras": { - "set_name": "Menagerie Extras", - "text_icon": "M", - "set_text": "" } } diff --git a/src/domdiv/card_db/en_us/sets_en_us.json b/src/domdiv/card_db/en_us/sets_en_us.json index d0a4c882..d8a44dd4 100644 --- a/src/domdiv/card_db/en_us/sets_en_us.json +++ b/src/domdiv/card_db/en_us/sets_en_us.json @@ -14,6 +14,11 @@ "set_text": "There are strange things going on in your basement laboratories. They keep calling up for more barrels of quicksilver, or bits of your hair. Well it's all in the name of progress. They're looking for a way to turn lead into gold, or at least into something better than lead. That lead had just been too good of a bargain to pass up; you didn't think, where will I put all this lead, what am I going to do with this lead anyway. Well that will all be sorted out. They're also looking for a universal solvent. If they manage that one, you will take whatever they use to hold it in and build a castle out of it. A castle that can't be dissolved! Now that's progress.\nThis is the 3rd addition to Dominion.", "text_icon": "A" }, + "alchemy extras": { + "set_name": "Alchemy Extras", + "set_text": "", + "text_icon": "A" + }, "animals": { "set_name": "Animals", "set_text": "Dominion: Animals is a fan created expansion for the card game Dominion. It contains three new kingdom cards: \"Rabbits\", \"Yard dog\", and \"Gray Mustang\".\nSee https://boardgamegeek.com/boardgameexpansion/203184/animals-expansion-mini-fan-expansion-dominion.", @@ -50,12 +55,24 @@ "short_name": "Dominion", "text_icon": "D1" }, + "dominion1stEdition extras": { + "set_name": "Dominion 1st Edition Extras", + "set_text": "", + "short_name": "Dominion Extras", + "text_icon": "D1" + }, "dominion2ndEdition": { "set_name": "Dominion 2nd Edition", "set_text": "You are a monarch, like your parents before you, a ruler of a small pleasant kingdom of rivers and evergreens. Unlike your parents, however, you have hopes and dreams! You want a bigger and more pleasant kingdom, with more rivers and a wider variety of trees. You want a Dominion! In all directions lie fiefs, freeholds, and feodums. All are small bits of land, controlled by petty lords and verging on anarchy. You will bring civilization to these people, uniting them under your banner.\nBut wait! It must be something in the air; several other monarchs have had the exact same idea. You must race to get as much of the unclaimed land as possible, fending them off along the way. To do this you will hire minions, construct buildings, spruce up your castle, and fill the coffers of your treasury. Your parents wouldn't be proud, but your grandparents, on your mother's side, would be delighted.", "short_name": "Dominion", "text_icon": "D2" }, + "dominion2ndEdition extras": { + "set_name": "Dominion 2nd Edition Extras", + "set_text": "", + "short_name": "Dominion Extras", + "text_icon": "D2" + }, "dominion2ndEditionUpgrade": { "set_name": "Dominion 2nd Edition Upgrade", "set_text": "This contains the seven new kingdom cards introduced in the second edition of Dominion, thereby allowing owners of the first edition to obtain these new cards without needing to repurchase the entire game.", @@ -93,6 +110,12 @@ "short_name": "Intrigue", "text_icon": "I1" }, + "intrigue1stEdition extras": { + "set_name": "Intrigue 1st Edition Extras", + "set_text": "", + "short_name": "Intrigue Extras", + "text_icon": "I1" + }, "intrigue2ndEdition": { "set_name": "Intrigue 2nd Edition", "set_text": "Something's afoot. The steward smiles at you like he has a secret, or like he thinks you have a secret, or like you think he thinks you have a secret. There are secret plots brewing, you're sure of it. At the very least, there are yours. A passing servant murmurs, \"The eggs are on the plate.\" You frantically search your codebook for the translation before realizing he means that breakfast is ready. Excellent. Everything is going according to plan.\nDominion: Intrigue (Second Edition), an expansion for Dominion or Dominion (Second Edition), contains 26 Kingdom card types that can be used with the base game, while also adding rules for playing with up to eight players at two tables or for playing a single game with up to six players.\nDominion: Intrigue (Second Edition) replaces six Kingdom card types from the first edition with six new types of Kingdom cards, while also replacing the blank cards in that item with a seventh new Kingdom card; these new cards are also available on their own in the Dominion: Intrigue Update Pack. In addition, the rulebook has been rewritten, one card has had a mild functional change (Masquerade skips players with no cards in hand), and other cards have received updated wording while remaining functionally the same.", @@ -136,11 +159,21 @@ "set_text": "Ah, money. There's nothing like the sound of coins clinking in your hands. You vastly prefer it to the sound of coins clinking in someone else's hands, or the sound of coins just sitting there in a pile that no-one can quite reach without getting up. Getting up, that's all behind you now. Life has been good to you. Just ten years ago, you were tilling your own fields in a simple straw hat. Today, your kingdom stretches from sea to sea, and your straw hat is the largest the world has ever known. You also have the world's smallest dog, and a life-size statue of yourself made out of baklava. Sure, money can't buy happiness, but it can buy envy, anger, and also this kind of blank feeling. You still have problems - troublesome neighbors that must be conquered. But this time, you'll conquer them in style.\nThis is the 4th addition to the game of Dominion. It adds 25 new Kingdom cards to Dominion, plus 2 new Basic cards that let players keep building up past Gold and Province. The central theme is wealth; there are treasures with abilities, cards that interact with treasures, and powerful expensive cards.", "text_icon": "P" }, + "prosperity extras": { + "set_name": "Prosperity Extras", + "set_text": "", + "text_icon": "P" + }, "renaissance": { "set_name": "Renaissance", "set_text": "It's a momentous time. Art has been revolutionized by the invention of \"perspective,\" and also of \"funding.\" A picture used to be worth a dozen or so words; these new ones are more like a hundred. Oil paintings have gotten so realistic that you've hired an artist to do a portrait of you each morning, so you can make sure your hair is good. Busts have gotten better too; no more stopping at the shoulders, they go all the way to the ground. Science and medicine have advanced; there's no more superstition, now they know the perfect number of leeches to apply for each ailment. You have a clock accurate to within an hour, and a calendar accurate to within a week. Your physician heals himself, and your barber cuts his own hair. This is truly a golden age.\nThis is the 12th expansion to Dominion. It has 300 cards, with 25 new Kingdom cards. There are tokens that let you save coins and actions for later, Projects that grant abilities, and Artifacts to fight over.", "text_icon": "R" }, + "renaissance extras": { + "set_name": "Renaissance Extras", + "set_text": "", + "text_icon": "R" + }, "seaside": { "set_name": "Seaside", "set_text": "All you ask is a tall ship and a star to steer her by. And someone who knows how to steer ships using stars. You finally got some of those rivers you'd wanted, and they led to the sea. These are dangerous, pirate-infested waters, and you cautiously send rat-infested ships across them, to establish lucrative trade at far-off merchant-infested ports. First, you will take over some islands, as a foothold. The natives seem friendly enough, crying their peace cries, and giving you spears and poison darts before you are even close enough to accept them properly. When you finally reach those ports you will conquer them, and from there you will look for more rivers. One day, all the rivers will be yours.\nThis is the 2nd addition to Dominion. It adds 26 new Kingdom cards to Dominion. Its central theme is your next turn; there are cards that do something this turn and next, cards that set up your next turn, and other ways to step outside of the bounds of a normal turn.", diff --git a/src/domdiv/card_db/fr/sets_fr.json b/src/domdiv/card_db/fr/sets_fr.json index 1362e97a..f53fa15b 100644 --- a/src/domdiv/card_db/fr/sets_fr.json +++ b/src/domdiv/card_db/fr/sets_fr.json @@ -140,10 +140,5 @@ "set_name": "Menagerie", "text_icon": "M", "set_text": "Dominion, that’s what you’re trying to achieve. This time with animals! They each have a lesson to teach, whether it’s how to spit really far, or what kind of grass tastes the best. It’s a lot to keep track of, but you’re like an elephant: you remember everything. And you’re afraid of mice. You’ve taken up riding. Horses are intimidating; they say you can lead a horse to water, but you haven’t managed it. So you’re working your way up, starting with dogs. So far so good; the dog hasn’t bucked you off yet. Your menagerie got off to a poor start, with just a goat, two rats, and the advisor who suggested starting a menagerie. You couldn’t get that fox you wanted, but it was probably bad anyway. Now you’ve got some camels, which are just as useless for sewing as you’d been warned, and a turtle that can hold its breath for longer than anyone can stay interested. Soon the animal kingdom will be yours.\nThis is the 13th expansion to Dominion. It has 400 cards, with 30 new Kingdom cards. There are Horses that save a draw for later, Exile mats that cards can be sent to and rescued from, and Ways that give Actions another option. Events return." - }, - "menagerie extras": { - "set_name": "Menagerie Extras", - "text_icon": "M", - "set_text": "" } } diff --git a/src/domdiv/card_db/it/sets_it.json b/src/domdiv/card_db/it/sets_it.json index d3655fe8..f0514ed6 100644 --- a/src/domdiv/card_db/it/sets_it.json +++ b/src/domdiv/card_db/it/sets_it.json @@ -140,10 +140,5 @@ "set_name": "Menagerie", "text_icon": "M", "set_text": "Dominion, that’s what you’re trying to achieve. This time with animals! They each have a lesson to teach, whether it’s how to spit really far, or what kind of grass tastes the best. It’s a lot to keep track of, but you’re like an elephant: you remember everything. And you’re afraid of mice. You’ve taken up riding. Horses are intimidating; they say you can lead a horse to water, but you haven’t managed it. So you’re working your way up, starting with dogs. So far so good; the dog hasn’t bucked you off yet. Your menagerie got off to a poor start, with just a goat, two rats, and the advisor who suggested starting a menagerie. You couldn’t get that fox you wanted, but it was probably bad anyway. Now you’ve got some camels, which are just as useless for sewing as you’d been warned, and a turtle that can hold its breath for longer than anyone can stay interested. Soon the animal kingdom will be yours.\nThis is the 13th expansion to Dominion. It has 400 cards, with 30 new Kingdom cards. There are Horses that save a draw for later, Exile mats that cards can be sent to and rescued from, and Ways that give Actions another option. Events return." - }, - "menagerie extras": { - "set_name": "Menagerie Extras", - "text_icon": "M", - "set_text": "" } } diff --git a/src/domdiv/card_db/nl_du/sets_nl_du.json b/src/domdiv/card_db/nl_du/sets_nl_du.json index ca67f13f..39742dcb 100644 --- a/src/domdiv/card_db/nl_du/sets_nl_du.json +++ b/src/domdiv/card_db/nl_du/sets_nl_du.json @@ -140,10 +140,5 @@ "set_name": "Menagerie", "text_icon": "M", "set_text": "Dominion, that’s what you’re trying to achieve. This time with animals! They each have a lesson to teach, whether it’s how to spit really far, or what kind of grass tastes the best. It’s a lot to keep track of, but you’re like an elephant: you remember everything. And you’re afraid of mice. You’ve taken up riding. Horses are intimidating; they say you can lead a horse to water, but you haven’t managed it. So you’re working your way up, starting with dogs. So far so good; the dog hasn’t bucked you off yet. Your menagerie got off to a poor start, with just a goat, two rats, and the advisor who suggested starting a menagerie. You couldn’t get that fox you wanted, but it was probably bad anyway. Now you’ve got some camels, which are just as useless for sewing as you’d been warned, and a turtle that can hold its breath for longer than anyone can stay interested. Soon the animal kingdom will be yours.\nThis is the 13th expansion to Dominion. It has 400 cards, with 30 new Kingdom cards. There are Horses that save a draw for later, Exile mats that cards can be sent to and rescued from, and Ways that give Actions another option. Events return." - }, - "menagerie extras": { - "set_name": "Menagerie Extras", - "text_icon": "M", - "set_text": "" } } diff --git a/src/domdiv/card_db/sets_db.json b/src/domdiv/card_db/sets_db.json index a39e20fd..62cf65a2 100644 --- a/src/domdiv/card_db/sets_db.json +++ b/src/domdiv/card_db/sets_db.json @@ -9,17 +9,6 @@ "set_text": "", "text_icon": "*" }, - "adventures extras": { - "edition": [ - "1", - "latest" - ], - "image": "adventures_set.png", - "no_randomizer": true, - "set_name": "*adventures extras*", - "set_text": "", - "text_icon": "*" - }, "alchemy": { "edition": [ "1", @@ -49,6 +38,7 @@ ], "image": "", "no_randomizer": true, + "has_extras": false, "set_name": "*base*", "set_text": "", "text_icon": "*" @@ -63,17 +53,6 @@ "set_text": "", "text_icon": "*" }, - "cornucopia extras": { - "edition": [ - "1", - "latest" - ], - "image": "cornucopia_set.png", - "no_randomizer": true, - "set_name": "*cornucopia extras*", - "set_text": "", - "text_icon": "*" - }, "dark ages": { "edition": [ "1", @@ -84,17 +63,6 @@ "set_text": "", "text_icon": "*" }, - "dark ages extras": { - "edition": [ - "1", - "latest" - ], - "image": "dark_ages_set.png", - "no_randomizer": true, - "set_name": "*dark ages extras*", - "set_text": "", - "text_icon": "*" - }, "dominion1stEdition": { "edition": [ "1" @@ -121,6 +89,8 @@ "1" ], "image": "dominion2ndEdition_set.png", + "has_extras": false, + "upgrades": "dominion1stEdition", "set_name": "*dominion2ndEditionUpgrade*", "set_text": "", "text_icon": "*" @@ -135,17 +105,6 @@ "set_text": "", "text_icon": "*" }, - "empires extras": { - "edition": [ - "1", - "latest" - ], - "image": "empires_set.png", - "no_randomizer": true, - "set_name": "*empires extras*", - "set_text": "", - "text_icon": "*" - }, "extras": { "edition": [ "1", @@ -153,6 +112,7 @@ ], "image": "", "no_randomizer": true, + "has_extras": false, "set_name": "*extras*", "set_text": "", "text_icon": "*" @@ -203,6 +163,8 @@ "1" ], "image": "intrigue2ndEdition_set.png", + "has_extras": false, + "upgrades": "intrigue1stEdition", "set_name": "*intrigue2ndEditionUpgrade*", "set_text": "", "text_icon": "*" @@ -217,17 +179,6 @@ "set_text": "", "text_icon": "*" }, - "menagerie extras": { - "edition": [ - "1", - "latest" - ], - "image": "menagerie_set.png", - "no_randomizer": true, - "set_name": "*menagerie extras*", - "set_text": "", - "text_icon": "*" - }, "nocturne": { "edition": [ "1", @@ -238,23 +189,13 @@ "set_text": "", "text_icon": "*" }, - "nocturne extras": { - "edition": [ - "1", - "latest" - ], - "image": "nocturne_set.png", - "no_randomizer": true, - "set_name": "*nocturne extras*", - "set_text": "", - "text_icon": "*" - }, "promo": { "edition": [ "1", "latest" ], "image": "promo_set.png", + "has_extras": false, "set_name": "*promo*", "set_text": "", "text_icon": "*" diff --git a/src/domdiv/card_db/types_db.json b/src/domdiv/card_db/types_db.json index 4d22cf7e..9daa995e 100644 --- a/src/domdiv/card_db/types_db.json +++ b/src/domdiv/card_db/types_db.json @@ -320,6 +320,8 @@ "Event" ], "card_type_image": "event.png", + "group_cost": "*", + "group_global_type": "Events", "defaultCardCount": 1, "tabCostHeightOffset": -1, "tabTextHeightOffset": 0 @@ -329,6 +331,7 @@ "Events" ], "card_type_image": "event.png", + "group_cost": "*", "defaultCardCount": 0, "tabCostHeightOffset": -1, "tabTextHeightOffset": 0 @@ -356,6 +359,8 @@ "Landmark" ], "card_type_image": "landmark.png", + "group_cost": "", + "group_global_type": "Landmarks", "defaultCardCount": 1, "tabCostHeightOffset": -1, "tabTextHeightOffset": 0 @@ -365,6 +370,7 @@ "Landmarks" ], "card_type_image": "landmark.png", + "group_cost": "", "defaultCardCount": 0, "tabCostHeightOffset": -1, "tabTextHeightOffset": 0 @@ -444,6 +450,8 @@ "Project" ], "card_type_image": "project.png", + "group_cost": "*", + "group_global_type": "Projects", "defaultCardCount": 1, "tabCostHeightOffset": -1, "tabTextHeightOffset": 0 @@ -453,6 +461,7 @@ "Projects" ], "card_type_image": "project.png", + "group_cost": "*", "defaultCardCount": 0, "tabCostHeightOffset": -1, "tabTextHeightOffset": 0 @@ -647,6 +656,8 @@ "Way" ], "card_type_image": "way.png", + "group_cost": "", + "group_global_type": "Ways", "defaultCardCount": 1, "tabCostHeightOffset": -1, "tabTextHeightOffset": 0 @@ -656,6 +667,7 @@ "Ways" ], "card_type_image": "way.png", + "group_cost": "", "defaultCardCount": 0, "tabCostHeightOffset": -1, "tabTextHeightOffset": 0 diff --git a/src/domdiv/card_db/xx/sets_xx.json b/src/domdiv/card_db/xx/sets_xx.json index b19d73c4..24aa544d 100644 --- a/src/domdiv/card_db/xx/sets_xx.json +++ b/src/domdiv/card_db/xx/sets_xx.json @@ -140,10 +140,5 @@ "set_name": "Menagerie", "text_icon": "M", "set_text": "Dominion, that’s what you’re trying to achieve. This time with animals! They each have a lesson to teach, whether it’s how to spit really far, or what kind of grass tastes the best. It’s a lot to keep track of, but you’re like an elephant: you remember everything. And you’re afraid of mice. You’ve taken up riding. Horses are intimidating; they say you can lead a horse to water, but you haven’t managed it. So you’re working your way up, starting with dogs. So far so good; the dog hasn’t bucked you off yet. Your menagerie got off to a poor start, with just a goat, two rats, and the advisor who suggested starting a menagerie. You couldn’t get that fox you wanted, but it was probably bad anyway. Now you’ve got some camels, which are just as useless for sewing as you’d been warned, and a turtle that can hold its breath for longer than anyone can stay interested. Soon the animal kingdom will be yours.\nThis is the 13th expansion to Dominion. It has 400 cards, with 30 new Kingdom cards. There are Horses that save a draw for later, Exile mats that cards can be sent to and rescued from, and Ways that give Actions another option. Events return." - }, - "menagerie extras": { - "set_name": "Menagerie Extras", - "text_icon": "M", - "set_text": "" } } diff --git a/src/domdiv/cards.py b/src/domdiv/cards.py index ac748e8b..e8acdd73 100644 --- a/src/domdiv/cards.py +++ b/src/domdiv/cards.py @@ -160,14 +160,20 @@ def isLandmark(self): def isPrize(self): return self.isType("Prize") + def get_GroupGlobalType(self): + return self.getType().getGroupGlobalType() + + def get_GroupCost(self): + return self.getType().getGroupCost() + def get_total_cost(self, c): # Return a tuple that represents the total cost of card c # Hightest cost cards are in order: - # - Landmarks to sort at the very end + # - Types with group cost of "" sort at the very end # - cards with * since that can mean anything # - cards with numeric errors # convert cost (a string) into a number - if c.isLandmark(): + if c.get_GroupCost() == "": c_cost = 999 elif not c.cost: c_cost = 0 # if no cost, treat as 0 @@ -245,12 +251,16 @@ def __init__( self, card_type, card_type_image, + group_global_type=None, + group_cost=None, defaultCardCount=10, tabTextHeightOffset=0, tabCostHeightOffset=-1, ): self.typeNames = tuple(card_type) self.tabImageFile = card_type_image + self.group_global_type = group_global_type + self.group_cost = group_cost self.defaultCardCount = defaultCardCount self.tabTextHeightOffset = tabTextHeightOffset self.tabCostHeightOffset = tabCostHeightOffset @@ -266,6 +276,12 @@ def getTabImageFile(self): return None return self.tabImageFile + def getGroupGlobalType(self): + return self.group_global_type + + def getGroupCost(self): + return self.group_cost + def getTabTextHeightOffset(self): return self.tabTextHeightOffset diff --git a/src/domdiv/draw.py b/src/domdiv/draw.py index 06bfd9d7..e358b9a7 100644 --- a/src/domdiv/draw.py +++ b/src/domdiv/draw.py @@ -1220,7 +1220,7 @@ def drawTab(self, item, wrapper="no", backside=False): if ( not card.isExpansion() and not card.isBlank() - and not card.isLandmark() + and card.get_GroupCost() != "" and not card.isType("Trash") ): if "tab" in self.options.cost: @@ -1646,7 +1646,9 @@ def drawSetNames(self, pageItems, backside=False): sets = [] for item in pageItems: - setTitle = item.card.cardset.title() + setTitle = " ".join( + word.capitalize() for word in item.card.cardset.split() + ) if setTitle not in sets: sets.append(setTitle) diff --git a/src/domdiv/main.py b/src/domdiv/main.py index b3bd9a21..0627f5f3 100644 --- a/src/domdiv/main.py +++ b/src/domdiv/main.py @@ -35,6 +35,9 @@ ORDER_CHOICES = ["expansion", "global", "colour", "cost"] +EXPANSION_GLOBAL_GROUP = "extras" +EXPANSION_EXTRA_POSTFIX = " extras" + LANGUAGE_DEFAULT = ( "en_us" # the primary language used if a language's parts are missing ) @@ -76,8 +79,8 @@ def get_expansions(): fan = [] official = [] for s in set_file: - if "extras" not in s: - # Make sure this are set either True or False + if EXPANSION_EXTRA_POSTFIX not in s: + # Make sure these are set either True or False set_file[s]["fan"] = set_file[s].get("fan", False) if set_file[s]["fan"]: fan.append(s) @@ -91,6 +94,27 @@ def get_expansions(): EXPANSION_CHOICES, FAN_CHOICES = get_expansions() +def get_global_groups(): + type_db_filepath = os.path.join("card_db", "types_db.json") + with get_resource_stream(type_db_filepath) as typefile: + type_file = json.loads(typefile.read().decode("utf-8")) + assert type_file, "Could not load any card types from database" + + group_global_choices = [] + group_global_valid = [] + for t in type_file: + if "group_global_type" in t: + group_global_valid.append("-".join(t["card_type"]).lower()) + group_global_choices.append(t["group_global_type"].lower()) + group_global_valid.extend(group_global_choices) + group_global_valid.sort() + group_global_choices.sort() + return group_global_choices, group_global_valid + + +GROUP_GLOBAL_CHOICES, GROUP_GLOBAL_VALID = get_global_groups() + + def get_types(language="en_us"): # get a list of valid types language = language.lower() @@ -458,11 +482,31 @@ def parse_opts(cmdline_args=None): "If this option is not given, all base cards are placed in their own 'Base' expansion.", ) group_select.add_argument( + "--group-special", "--special-card-groups", action="store_true", + dest="group_special", help="Group cards that generally are used together " "(e.g., Shelters, Tournament and Prizes, Urchin/Mercenary, etc.).", ) + group_select.add_argument( + "--group-kingdom", + action="store_true", + dest="group_kingdom", + help="Group cards that have randomizers into the expansion, " + "and those that don't have randomizers into the expansion's 'Extra' section.", + ) + group_select.add_argument( + "--group-global", + nargs="*", + action="append", + dest="group_global", + help="Group all cards of the specified types across all expansions into one 'Extras' divider. " + "This may be called multiple times. Values are not case sensitive. " + "Choices available include: {}".format( + ", ".join("%s" % x for x in GROUP_GLOBAL_VALID) + ), + ) group_select.add_argument( "--no-trash", action="store_true", @@ -490,22 +534,26 @@ def parse_opts(cmdline_args=None): group_select.add_argument( "--exclude-events", action="store_true", - help="Group all 'Event' cards across all expansions into one divider.", + help="Group all 'Event' cards across all expansions into one divider." + "Same as '--group-global Events'", ) group_select.add_argument( "--exclude-landmarks", action="store_true", - help="Group all 'Landmark' cards across all expansions into one divider.", + help="Group all 'Landmark' cards across all expansions into one divider." + "Same as '--group-global landmarks'", ) group_select.add_argument( "--exclude-projects", action="store_true", - help="Group all 'Project' cards across all expansions into one divider.", + help="Group all 'Project' cards across all expansions into one divider." + "Same as '--group-global projects'", ) group_select.add_argument( "--exclude-ways", action="store_true", - help="Group all 'Way' cards across all expansions into one divider.", + help="Group all 'Way' cards across all expansions into one divider." + "Same as '--group-global ways'", ) group_select.add_argument( "--only-type-any", @@ -886,6 +934,28 @@ def clean_opts(options): set([item.lower() for sublist in options.only_type_all for item in sublist]) ) + if options.group_global is None: + options.group_global = [] + elif not any(options.group_global): + # option given with nothing indicates all possible global groupings + options.group_global = GROUP_GLOBAL_VALID + else: + # options.group_global is a list of lists. Reduce to single lowercase list + options.group_global = [ + item.lower() for sublist in options.group_global for item in sublist + ] + # For backwards compatibility + if options.exclude_events: + options.group_global.append("events") + if options.exclude_landmarks: + options.group_global.append("landmarks") + if options.exclude_projects: + options.group_global.append("projects") + if options.exclude_ways: + options.group_global.append("ways") + # Remove duplicates from the list + options.group_global = list(set(options.group_global)) + if options.tabs_only and options.label_name is None: # default is Avery 8867 options.label_name = "8867" @@ -1097,10 +1167,22 @@ def read_card_data(options): with get_resource_stream(set_db_filepath) as setfile: Card.sets = json.loads(setfile.read().decode("utf-8")) assert Card.sets, "Could not load any sets from database" + new_sets = {} for s in Card.sets: # Make sure these are set either True or False Card.sets[s]["no_randomizer"] = Card.sets[s].get("no_randomizer", False) Card.sets[s]["fan"] = Card.sets[s].get("fan", False) + Card.sets[s]["has_extras"] = Card.sets[s].get("has_extras", True) + Card.sets[s]["upgrades"] = Card.sets[s].get("upgrades", None) + new_sets[s] = Card.sets[s] + # Make an "Extras" set for normal expansions + if Card.sets[s]["has_extras"]: + e = s + EXPANSION_EXTRA_POSTFIX + new_sets[e] = copy.deepcopy(Card.sets[s]) + new_sets[e]["set_name"] = "*" + s + EXPANSION_EXTRA_POSTFIX + "*" + new_sets[e]["no_randomizer"] = True + new_sets[e]["has_extras"] = False + Card.sets = new_sets # Remove the Trash card. Do early before propagating to various sets. if options.no_trash: @@ -1131,9 +1213,9 @@ def read_card_data(options): for x in range(0, options.include_blanks): c = Card( card_tag="Blank", - cardset="extras", - cardset_tag="extras", - cardset_tags=["extras"], + cardset=EXPANSION_GLOBAL_GROUP, + cardset_tag=EXPANSION_GLOBAL_GROUP, + cardset_tags=[EXPANSION_GLOBAL_GROUP], randomizer=False, types=("Blank",), ) @@ -1278,7 +1360,7 @@ def by_cost_sort_key(self, card): return ( card.cardset, int(card.isExpansion()), - card.get_total_cost(card), + str(card.get_total_cost(card)), self.strip_accents(card.name), ) @@ -1419,72 +1501,45 @@ def filter_sort_cards(cards, options): # Combine upgrade cards with their expansion if options.upgrade_with_expansion: for card in cards: - if card.cardset_tag == "dominion2ndEditionUpgrade": - card.cardset_tag = "dominion1stEdition" - options.expansions.append(card.cardset_tag.lower()) - elif card.cardset_tag == "intrigue2ndEditionUpgrade": - card.cardset_tag = "intrigue1stEdition" + if Card.sets[card.cardset_tag]["upgrades"]: + card.cardset_tag = Card.sets[card.cardset_tag]["upgrades"] options.expansions.append(card.cardset_tag.lower()) - # Combine all Events across all expansions - if options.exclude_events: - cards = combine_cards( - cards, - old_card_type="Event", - new_type="Events", - new_card_tag="events", - new_cardset_tag="extras", - ) - if options.expansions: - options.expansions.append("extras") - - # Combine all Landmarks across all expansions - if options.exclude_landmarks: - cards = combine_cards( - cards, - old_card_type="Landmark", - new_type="Landmarks", - new_card_tag="landmarks", - new_cardset_tag="extras", - ) - if options.expansions: - options.expansions.append("extras") - - # Combine all Projects across all expansions - if options.exclude_projects: - cards = combine_cards( - cards, - old_card_type="Project", - new_type="Projects", - new_card_tag="projects", - new_cardset_tag="extras", - ) - if options.expansions: - options.expansions.append("extras") - - # Combine all Ways across all expansions - if options.exclude_ways: - cards = combine_cards( - cards, - old_card_type="Way", - new_type="Ways", - new_card_tag="ways", - new_cardset_tag="extras", - ) + # Combine globally all cards of the given types + # For example, Events, Landmarks, Projects, Ways + if options.group_global: + # First find all possible types to group that match options.group_global + types_to_group = {} + for t in Card.types: + group_global_type = Card.types[t].getGroupGlobalType() + if group_global_type: + theType = "-".join(t) + # Save if either the old or the new type matches the option + # Remember options.global_group is already lowercase + if theType.lower() in options.group_global: + types_to_group[theType] = group_global_type + elif group_global_type.lower() in options.group_global: + types_to_group[theType] = group_global_type + + # Now work through the matching types to group + for t in types_to_group: + cards = combine_cards( + cards, + old_card_type=t, + new_type=types_to_group[t], + new_card_tag=types_to_group[t].lower(), + new_cardset_tag=EXPANSION_GLOBAL_GROUP, + ) if options.expansions: - options.expansions.append("extras") + options.expansions.append(EXPANSION_GLOBAL_GROUP) # Take care of any blank cards if options.include_blanks > 0: if options.expansions: - options.expansions.append("extras") - - # FIX THIS: Combine all Prizes across all expansions - # if options.exclude_prizes: - # cards = combine_cards(cards, 'Prize', 'prizes') + options.expansions.append(EXPANSION_GLOBAL_GROUP) # Group all the special cards together - if options.special_card_groups: + if options.group_special: keep_cards = [] # holds the cards that are to be kept group_cards = {} # holds the cards for each group for card in cards: @@ -1507,10 +1562,8 @@ def filter_sort_cards(cards, options): ) # For now, change the name to the group_tab card.description = error_msg card.extra = error_msg - if card.isType("Event") or card.isType("Project"): - card.cost = "*" - if card.isType("Landmark"): - card.cost = "" + if card.get_GroupCost(): + card.cost = card.get_GroupCost() # now save the card keep_cards.append(card) else: @@ -1531,19 +1584,31 @@ def filter_sort_cards(cards, options): cards = keep_cards - # Now fix up card costs + # Now fix up card costs for groups by Type (Events, Landmarks, etc.) for card in cards: - if card.card_tag in group_cards: - if group_cards[card.group_tag].isType("Event") or group_cards[ + if ( + card.card_tag in group_cards + and group_cards[card.group_tag].get_GroupCost() + ): + group_cards[card.group_tag].cost = group_cards[ card.group_tag - ].isType("Project"): - group_cards[card.group_tag].cost = "*" - group_cards[card.group_tag].debtcost = 0 - group_cards[card.group_tag].potcost = 0 - if group_cards[card.group_tag].isType("Landmark"): - group_cards[card.group_tag].cost = "" - group_cards[card.group_tag].debtcost = 0 - group_cards[card.group_tag].potcost = 0 + ].get_GroupCost() + group_cards[card.group_tag].debtcost = 0 + group_cards[card.group_tag].potcost = 0 + + # Separate Kingdom (with Randomizer) from non-Kingdom cards (without Randomizer) + if options.group_kingdom: + new_cards = [] + new_sets = {} + for card in cards: + if not card.randomizer and Card.sets[card.cardset_tag]["has_extras"]: + card.cardset_tag += EXPANSION_EXTRA_POSTFIX + new_sets[card.cardset_tag] = True + new_cards.append(card) + cards = new_cards + if options.expansions and new_cards: + # Add the new expansion "extras" to the overall expansion list + options.expansions.extend([s for s in new_sets]) # Get the final type names in the requested language Card.type_names = add_type_text(Card.type_names, LANGUAGE_DEFAULT) @@ -1599,7 +1664,9 @@ def filter_sort_cards(cards, options): expanded_expansions.append(e) # Now get the actual sets that are matched above - options.expansions = set([e for e in expanded_expansions]) # Remove duplicates + options.expansions = set( + [e.lower() for e in expanded_expansions] + ) # Remove duplicates knownExpansions = set() for e in options.expansions: for s in Official_sets: @@ -1631,7 +1698,7 @@ def filter_sort_cards(cards, options): expanded_expansions.append(e) # Now get the actual sets that are matched above - options.fan = set([e for e in expanded_expansions]) # Remove duplicates + options.fan = set([e.lower() for e in expanded_expansions]) # Remove duplicates knownExpansions = set() for e in options.fan: for s in Fan_sets: @@ -1641,7 +1708,13 @@ def filter_sort_cards(cards, options): # Give indication if an imput did not match anything unknownExpansions = options.fan - knownExpansions if unknownExpansions: - print("Error - unknown fan expansion(s): %s" % ", ".join(unknownExpansions)) + print( + ( + "Error - unknown expansion(s): {}".format( + ", ".join(unknownExpansions) + ) + ) + ) if options.exclude_expansions: # Expand out any wildcards, matching set key or set name in the given language @@ -1714,7 +1787,10 @@ def filter_sort_cards(cards, options): cardnamesByExpansion = defaultdict(dict) randomizerCountByExpansion = Counter() for c in cards: - if cardSorter.isBaseExpansionCard(c) or c.isBlank(): + if c.isBlank() or ( + cardSorter.isBaseExpansionCard(c) + and not options.base_cards_with_expansion + ): continue if c.randomizer: randomizerCountByExpansion[c.cardset] += 1