commit
550c6a4a65
38
.bzrignore
38
.bzrignore
@ -1,38 +0,0 @@
|
||||
dist
|
||||
card_images
|
||||
build
|
||||
sumpfork_dominion_tabs_A4_v1.3.pdf
|
||||
sumpfork_dominion_tabs_A4_v1.4.pdf
|
||||
sumpfork_dominion_tabs_A4_v1.5.pdf
|
||||
sumpfork_dominion_tabs_cornucopia.pdf
|
||||
sumpfork_dominion_tabs_sameside_v1.1.pdf
|
||||
sumpfork_dominion_tabs_sleeved_v1.3.pdf
|
||||
sumpfork_dominion_tabs_sleeved_v1.4.pdf
|
||||
sumpfork_dominion_tabs_sleeved_v1.5.pdf
|
||||
sumpfork_dominion_tabs_v1.0.pdf
|
||||
sumpfork_dominion_tabs_v1.1.pdf
|
||||
sumpfork_dominion_tabs_v1.2.pdf
|
||||
sumpfork_dominion_tabs_v1.3.pdf
|
||||
sumpfork_dominion_tabs_v1.4.pdf
|
||||
sumpfork_dominion_tabs_v1.5.pdf
|
||||
sumpfork_dominion_tabs_vertical_A4_v1.3.pdf
|
||||
sumpfork_dominion_tabs_vertical_A4_v1.5.pdf
|
||||
sumpfork_dominion_tabs_vertical_sameside_v1.1.pdf
|
||||
sumpfork_dominion_tabs_vertical_sleeved_v1.3.pdf
|
||||
sumpfork_dominion_tabs_vertical_sleeved_v1.4.pdf
|
||||
sumpfork_dominion_tabs_vertical_sleeved_v1.5.pdf
|
||||
sumpfork_dominion_tabs_vertical_v1.1.pdf
|
||||
sumpfork_dominion_tabs_vertical_v1.2.pdf
|
||||
sumpfork_dominion_tabs_vertical_v1.3.pdf
|
||||
sumpfork_dominion_tabs_vertical_v1.4.pdf
|
||||
sumpfork_dominion_tabs_vertical_v1.5.pdf
|
||||
fonts
|
||||
old_images
|
||||
sumpfork_dominion_tabs_v1.3.zip
|
||||
sumpfork_dominion_tabs_v1.4.zip
|
||||
sumpfork_dominion_tabs_v1.5.zip
|
||||
dominion_tabs.pdf
|
||||
sumpfork_dominion_tabs_*
|
||||
dominiontabs.egg-info
|
||||
generated
|
||||
.DS_Store
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@ -5,3 +5,4 @@ generated
|
||||
dominiontabs.egg-info
|
||||
build
|
||||
dist
|
||||
*~
|
||||
|
||||
9
.travis.yml
Normal file
9
.travis.yml
Normal file
@ -0,0 +1,9 @@
|
||||
language: python
|
||||
python:
|
||||
- "2.7"
|
||||
# command to install dependencies
|
||||
install:
|
||||
- pip install -U setuptools
|
||||
- pip install .
|
||||
# command to run tests
|
||||
script: nosetests
|
||||
@ -1,7 +1,3 @@
|
||||
include dominion_cards.txt
|
||||
include dominion_card_extras.txt
|
||||
include *.png
|
||||
include card_db/*/*.json
|
||||
include images/*.png
|
||||
exclude card_images/*
|
||||
exclude old_images/*
|
||||
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
# main package
|
||||
|
||||
__version__ = '1.9.1'
|
||||
__version__ = '2.0'
|
||||
|
||||
52
card_db/de/card_groups.json
Normal file
52
card_db/de/card_groups.json
Normal file
@ -0,0 +1,52 @@
|
||||
{
|
||||
"Tournament": {
|
||||
"subcards": [
|
||||
"Bag of Gold",
|
||||
"Diadem",
|
||||
"Followers",
|
||||
"Princess",
|
||||
"Trusty Steed"
|
||||
],
|
||||
"new_name": "Tournament and Prizes"
|
||||
},
|
||||
"Shelters": {
|
||||
"subcards": [
|
||||
"Hovel",
|
||||
"Overgrown Estate",
|
||||
"Necropolis"
|
||||
],
|
||||
"new_name": "Shelters"
|
||||
},
|
||||
"Page": {
|
||||
"subcards": [
|
||||
"Treasure Hunter",
|
||||
"Warrior",
|
||||
"Hero",
|
||||
"Champion"
|
||||
],
|
||||
"new_name": "Page -> Champion"
|
||||
},
|
||||
"Peasant": {
|
||||
"subcards": [
|
||||
"Soldier",
|
||||
"Fugitive",
|
||||
"Disciple",
|
||||
"Teacher"
|
||||
],
|
||||
"new_name": "Peasant -> Teacher"
|
||||
},
|
||||
"Hermit \/ Madman": {
|
||||
"subcards": [
|
||||
"Hermit",
|
||||
"Madman"
|
||||
],
|
||||
"new_name": "Hermit \/ Madman"
|
||||
},
|
||||
"Urchin \/ Mercenary": {
|
||||
"subcards": [
|
||||
"Urchin",
|
||||
"Mercenary"
|
||||
],
|
||||
"new_name": "Urchin \/ Mercenary"
|
||||
}
|
||||
}
|
||||
1903
card_db/de/cards.json
Normal file
1903
card_db/de/cards.json
Normal file
File diff suppressed because it is too large
Load Diff
9
card_db/de/mapping.json
Normal file
9
card_db/de/mapping.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"Blütezeit": "prosperity",
|
||||
"Dominion": "dominion",
|
||||
"Seaside": "seaside",
|
||||
"Die Alchemisten": "alchemy",
|
||||
"Hinterland": "hinterlands",
|
||||
"Intrige": "intrigue",
|
||||
"Reiche Ernte": "cornucopia"
|
||||
}
|
||||
52
card_db/en_us/card_groups.json
Normal file
52
card_db/en_us/card_groups.json
Normal file
@ -0,0 +1,52 @@
|
||||
{
|
||||
"Tournament": {
|
||||
"subcards": [
|
||||
"Bag of Gold",
|
||||
"Diadem",
|
||||
"Followers",
|
||||
"Princess",
|
||||
"Trusty Steed"
|
||||
],
|
||||
"new_name": "Tournament and Prizes"
|
||||
},
|
||||
"Shelters": {
|
||||
"subcards": [
|
||||
"Hovel",
|
||||
"Overgrown Estate",
|
||||
"Necropolis"
|
||||
],
|
||||
"new_name": "Shelters"
|
||||
},
|
||||
"Page": {
|
||||
"subcards": [
|
||||
"Treasure Hunter",
|
||||
"Warrior",
|
||||
"Hero",
|
||||
"Champion"
|
||||
],
|
||||
"new_name": "Page -> Champion"
|
||||
},
|
||||
"Peasant": {
|
||||
"subcards": [
|
||||
"Soldier",
|
||||
"Fugitive",
|
||||
"Disciple",
|
||||
"Teacher"
|
||||
],
|
||||
"new_name": "Peasant -> Teacher"
|
||||
},
|
||||
"Hermit \/ Madman": {
|
||||
"subcards": [
|
||||
"Hermit",
|
||||
"Madman"
|
||||
],
|
||||
"new_name": "Hermit \/ Madman"
|
||||
},
|
||||
"Urchin \/ Mercenary": {
|
||||
"subcards": [
|
||||
"Urchin",
|
||||
"Mercenary"
|
||||
],
|
||||
"new_name": "Urchin \/ Mercenary"
|
||||
}
|
||||
}
|
||||
@ -1,6 +0,0 @@
|
||||
Tournament, Bag of Gold, Diadem, Followers, Princess, Trusty Steed, Tournament and Prizes
|
||||
Shelters, Hovel, Overgrown Estate, Necropolis, Shelters
|
||||
Page, Treasure Hunter, Warrior, Hero, Champion, Page -> Champion
|
||||
Peasant, Soldier, Fugitive, Disciple, Teacher, Peasant -> Teacher
|
||||
Hermit, Madman, Hermit / Madman
|
||||
Urchin, Mercenary, Urchin / Mercenary
|
||||
3534
card_db/en_us/cards.json
Normal file
3534
card_db/en_us/cards.json
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,695 +0,0 @@
|
||||
1 Cellar Dominion Action $2 +1 Action, Discard any number of cards. +1 Card per card discarded.
|
||||
2 Chapel Dominion Action $2 Trash up to 4 cards from your hand.
|
||||
3 Moat Dominion Action - Reaction $2 +2 Cards, When another player plays an Attack card, you may reveal this from your hand. If you do, you are unaffected by that Attack.
|
||||
4 Chancellor Dominion Action $3 +2 Coins, You may immediately put your deck into your discard pile.
|
||||
5 Village Dominion Action $3 +1 Card, +2 Actions.
|
||||
6 Woodcutter Dominion Action $3 +1 Buy, +2 Coins.
|
||||
7 Workshop Dominion Action $3 Gain a card costing up to 4 Coins.
|
||||
8 Bureaucrat Dominion Action - Attack $4 Gain a silver card; put it on top of your deck. Each other player reveals a Victory card from his hand and puts it on his deck (or reveals a hand with no Victory cards).
|
||||
9 Feast Dominion Action $4 Trash this card. Gain a card costing up to 5 Coins.
|
||||
10 Gardens Dominion Victory $4 Variable, Worth 1 <VP> for every 10 cards in your deck (rounded down).
|
||||
11 Militia Dominion Action - Attack $4 +2 Coins, Each other player discards down to 3 cards in his hand.
|
||||
12 Moneylender Dominion Action $4 Trash a Copper from your hand. If you do, +3 Coins.
|
||||
13 Remodel Dominion Action $4 Trash a card from your hand. Gain a card costing up to 2 Coins more than the trashed card.
|
||||
14 Smithy Dominion Action $4 +3 Cards.
|
||||
15 Spy Dominion Action - Attack $4 +1 Card, +1 Action, Each player (including you) reveals the top card of his deck and either discards it or puts it back, your choice.
|
||||
16 Thief Dominion Action - Attack $4 Each other player reveals the top 2 cards of his deck. If they revealed any Treasure cards, they trash one of them that you choose. You may gain any or all of these trashed cards. They discard the other revealed cards.
|
||||
17 Throne Room Dominion Action $4 Choose an Action card in your hand. Play it twice.
|
||||
18 Council Room Dominion Action $5 +4 Cards, +1 Buy, Each other player draws a card.
|
||||
19 Festival Dominion Action $5 +2 Actions, +1 Buy, +2 Coins.
|
||||
20 Laboratory Dominion Action $5 +2 Cards, +1 Action.
|
||||
21 Library Dominion Action $5 Draw until you have 7 cards in hand. You may set aside any Action cards drawn this way, as you draw them; discard the set aside cards after you finish drawing.
|
||||
22 Market Dominion Action $5 +1 Card, +1 Action, +1 Buy, +1 Coin.
|
||||
23 Mine Dominion Action $5 Trash a Treasure card from your hand. Gain a Treasure card costing up to 3 Coins more; put it into your hand.
|
||||
24 Witch Dominion Action - Attack $5 +2 Cards, Each other player gains a Curse card.
|
||||
25 Adventurer Dominion Action $6 Reveal cards from your deck until you reveal 2 Treasure cards. Put those Treasure cards in your hand and discard the other revealed cards.
|
||||
26 Copper Dominion Treasure $0 Worth 1 Coin.
|
||||
27 Silver Dominion Treasure $3 Worth 2 Coins.
|
||||
28 Gold Dominion Treasure $6 Worth 3 Coins.
|
||||
29 Curse Dominion Curse $0 -1 <VP>
|
||||
30 Estate Dominion Victory $2 1 <VP>
|
||||
31 Duchy Dominion Victory $5 3 <VP>
|
||||
32 Province Dominion Victory $8 6 <VP>
|
||||
33 Trash Dominion Action $0 Pile of trash.
|
||||
|
||||
1 Courtyard Intrigue Action $2 +3 Card, Put a card from your hand on top of your deck.
|
||||
2 Pawn Intrigue Action $2 Choose two: +1 Card, +1 Action, +1 Buy, +1 Coin. (The choices must be different.).
|
||||
3 Secret Chamber Intrigue Action - Reaction $2 Discard any number of cards. +1 Coin per card discarded. - When another player plays an Attack card, you may reveal this from your hand. If you do, +2 cards, then put 2 cards from your hand on top of your deck.
|
||||
4 Great Hall Intrigue Action - Victory $3 +1 Card, +1 Action, 1 <VP>
|
||||
5 Masquerade Intrigue Action $3 +2 Card, Each player passes a card in their hand to the player on their left. You may trash a card from your hand.
|
||||
6 Shanty Town Intrigue Action $3 +2 Actions, Reveal your hand. If you have no Action cards in hand, +2 Cards.
|
||||
7 Steward Intrigue Action $3 Choose one: +2 Cards; or +2 Coins; or trash 2 cards from your hand.
|
||||
8 Swindler Intrigue Action - Attack $3 +2 Coins, Each other player trashes the top card of his deck and gains a card with the same cost that you choose.
|
||||
9 Wishing Well Intrigue Action $3 +1 Card, +1 Action, Name a card, then reveal the top card of your deck. If it is the named card, put it in your hand.
|
||||
10 Baron Intrigue Action $4 +1 Buy, You may discard an Estate card. If you do, +4 Coins. Otherwise, gain an Estate card.
|
||||
11 Bridge Intrigue Action $4 +1 Buy, +1 Coin. All cards (including cards in players' hands) cost 1 Coin less this turn, but not less than 0 Coins.
|
||||
12 Conspirator Intrigue Action $4 +2 Coins. If you've played 3 or more Actions this turn (counting this): +1 Card, +1 Action.
|
||||
13 Coppersmith Intrigue Action $4 Copper produces an extra 1 Coin this turn.
|
||||
14 Ironworks Intrigue Action $4 Gain a card costing up to 4 Coins. If it is an... Action card, +1 Action. Treasure card, +1 Coin. Victory card, +1 Card.
|
||||
15 Mining Village Intrigue Action $4 +1 Card, +2 Actions. You may trash this card immediately. If you do, +2 Coins.
|
||||
16 Scout Intrigue Action $4 +1 Action. Reveal the top 4 cards of your deck. Put the revealed Victory cards into your hand. Put the other cards on top of your deck in any order.
|
||||
17 Duke Intrigue Victory $5 Worth 1 <VP> per Duchy you have.
|
||||
18 Minion Intrigue Action - Attack $5 +1 Action, Choose one: +2 Coins; or discard your hand, +4 Cards, and each other player with at least 5 cards in hand discards his hand and draws 4 cards.
|
||||
19 Saboteur Intrigue Action - Attack $5 Each other player reveals cards from the top of his deck until revealing one costing 3 Coins or more. He trashes that card and may gain a card costing at most 2 Coins less than it. He discards the other revealed cards.
|
||||
20 Torturer Intrigue Action - Attack $5 +3 Card, Each other player chooses one: he discards 2 cards; or he gains a Curse card, putting it in his hand.
|
||||
21 Trading Post Intrigue Action $5 Trash 2 cards from your hand. If you do, gain a silver card; put it into your hand.
|
||||
22 Tribute Intrigue Action $5 The player to your left reveals then discards the top 2 cards of his deck. For each differently named card revealed, if it is an... Action Card, +2 Actions; Treasure Card, +2 Coins; Victory Card, +2 Cards.
|
||||
23 Upgrade Intrigue Action $5 +1 Card, +1 Action, Trash a card from your hand. Gain a card costing exactly 1 Coin more than it.
|
||||
24 Harem Intrigue Treasure - Victory $6 Worth 2 Coins, 2 <VP>
|
||||
25 Nobles Intrigue Action - Victory $6 2 <VP>
|
||||
Choose one: +3 Cards, or +2 Actions.
|
||||
26 Copper Intrigue Treasure $0 Worth 1 Coin.
|
||||
27 Silver Intrigue Treasure $3 Worth 2 Coins.
|
||||
28 Gold Intrigue Treasure $6 Worth 3 Coins.
|
||||
29 Curse Intrigue Curse $0 -1 <VP>
|
||||
30 Estate Intrigue Victory $2 1 <VP>
|
||||
31 Duchy Intrigue Victory $5 3 <VP>
|
||||
32 Province Intrigue Victory $8 6 <VP>
|
||||
33 Trash Intrigue Action $0 Pile of trash.
|
||||
|
||||
1 Embargo Seaside Action $2 +2 Coins, Trash this card. Put an Embargo token on top of a Supply pile. - When a player buys a card, he gains a Curse card per Embargo token on that pile.
|
||||
2 Haven Seaside Action - Duration $2 +1 Card, +1 Action, Set aside a card from your hand face down. At the start of your next turn, put it into your hand.
|
||||
3 Lighthouse Seaside Action - Duration $2 +1 Action, Now and at the start of your next turn: +1 Coin. - While this is in play, when another player plays an Attack card, it doesn't affect you.
|
||||
4 Native Village Seaside Action $2 +2 Actions, Choose one: Set aside the top card of your deck face down on your Native Village mat; or put all the cards from your mat into your hand. You may look at the cards on your mat at any time; return them to your deck at the end of the game.
|
||||
5 Pearl Diver Seaside Action $2 +1 Card, +1 Action, Look at the bottom card of your deck. You may put it on top.
|
||||
6 Ambassador Seaside Action - Attack $3 Reveal a card from your hand. Return up to 2 copies of it from your hand to the Supply. Then each other player gains a copy of it.
|
||||
7 Fishing Village Seaside Action - Duration $3 +2 Actions, +1 Coin, At the start of your next turn: +1 Action, +1 Coin.
|
||||
8 Lookout Seaside Action $3 +1 Action, Look at the top 3 cards of your deck. Trash one of them. Discard one of them. Put the other one on top of your deck.
|
||||
9 Smugglers Seaside Action $3 Gain a copy of a card costing up to 6 Coins that the player to your right gained on his last turn.
|
||||
10 Warehouse Seaside Action $3 +3 Card, +1 Action, Discard 3 cards.
|
||||
11 Caravan Seaside Action - Duration $4 +1 Card, +1 Action
|
||||
At the start of your next turn, +1 Card.
|
||||
12 Cutpurse Seaside Action - Attack $4 +2 Coins, Each other player discards a Copper card (or reveals a hand with no Copper).
|
||||
13 Island Seaside Action - Victory $4 Set aside this and another card from your hand. Return them to your deck at the end of the game. 2 VP
|
||||
14 Navigator Seaside Action $4 +2 Coins, Look at the top 5 cards of your deck. Either discard all of them, or put them back on top of your deck in any order.
|
||||
15 Pirate Ship Seaside Action - Attack $4 Choose one: Each other player reveals the top 2 cards of his deck, trashes a revealed Treasure that you choose, discards the rest, and if anyone trashed a Treasure you take a Coin token; or, +1 Coin per Coin token you've taken with Pirate Ships this game.
|
||||
16 Salvager Seaside Action $4 +1 Buy, Trash a card from your hand. +Coins equal to its cost.
|
||||
17 Sea Hag Seaside Action - Attack $4 Each other player discards the top card of his deck, then gains a Curse card, putting it on top of his deck.
|
||||
18 Treasure Map Seaside Action $4 Trash this and another copy of Treasure Map from your hand. If you do trash two Treasure Maps, gain 4 Gold cards, putting them on top of your deck.
|
||||
19 Bazaar Seaside Action $5 +1 Card, +2 Actions, +1 Coin.
|
||||
20 Explorer Seaside Action $5 You may reveal a Province card from your hand. If you do, gain a Gold card, putting it into your hand. Otherwise, gain a Silver card, putting it into your hand.
|
||||
21 Ghost Ship Seaside Action - Attack $5 +2 Card, Each other player with 4 or more cards in hand puts cards from his hand on top of his deck until he has 3 cards in his hand.
|
||||
22 Merchant Ship Seaside Action - Duration $5 Now and at the start of your next turn: +2 Coins.
|
||||
23 Outpost Seaside Action - Duration $5 You only draw 3 cards (instead of 5) in this turn's Clean-up phase. Take an extra turn after this one. This can't cause you to take more than two consecutive turns.
|
||||
24 Tactician Seaside Action - Duration $5 Discard your hand. If you discarded any cards this way, then at the start of your next turn, +5 Cards, +1 Buy, and +1 Action.
|
||||
25 Treasury Seaside Action $5 +1 Card, +1 Action, +1 Coin, When you discard this from play, if you didn't buy a Victory card this turn, you may put this on top of your deck.
|
||||
26 Wharf Seaside Action - Duration $5 Now and at the start of your next turn: +2 Cards, +1 Buy.
|
||||
|
||||
1 Transmute Alchemy Action $0 1P Trash a card from your hand. If it is an...
|
||||
Action card, gain a Duchy
|
||||
Treasure card, gain a Transmute
|
||||
Victory card, gain a Gold
|
||||
2 Vineyard Alchemy Victory $0 1P Worth 1 <VP> for every 3 Action cards in your deck (rounded down).
|
||||
3 Apothecary Alchemy Action $2 1P +1 Card
|
||||
+1 Action
|
||||
Reveal the top 4 cards of your deck. Put the revealed Coppers and Potions into your hand. Put the other cards back on top in any order.
|
||||
4 Herbalist Alchemy Action $2 +1 Buy
|
||||
+1 Coin
|
||||
When you discard this from play, you may put one of your Treasures from play on top of your deck.
|
||||
5 Scrying Pool Alchemy Action - Attack $2 1P +1 Action
|
||||
Each player (including you) reveals the top card of his deck and either discards it or puts it back, your choice. Then reveal cards from the top of your deck until revealing one that isn't an Action.
|
||||
Put all of your revealed cards into your hand.
|
||||
6 University Alchemy Action $2 1P +2 Actions
|
||||
You may gain an Action card costing up to 5 Coins.
|
||||
7 Alchemist Alchemy Action $3 1P +2 Cards
|
||||
+1 Action
|
||||
When you discard this from play, you may put this on top of your deck if you have a Potion in play.
|
||||
8 Familiar Alchemy Action - Attack $3 1P +1 Card
|
||||
+1 Action
|
||||
Each other player gains a curse.
|
||||
9 Philosopher's Stone Alchemy Treasure $3 1P When you play this, count your deck and discard pile.
|
||||
Worth 1 Coin per 5 cards total between them (rounded down).
|
||||
10 Golem Alchemy Action $4 1P Reveal cards from your deck until you reveal 2 Action cards other than Golem Cards.
|
||||
Discard the other cards, then play the Action cards in either order.
|
||||
11 Potion Alchemy Treasure $4 Worth 1 Potion.
|
||||
12 Apprentice Alchemy Action $5 +1 Action
|
||||
Trash a card from your hand.
|
||||
+1 Card per Coin it costs.
|
||||
+2 Cards if it has Potion in its cost.
|
||||
13 Possession Alchemy Action $6 1P The player to your left takes an extra turn after this one, in which you can see all cards he can and make all decisions for him. Any cards he would gain on that turn, you gain instead; any cards of his that are trashed are set aside and returned to his discard pile at end of turn.
|
||||
14 Possession 2/2 Alchemy Action $6 1P -During the Possessed turn, whenever one of that player's cards is trashed, set it aside, and that player puts it into his discard pile at the end of the turn, after Clean-up. This counts as the card being trashed, so, for example, you could trash a Mining Village (from Intrigue) and get the 2 coins. Getting those cards back at end of turn does not count as those cards being gained (so for example, you won't get them). Other players' cards that are trashed during that turn are not returned.
|
||||
-If you make another player play an Attack via Possession, that Attack will hit you like it would normally. If you want to use a Reaction in response to that Attack (such as Secret Chamber from Intrigue), you would be the one revealing the Reaction, not the player being Possessed.
|
||||
-Possession is cumulative; if you play it twice in one turn, there will be two extra turns after this one.
|
||||
-Cards passed with Masquerade (from Intrigue) are not being gained or trashed, and so are passed normally. Cards returned to the Supply with Ambassador (from Seaside) are also not being trashed, and so return to the Supply normally.
|
||||
|
||||
1 Loan Prosperity Treasure $3 Worth 1 Coin.
|
||||
When you play this, reveal cards from your deck until you reveal a Treasure. Discard it or trash it. Discard the other cards.
|
||||
2 Trade Route Prosperity Action $3 +1 Buy
|
||||
+1 Coin per token on the Trade Route mat.
|
||||
Trash a card from your hand.
|
||||
______________________
|
||||
Setup: Put a token on each Victory card Supply pile. When a card is gained from that pile, move the token to the Trade Route mat.
|
||||
3 Watchtower Prosperity Reaction $3 Draw until you have 6 cards in hand.
|
||||
______________________
|
||||
When you gain a card, you may reveal this from your hand. If you do, either trash that card, or put it on top of your deck.
|
||||
4 Bishop Prosperity Action $4 +1 Coin
|
||||
+1 <VP>
|
||||
Trash a card from your hand. +<VP> equal to half its cost in coins, rounded down.
|
||||
Each other player may trash a card from his hand.
|
||||
5 Monument Prosperity Action $4 +2 Coins; +1 <VP>
|
||||
6 Quarry Prosperity Treasure $4 Worth 1 Coin.
|
||||
______________________
|
||||
While this is in play, Action cards cost 2 Coins less, but not less than 0 Coins.
|
||||
7 Talisman Prosperity Treasure $4 Worth 1 Coin.
|
||||
______________________
|
||||
While this is in play, when you buy a card costing 4 Coins or less that is not a Victory card, gain a copy of it.
|
||||
8 Worker's Village Prosperity Action $4 +1 Card
|
||||
+2 Actions
|
||||
+1 Buy
|
||||
9 City Prosperity Action $5 +1 Card
|
||||
+2 Actions
|
||||
If there are one or more empty Supply piles, +1 Card. If there are two or more, +1 Coin and +1 Buy.
|
||||
10 Contraband Prosperity Treasure $5 Worth 3 Coins.
|
||||
+1 Buy
|
||||
When you play this, the player to your left names a card. You can't buy that card this turn.
|
||||
11 Counting House Prosperity Action $5 Look through your discard pile, reveal any number of Copper cards from it, and put them into your hand.
|
||||
12 Mint Prosperity Action $5 You may reveal a Treasure card from your hand. Gain a copy of it.
|
||||
______________________
|
||||
When you buy this, trash all Treasures you have in play.
|
||||
13 Mountebank Prosperity Action - Attack $5 +2 Coins
|
||||
Each other player may discard a Curse. If he doesn't, he gains a Curse and a Copper.
|
||||
14 Rabble Prosperity Action - Attack $5 +3 Cards
|
||||
Each other player reveals the top 3 cards of his deck, discards the revealed Actions and Treasures, and puts the rest back on top in any order he chooses.
|
||||
15 Royal Seal Prosperity Treasure $5 Worth 2 Coins.
|
||||
______________________
|
||||
While this is in play, when you gain a card, you may put that card on top of your deck.
|
||||
16 Vault Prosperity Action $5 +2 Cards
|
||||
Discard any number of cards. +1 Coin per card discarded.
|
||||
Each other player may discard 2 cards. If he does, he draws a card.
|
||||
17 Venture Prosperity Treasure $5 Worth 1 Coin.
|
||||
When you play this, reveal cards from your deck until you reveal a Treasure. Discard the other cards. Play that Treasure.
|
||||
18 Goons Prosperity Action - Attack $6 +1 Buy
|
||||
+2 Coins
|
||||
Each other player discards down to 3 cards in hand.
|
||||
______________________
|
||||
While this is in play, when you buy a card, +1 <VP>.
|
||||
19 Grand Market Prosperity Action $6 +1 Card
|
||||
+1 Action
|
||||
+1 Buy
|
||||
+2 Coins
|
||||
______________________
|
||||
You can't buy this if you have any Copper in play.
|
||||
20 Hoard Prosperity Treasure $6 Worth 2 Coins.
|
||||
______________________
|
||||
While this is in play, when you buy a Victory card, gain a Gold.
|
||||
21 Bank Prosperity Treasure $7 Worth ? Coins.
|
||||
When you play this, it`s worth 1 Coin per Treasure card you have in play (counting this).
|
||||
22 Expand Prosperity Action $7 Trash a card from your hand. Gain a card costing up to 3 Coins more than the trashed card.
|
||||
23 Forge Prosperity Action $7 Trash any number of cards from your hand. Gain a card with cost exactly equal to the total cost in coins of the trashed cards.
|
||||
24 King's Court Prosperity Action $7 You may choose an Action card in your hand. Play it three times.
|
||||
25 Peddler Prosperity Action $8* +1 Card; +1 Action; +2 Coin
|
||||
______________________
|
||||
During your Buy phase, this costs 2 Coins less per Action card you have in play, but not less than 0 Coins.
|
||||
26 Platinum Prosperity Treasure $9 Worth 5 Coins.
|
||||
27 Colony Prosperity Victory $11 10 <VP>.
|
||||
|
||||
1 Black Market Promo Action $3 +2 Coins, Reveal the top 3 cards of the Black Market deck. You may buy one of them immediately. Put the unbought cards on the bottom of the Black Market deck in any order.
|
||||
(Before the game, make a Black Market deck out of one copy of each Kingdom card not in the supply.).
|
||||
2 Envoy Promo Action $4 Reveal the top 5 cards of your deck. The player to your left chooses one for you to discard. Draw the rest.
|
||||
3 Stash Promo Treasure $5 Worth 2 Coins. When you shuffle, you may put this anywhere in your deck.
|
||||
4 Walled Village Promo Action $4 +1 Card
|
||||
+2 Actions
|
||||
At the start of Clean-up, if you have this and no more than one other Action card in play, you may put this on top of your deck.
|
||||
5 Governor Promo Action $5 +1 Action
|
||||
Choose one; you get the version in parentheses: Each player gets +1 (+3) Cards; or each player gains a Silver (Gold); or each player may trash a card from his hand and gain a card costing exactly 1 Coin (2 Coins) more.
|
||||
6 Prince Promo Action $8 You may set this aside. If you do, set aside an Action card from your hand costing up to 4 coins. At the start of each of your turns, play that Action, setting it aside again when you discard it from play. (Stop playing it if you fail to set it aside on a turn you play it).
|
||||
|
||||
1 Copper Base Treasure $0 Worth 1 Coin.
|
||||
2 Silver Base Treasure $3 Worth 2 Coins.
|
||||
3 Gold Base Treasure $6 Worth 3 Coins.
|
||||
4 Platinum Base Treasure $9 Worth 5 Coins.
|
||||
5 Potion Base Treasure $4 Worth 1 Potion.
|
||||
6 Curse Base Curse $0 -1 <VP>
|
||||
7 Estate Base Victory $2 1 <VP>
|
||||
8 Duchy Base Victory $5 3 <VP>
|
||||
9 Province Base Victory $8 6 <VP>
|
||||
10 Colony Base Victory $11 10 <VP>
|
||||
11 Trash Base Action $0 Pile of trash.
|
||||
|
||||
1 Bag of Gold Cornucopia Action - Prize $0* +1 Action
|
||||
Gain a Gold, putting it on top of your deck.
|
||||
(This is not in the Supply.)
|
||||
2 Diadem Cornucopia Treasure - Prize $0* Worth 2 Coins.
|
||||
When you play this, +1 Coins per unused Action you have (Action, not Action card).
|
||||
(This is not in the Supply.)
|
||||
3 Followers Cornucopia Action - Attack - Prize $0* +2 Cards
|
||||
Gain an Estate. Each other player gains a Curse and discards down to 3 cards in hand.
|
||||
(This is not in the Supply.)
|
||||
4 Princess Cornucopia Action - Prize $0* +1 Buy
|
||||
While this is in play, cards cost 2 Coins less, but not less than 0 Coins.
|
||||
(This is not in the Supply.)
|
||||
5 Trusty Steed Cornucopia Action - Prize $0* Choose two: +2 Cards; or +2 Actions; or +2 Coins; or gain 4 Silvers and put your deck into your discard pile.
|
||||
(This is not in the Supply.)
|
||||
6 Hamlet Cornucopia Action $2 +1 Card
|
||||
+1 Action
|
||||
You may discard a card; If you do +1 Action.
|
||||
You may discard a card; If you do +1 Buy
|
||||
7 Fortune Teller Cornucopia Action - Attack $3 +2 Coin
|
||||
Each other player reveals cards from the top of his deck until he reveals a Victory of Curse card. He puts it on top and discards the other revealed cards.
|
||||
8 Menagerie Cornucopia Action $3 +1 Action
|
||||
Reveal your hand.
|
||||
If there are no duplicate cards in it, +3 Cards.
|
||||
Otherwise, +1 Card.
|
||||
9 Farming Village Cornucopia Action $4 +2 Actions
|
||||
Reveal cards from the top of your deck until you reveal an Action or Treasure card. Put that card into your hand and discard the other cards.
|
||||
10 Horse Traders Cornucopia Action - Reaction $4 +1 Buy
|
||||
+3 Coin
|
||||
Discard 2 Cards
|
||||
When another player plays an Attack card, you may set this aside from your hand. If you do, then at the start of your next turn, +1 Card and return this to your hand.
|
||||
11 Remake Cornucopia Action $4 Do this twice: Trash a card from your hand then gain a card costing exactly 1 more than the trashed card.
|
||||
12 Tournament Cornucopia Action $4 +1 Action
|
||||
Each player may reveal a Province from his hand. If you do, discard it and gain a Prize (from the Prize pile) or a Duchy, putting it on top of your deck. If no-one else does, +1 Card +1 Coin.
|
||||
|
||||
Prizes: Bag of Gold, Diadem, Followers, Princess, Trusty Steed
|
||||
13 Young Witch Cornucopia Action - Attack $4 +2 Cards
|
||||
Discard 2 cards. Each other player may reveal a Bane card from his hand.
|
||||
If he doesn’t, he gains a Curse.
|
||||
Setup: Add an extra Kingdom card pile costing 2 or 3 to the Supply. Cards from that pile are Bane cards.
|
||||
14 Harvest Cornucopia Action $5 Reveal the top 4 cards of your deck, then discard them. +1 Coin per differently named card revealed.
|
||||
15 Horn of Plenty Cornucopia Treasure $5 Worth 0 Coins
|
||||
When you play this, gain a card costing up to 1 Coin per differently named card you have in play, counting this. If it’s a Victory card, trash this.
|
||||
16 Hunting Party Cornucopia Action $5 +1 Card
|
||||
+1 Action
|
||||
Reveal your hand. Reveal cards from your deck until you reveal a card that isn’t in a duplicate of one in your hand and discard the rest.
|
||||
17 Jester Cornucopia Action - Attack $5 +2 Coins
|
||||
Each other player discards the top card of his deck. If it’s a Victory card he gains a Curse. Otherwise he gains a copy of the discarded card or you do, your choice.
|
||||
18 Fairgrounds Cornucopia Victory $6 Worth 2 <VP> for every 5 differently named cards in your deck (rounded down)
|
||||
19 Prizes Cornucopia Extras Prize $0* Prizes are never in the supply. They can only be obtained via Tournament.
|
||||
Bag of Gold: +1 Action; Gain a Gold, putting it on top of your deck.
|
||||
Diadem: +2 Coins; When you play this, +1 Coins per unused Action you have.
|
||||
Followers: +2 Cards; Gain an Estate. Each other player gains a Curse and discards down to 3 cards in hand.
|
||||
Princess: +1 Buy; While this is in play, cards cost 2 Coins less, but not less than 0 Coins.
|
||||
Trusty Steed: Choose two: +2 Cards; or +2 Actions; or +2 Coins; or gain 4 Silvers and put your deck into your discard pile.
|
||||
|
||||
1 Crossroads Hinterlands Action $2 Reveal your hand.
|
||||
+1 Card per Victory card revealed. If this is the first time you played a Crossroads this turn, +3 Actions.
|
||||
2 Duchess Hinterlands Action $2 +2 Coins
|
||||
Each player (including you) looks at the top card of his deck, and discards it or puts it back.
|
||||
______________________
|
||||
In games using this, when you gain a Duchy, you may gain a Duchess.
|
||||
3 Fool's Gold Hinterlands Treasure - Reaction $2 If this is the first time you played a Fool's Gold this turn, this is worth 1 coin, otherwise it's worth 4 coins.
|
||||
______________________
|
||||
When another player gains a Province, you may trash this from your hand. If you do, gain a Gold, putting it on your deck.
|
||||
4 Develop Hinterlands Action $3 Trash a card from your hand. Gain a card costing exactly 1 coin more than it and a card costing exactly 1 less than it, in either order, putting them on top of your deck.
|
||||
5 Oasis Hinterlands Action $3 +1 Card
|
||||
+1 Action
|
||||
+1 Coins
|
||||
Discard a card.
|
||||
6 Oracle Hinterlands Action - Attack $3 Each player (including you) reveals the top 2 cards of his deck, and you choose one: either he discards them, or he puts them back on top in an order he chooses.
|
||||
+2 Cards
|
||||
7 Scheme Hinterlands Action $3 +1 Card
|
||||
+1 Action
|
||||
At the start of Clean-up this turn, you may choose an Action card you have in play. If you discard it from play this turn, put it on your deck.
|
||||
8 Tunnel Hinterlands Victory - Reaction $3 2 <VP>
|
||||
______________________
|
||||
When you discard this other than during a Clean-up phase, you may reveal it. If you do, gain a Gold.
|
||||
9 Jack of all Trades Hinterlands Action $4 Gain a Silver.
|
||||
Look at the top card of your deck; discard it or put it back.
|
||||
Draw until you have 5 cards in hand.
|
||||
You may trash a card from your hand that is not a Treasure.
|
||||
10 Noble Brigand Hinterlands Action - Attack $4 +1 Coin
|
||||
When you buy this or play it, each other player reveals the top 2 cards of his deck, trashes a revealed Silver or Gold you choose, and discards the rest. If he didn't reveal a Treasure, he gains a Copper. You gain the trashed cards.
|
||||
11 Nomad Camp Hinterlands Action $4 +1 Buy
|
||||
+2 Coins
|
||||
______________________
|
||||
When you gain this, put it on top of your deck.
|
||||
12 Silk Road Hinterlands Victory $4 Worth 1 <VP> for every 4 Victory cards in your deck (round down).
|
||||
13 Spice Merchant Hinterlands Action $4 You may trash a Treasure from your hand. If you do, choose one:
|
||||
+2 Cards and +1 Action;
|
||||
or +2 Coins and +1 Buy.
|
||||
14 Trader Hinterlands Action - Reaction $4 Trash a card from your hand. Gain a number of Silvers equal to its cost in coins.
|
||||
______________________
|
||||
When you would gain a card, you may reveal this from your hand. If you do, instead, gain a silver.
|
||||
15 Cache Hinterlands Treasure $5 Worth 3 coins
|
||||
______________________
|
||||
When you gain this, gain two Coppers.
|
||||
16 Cartographer Hinterlands Action $5 +1 Card
|
||||
+1 Action
|
||||
Look at the top 4 cards of your deck. Discard any number of them. Put the rest back on top in any order.
|
||||
17 Embassy Hinterlands Action $5 +5 Cards
|
||||
Discard 3 cards.
|
||||
______________________
|
||||
When you gain this, each other player gains a Silver.
|
||||
18 Haggler Hinterlands Action $5 +2 Coins
|
||||
______________________
|
||||
While this is in play, when you buy a card, gain a card costing less than it that is not a Victory card.
|
||||
19 Highway Hinterlands Action $5 +1 Card
|
||||
+1 Action
|
||||
______________________
|
||||
While this is in play, cards cost 1 Coin less, but not less than 0 Coins.
|
||||
20 Ill-Gotten Gains Hinterlands Treasure $5 Worth 1 Coin
|
||||
When you play this, you may gain a Copper, putting it into your hand.
|
||||
______________________
|
||||
When you gain this, each other player gains a Curse.
|
||||
21 Inn Hinterlands Action $5 +2 Cards
|
||||
+2 Actions
|
||||
Discard 2 cards.
|
||||
______________________
|
||||
When you gain this, look through your discard pile (including this), reveal any number of Action cards from it, and shuffle them into your deck.
|
||||
22 Mandarin Hinterlands Action $5 +3 Coins
|
||||
Put a card from your hand on top of your deck.
|
||||
______________________
|
||||
When you gain this, put all Treasures you have in play on top of your deck in any order.
|
||||
23 Margrave Hinterlands Action - Attack $5 +3 Cards
|
||||
+1 Buy
|
||||
Each other player draws a card, then discards down to 3 cards in hand.
|
||||
24 Stables Hinterlands Action $5 You may discard a Treasure. If you do, +3 Cards and +1 Action.
|
||||
25 Border Village Hinterlands Action $6 +1 Card
|
||||
+2 Actions
|
||||
______________________
|
||||
When you gain this, gain a card costing less than this.
|
||||
26 Farmland Hinterlands Victory $6 2 <VP>
|
||||
______________________
|
||||
When you buy this, trash a card from your hand. Gain a card costing exactly 2 Coins more than the trashed card.
|
||||
|
||||
1 Ruins Dark Ages Action - Ruins $0 Abandoned Mine: +1 Coin
|
||||
Ruined Library: +1 Card
|
||||
Ruined Market: +1 Buy
|
||||
Ruined Village: +1 Action
|
||||
Survivors: Look at the top 2 cards of your deck. Discard them or put them back in any order.
|
||||
2 Madman Dark Ages Action $0* +2 Actions
|
||||
Return this to the Madman pile. If you do, +1 Card per card in your hand.
|
||||
(This card is not in the supply.)
|
||||
3 Spoils Dark Ages Treasure $0* Worth 3 Coins
|
||||
When you play this, return it to the Spoils pile.
|
||||
(This is not in the Supply.)
|
||||
4 Hovel Dark Ages Reaction - Shelter $1 When you buy a Victory card, you may trash this from your hand.
|
||||
5 Necropolis Dark Ages Action - Shelter $1 +2 Actions
|
||||
6 Overgrown Estate Dark Ages Victory - Shelter $1 0 <VP>
|
||||
______________________
|
||||
When you trash this, +1 Card.
|
||||
7 Poor House Dark Ages Action $1 +4 Coins
|
||||
Reveal your hand. -1 Coin per Treasure card in your hand, to a minimum of 0 Coins.
|
||||
8 Squire Dark Ages Action $2 +1 Coin
|
||||
Choose one: +2 Actions; or +2 Buys; or gain a Silver.
|
||||
______________________
|
||||
When you trash this, gain an Action card.
|
||||
9 Vagrant Dark Ages Action $2 +1 Card, +1 Action
|
||||
Reveal the top card of your deck. If it's a Curse, Ruins, Shelter, or Victory card, put it into your hand.
|
||||
10 Hermit Dark Ages Action $3 Look through your discard pile. You may trash a card from your discard pile or hand that is not a Treasure. Gain a card costing up to 3 Coins.
|
||||
When you discard this from play, if you did not buy any cards this turn, trash this and gain a Madman from the Madman pile.
|
||||
11 Sage Dark Ages Action $3 +1 Action
|
||||
Reveal cards from the top of your deck until you reveal one costing 3 Coins or more. Put that card into your hand and discard the rest.
|
||||
12 Feodum Dark Ages Victory $4 Worth 1 <VP> for every 3 Silvers in your deck (round down).
|
||||
______________________
|
||||
When you trash this, gain 3 Silvers.
|
||||
13 Fortress Dark Ages Action $4 +1 Card, +2 Actions
|
||||
______________________
|
||||
When you trash this, put it into your hand.
|
||||
14 Ironmonger Dark Ages Action $4 +1 Card, +1 Action
|
||||
Reveal the top card of your deck; you may discard it. Either way, if it is an…
|
||||
Action card, +1 Action
|
||||
Treasure card, +1 Coin
|
||||
Victory card, +1 Card
|
||||
15 Procession Dark Ages Action $4 You may play an Action card from your hand twice. Trash it. Gain an Action card costing exactly 1 Coin more than it.
|
||||
16 Rats Dark Ages Action $4 +1 Card, +1 Action
|
||||
Gain a Rats. Trash a card from your hand other than a Rats (or reveal a hand of all Rats).
|
||||
______________________
|
||||
When you trash this, +1 Card.
|
||||
17 Band of Misfits Dark Ages Action $5 Play this as if it were an Action card in the Supply costing less than it that you choose.
|
||||
This is that card until it leaves play.
|
||||
18 Bandit Camp Dark Ages Action $5 +1 Card, +2 Actions
|
||||
Gain a Spoils from the Spoils pile.
|
||||
19 Count Dark Ages Action $5 Choose one: Discard 2 cards; or put a card from your hand on top of your deck; or gain a Copper.
|
||||
Choose one: +3 Coins; or trash your hand; or gain a Duchy.
|
||||
20 Cultist Dark Ages Action - Attack - Looter $5 +2 Cards
|
||||
Each other player gains a Ruins. You may play a Cultist from your hand.
|
||||
______________________
|
||||
When you trash this, +3 Cards.
|
||||
21 Graverobber Dark Ages Action $5 Choose one: Gain a card from the trash costing from 3 Coins to 6 Coins, putting it on top of your deck; or trash an Action card from your hand and gain a card costing up to 3 Coins more than it.
|
||||
22 Pillage Dark Ages Action - Attack $5 Trash this. Each other player with 5 or more cards in hand reveals his hand and discards a card that you choose.
|
||||
Gain 2 Spoils from the Spoils pile.
|
||||
23 Scavenger Dark Ages Action $4 +2 Coins
|
||||
You may put your deck into your discard pile. Look through your discard pile and put one card from it on top of your deck.
|
||||
24 Altar Dark Ages Action $6 Trash a card from your hand. Gain a card costing up to 5 Coins.
|
||||
29 Armory Dark Ages Action $4 Gain a card costing up to 4 Coins, putting it on top of your deck.
|
||||
25 Beggar Dark Ages Action - Reaction $2 Gain 3 Coppers, putting them into your hand.
|
||||
______________________
|
||||
When another player plays an Attack card, you may discard this.
|
||||
If you do, gain two Silvers, putting one on top of your deck.
|
||||
26 Catacombs Dark Ages Action $5 Look at the top 3 cards of your deck.
|
||||
Choose one: Put them into your hand;
|
||||
or discard them and +3 Cards.
|
||||
______________________
|
||||
When you trash this, gain a cheaper card.
|
||||
27 Counterfeit Dark Ages Treasure $5 Worth 1 Coin
|
||||
+1 Buy
|
||||
When you play this, you may play a Treasure from your hand twice. If you do, trash that Treasure
|
||||
28 Death Cart Dark Ages Action - Looter $4 +5 Coins
|
||||
You may trash an Action card from your hand. If you don’t, trash this.
|
||||
______________________
|
||||
When you gain this, gain 2 Ruins.
|
||||
29 Forager Dark Ages Action $3 +1 Action
|
||||
+1 Buy
|
||||
Trash a card from your hand.
|
||||
+1 Coin per differently named Treasure
|
||||
in the trash.
|
||||
30 Junk Dealer Dark Ages Action $5 +1 Card
|
||||
+1 Action
|
||||
+1 Coin
|
||||
Trash a card from your hand.
|
||||
31 Knights Dark Ages Action $5 This is a pile in which each card is different. There is the same basic ability on each card, but also another ability unique to that card in the pile, and they all have different names. Shuffle the Knights pile before playing with it, keeping it face down except for the top one, which is the only card that can be gained from the pile. See Additional Rules for Dark Ages and Preparation. Follow the rules on Knights in order from top to bottom; Sir Michael causes players to discard before it trashes cards.
|
||||
32 Marauder Dark Ages Action $4 Gain a Spoils from the Spoils pile.
|
||||
Each other player gains a Ruins.
|
||||
33 Market Square Dark Ages Action - Reaction $3 +1 Card
|
||||
+1 Action
|
||||
+1 Buy
|
||||
______________________
|
||||
When one of your cards is trashed,
|
||||
you may discard this from your
|
||||
hand. If you do, gain a Gold.
|
||||
34 Rebuild Dark Ages Action $5 + 1 Action
|
||||
Name a card. Reveal cards from the top of your deck until you reveal a Victory card that is not the named card. Discard the other cards. Trash the Victory card and gain a Victory card costing up to 3 Coins more than it.
|
||||
35 Rogue Dark Ages Action - Attack $5 + 2 Coins
|
||||
If there are any cards in the trash costing from 3 Coins to 6 Coins, gain one of them. Otherwise, each other player reveals the top 2 cards of his deck, trashes one of them costing from 3 Coins to 6 Coins, and discards the rest.
|
||||
36 Storeroom Dark Ages Action $3 + 1 Buy
|
||||
Discard any number of cards.
|
||||
+1 Card per card discarded.
|
||||
Discard any number of cards.
|
||||
+ 1 Coins per card discarded the second time.
|
||||
37 Urchin Dark Ages Action - Attack $3 +1 Card
|
||||
+1 Action
|
||||
Each other player discards down to 4 cards in hand.
|
||||
______________________
|
||||
When you play another Attack card with this in play, you may trash this.
|
||||
If you do, gain a Mercenary from the Mercenary pile.
|
||||
38 Wandering Minstrel Dark Ages Action $4 +1 Card
|
||||
+2 Actions
|
||||
Reveal the top 3 cards of your deck.
|
||||
Put the Actions back on top in any order and discard the rest.
|
||||
39 Hunting Grounds Dark Ages Action $6 + 4 Cards
|
||||
______________________
|
||||
When you trash this,
|
||||
gain a Duchy or 3 Estates.
|
||||
40 Mercenary Dark Ages Action - Attack $0* You may trash 2 cards from your hand.
|
||||
If you do, +2 Cards, + 2 Coins,
|
||||
and each other player discards down to 3 cards in hand.
|
||||
(This is not in the Supply.)
|
||||
41 Mystic Dark Ages Action $5 +1 Action
|
||||
+ 2 Coins
|
||||
Name a card.
|
||||
Reveal the top card of your deck.
|
||||
If it’s the named card, put it into your hand.
|
||||
42 Shelters Dark Ages Extras Action - Shelter $1 Hovel: When you buy a Victory card, you may trash this from your hand.
|
||||
Necropolis: +2 Actions
|
||||
Overgrown Estate: 0 <VP>; when you trash this, +1 Card.
|
||||
43 Urchin / Mercenary Dark Ages Extras Action $3 Urchin: When you play this, you draw a card and get +1 Action, then each other player discards down to 4 cards in hand. Players who already have 4 or fewer cards in hand do not do anything. While Urchin is in play, when you play another Attack card, before resolving it, you may trash the Urchin. If you do, you gain a Mercenary. If there are no Mercenaries left you do not gain one. If you play the same Urchin twice in one turn, such as via Procession, that does not let you trash it for a Mercenary. If you play two different Urchins however, playing the second one will let you trash the first one.
|
||||
44 Hermit / Madman Dark Ages Extras Action $3 Hermit: When you play this, look through your discard pile, and then you may choose to trash a card that is not a Treasure, from either your hand or your discard pile. You do not have to trash a card and cannot trash Treasures. A card with multiple types, one of which is Treasure (such as Harem from Intrigue), is a Treasure. After trashing or not, you gain a card costing up to 3 Coins. The card you gain comes from the Supply and is put into your discard pile. Gaining a card is mandatory if it is possible. Then, when you discard Hermit from play - normally, in Clean-up, after playing it in your Action phase - if you did not buy any cards this turn, you trash Hermit and gain a Madman. It does not matter whether or not you gained cards other ways, only whether or not you bought a card. If there are no Madman cards left, you do not gain one. If Hermit is not discarded from play during Clean-up - for example, if you put it on your deck with Scheme (from Hinterlands) - then the ability that trashes it will not trigger.
|
||||
|
||||
1 Advisor Guilds Action $4 +1 Action
|
||||
Reveal the top 3 cards of your deck. The player to your left chooses one of them. Discard that card. Put the other cards into your hand.
|
||||
2 Baker Guilds Action $5 +1 Card
|
||||
+1 Action
|
||||
Take a Coin token.
|
||||
______________________
|
||||
Setup: Each player takes a Coin token.
|
||||
3 Butcher Guilds Action $5 Take two Coin tokens. You may trash a card from your hand and then pay any number of Coin tokens. If you did trash a card, gain a card with a cost of up to the cost of the trashed card plus the number of Coin tokens you paid.
|
||||
4 Candlestick Maker Guilds Action $2 +1 Action
|
||||
+1 Buy
|
||||
Take a Coin token.
|
||||
5 Doctor Guilds Action $3+ Name a card. Reveal the top 3 cards of your deck. Trash the matches. Put the rest back on top in any order.
|
||||
______________________
|
||||
When you buy this, you may overpay for it. For each 1 Coin you overpaid, look at the top card of your deck; trash it, discard it, or put it back.
|
||||
6 Herald Guilds Action $4+ +1 Card
|
||||
+1 Action
|
||||
Reveal the top card of your deck. If it is an Action, play it.
|
||||
______________________
|
||||
When you buy this, you may overpay for it. For each 1 Coin you overpaid, look through your discard pile and put a card from it on top of your deck.
|
||||
7 Journeyman Guilds Action $5 Name a card. Reveal cards from the top of your deck until you reveal 3 cards that are not the named card. Put those cards into your hand and discard the rest.
|
||||
8 Masterpiece Guilds Treasure $3+ Worth 1 Coin.
|
||||
______________________
|
||||
When you buy this, you may overpay for it. If you do, gain a Silver per 1 Coin you overpaid.
|
||||
9 Merchant Guild Guilds Action $5 +1 Buy
|
||||
+1 Coin
|
||||
______________________
|
||||
While this is in play, when you buy a card, take a Coin token.
|
||||
10 Plaza Guilds Action $4 +1 Card
|
||||
+2 Actions
|
||||
You may discard a Treasure card. If you do, take a Coin token.
|
||||
11 Soothsayer Guilds Action - Attack $5 Gain a Gold. Each other player gains a Curse. Each player who did draws a card.
|
||||
12 Stonemason Guilds Action $2+ Trash a card from your hand. Gain 2 cards each costing less than it.
|
||||
______________________
|
||||
When you buy this, you may overpay for it. If you do, gain 2 Action cards each costing the amount you overpaid.
|
||||
13 Taxman Guilds Action - Attack $4 You may trash a Treasure from your hand. Each other player with 5 or more cards in hand discards a copy of it (or reveals a hand without it). Gain a Treasure card costing up to 3 Coins more than the trashed card, putting it on top of your deck.
|
||||
|
||||
1 Amulet Adventures Action - Duration $3 Now and at the start of your next turn, choose one: +1 Coin; or trash a card from your hand; or gain a Silver.
|
||||
2 Artificer Adventures Action $5 +1 Card
|
||||
+1 Action
|
||||
+1 Coin
|
||||
Discard any number of cards. You may gain a card costing exactly 1 Coin per card discarded, putting it on top of your deck.
|
||||
3 Bridge Troll Adventures Action - Attack - Duration $5 Each other player takes his -1 Coin token. Now and at the start of your next turn:
|
||||
+1 Buy
|
||||
______________________
|
||||
While this is in play, cards cost 1 Coin less on your turn, but not less than 0 Coins.
|
||||
4 Caravan Guard Adventures Action - Duration - Reaction $3 +1 Card
|
||||
+1 Action
|
||||
At the start of your next turn, +1 Coin
|
||||
______________________
|
||||
When another player plays an Attack card, you may play this from your hand. (+1 Action has no effect if it's not your turn.)
|
||||
5 Dungeon Adventures Action - Duration $3 +1 Action
|
||||
Now and at the start of your next turn: +2 Cards then discard 2 cards.
|
||||
6 Duplicate Adventures Action - Reserve $4 Put this on your Tavern mat.
|
||||
______________________
|
||||
When you gain a card costing up to 6 Coins, you may call this, to gain a copy of that card.
|
||||
7 Gear Adventures Action - Duration $3 +2 Cards
|
||||
Set aside up to 2 cards from your hand face down. At the start of your next turn, put them into your hand.
|
||||
8 Giant Adventures Action - Attack $5 Turn your Journey token over (it starts face up). If it's face down, +1 Coin. If it's face up, +5 Coins, and each other player reveals the top card of his deck, trashes it if it costs 3 Coins to 6 Coins, and otherwise discards it and gains a Curse.
|
||||
9 Guide Adventures Action - Reserve $3 +1 Card
|
||||
+1 Action
|
||||
Put this on your Tavern mat.
|
||||
______________________
|
||||
At the start of your turn, you may call this, to discard your hand and draw 5 cards.
|
||||
10 Haunted Woods Adventures Action - Attack - Duration $5 Until your next turn, when any other player buys a card, he puts his hand on top of his deck in any order.
|
||||
At the start of your next turn:
|
||||
+3 Cards
|
||||
11 Hireling Adventures Action - Duration $6 At the start of each of your turns for the rest of the game:
|
||||
+1 Card
|
||||
(This stays in play.)
|
||||
12 Lost City Adventures Action $5 +2 Cards
|
||||
+2 Actions
|
||||
______________________
|
||||
When you gain this, each other player draws a card.
|
||||
13 Magpie Adventures Action $4 +1 Card
|
||||
+1 Action
|
||||
Reveal the top card of your deck. If it's a Treasure, put it into your hand. If it's an Action or Victory card, gain a Magpie.
|
||||
14 Messenger Adventures Action $4 +1 Buy
|
||||
+2 Coins
|
||||
You may put your deck into your discard pile.
|
||||
______________________
|
||||
When this is your first buy in a turn, gain a card costing up to 4 Coins, and each other player gains a copy of it.
|
||||
15 Miser Adventures Action $4 Choose one: Put a Copper from your hand onto your Tavern mat; or +1 Coin per Copper on your Tavern mat.
|
||||
16 Ranger Adventures Action $4 +1 Buy
|
||||
Turn your Journey token over (it starts face up). If it's face up, +5 Cards.
|
||||
17 Ratcatcher Adventures Action - Reserve $2 +1 Card
|
||||
+1 Action
|
||||
Put this on your Tavern mat.
|
||||
______________________
|
||||
At the start of your turn, you may call this, to trash a card from your hand.
|
||||
18 Raze Adventures Action $2 +1 Action
|
||||
Trash this or a card from your hand. Look at the number of cards from the top of your deck equal to the cost in Coins of the trashed card. Put one into your hand and discard the rest.
|
||||
19 Royal Carriage Adventures Action - Reserve $5 +1 Action
|
||||
Put this on your Tavern mat.
|
||||
______________________
|
||||
Directly after resolving an Action, if it's still in play, you may call this, to replay that Action.
|
||||
20 Storyteller Adventures Action $5 +1 Action
|
||||
+1 Coin
|
||||
Play up to 3 Treasures from your hand. Pay all of your Coins. +1 Card per Coin paid.
|
||||
21 Swamp Hag Adventures Action - Attack - Duration $5 Until your next turn, when any other player buys a card, he gains a Curse.
|
||||
At the start of your next turn:
|
||||
+3 Coins
|
||||
22 Transmogrify Adventures Action - Reserve $4 +1 Action
|
||||
Put this on your Tavern mat.
|
||||
______________________
|
||||
At the start of your turn, you may call this, to trash a card from your hand, gain a card costing up to 1 Coin more than it, and put that card into your hand.
|
||||
23 Wine Merchant Adventures Action - Reserve $5 +1 Buy
|
||||
+4 Coins
|
||||
Put this on your Tavern mat.
|
||||
______________________
|
||||
At the end of your Buy phase, if you have at least 2 Coins unspent, you may discard this from your Tavern mat.
|
||||
24 Port Adventures Action $4 +1 Card
|
||||
+2 Actions
|
||||
______________________
|
||||
When you buy this, gain another Port.
|
||||
25 Coin of the Realm Adventures Treasure - Reserve $2 1 Coin
|
||||
When you play this, put it on your Tavern mat.
|
||||
______________________
|
||||
Directly after resolving an Action, you may call this for +2 Actions.
|
||||
26 Relic Adventures Treasure - Attack $5 2 Coins
|
||||
When you play this, each other player puts his -1 Card token on his deck.
|
||||
27 Treasure Trove Adventures Treasure $5 2 Coins
|
||||
When you play this, gain a Gold and a Copper.
|
||||
28 Distant Lands Adventures Action - Reserve - Victory $5 Put this on your Tavern mat.
|
||||
______________________
|
||||
Worth 4 VP if on your Tavern mat at the end of the Game (otherwise worth 0 VP).
|
||||
29 Page Adventures Action - Traveller $2 +1 Card
|
||||
+1 Action
|
||||
______________________
|
||||
When you discard this from play, you may exchange it for a Treasure Hunter.
|
||||
30 Peasant Adventures Action - Traveller $2 +1 Buy
|
||||
+1 Coin
|
||||
______________________
|
||||
When you discard this from play, you may exchange it for a Soldier.
|
||||
31 Treasure Hunter Adventures Action - Traveller $3* +1 Action
|
||||
+1 Coin
|
||||
Gain a Silver per card the player to your right gained in his last turn.
|
||||
______________________
|
||||
When you discard this from play, you may exchange it for a Warrior.
|
||||
(This is not in the Supply.)
|
||||
32 Warrior Adventures Action - Attack - Traveller $4* +2 Cards
|
||||
For each Traveller you have in play (including this), each other player discards the top card of his deck and trashes it if it costs 3 Coins or 4 Coins.
|
||||
______________________
|
||||
When you discard this from play, you may exchange it for a Hero.
|
||||
(This is not in the Supply.)
|
||||
33 Hero Adventures Action - Traveller $5* +2 Coins
|
||||
Gain a Treasure.
|
||||
______________________
|
||||
When you discard this from play, you may exchange it for a Champion.
|
||||
(This is not in the Supply.)
|
||||
34 Champion Adventures Action - Duration $6* +1 Action
|
||||
For the rest of the game, when another player plays an Attack, it doesn't affect you, and when you play an Action, +1 Action.
|
||||
(This stays in play. This is not in the Supply.)
|
||||
35 Soldier Adventures Action - Attack - Traveller $3* +2 Coins
|
||||
+1 Coin per other Attack you have in play. Each other player with 4 or more cards in hand discards a card.
|
||||
______________________
|
||||
When you discard this from play, you may exchange it for a Fugitive.
|
||||
(This is not in the Supply.)
|
||||
36 Fugitive Adventures Action - Traveller $4* +2 Cards
|
||||
+1 Action
|
||||
Discard a card.
|
||||
______________________
|
||||
When you discard this from play, you may exchange it for a Disciple.
|
||||
(This is not in the Supply.)
|
||||
37 Disciple Adventures Action - Traveller $5* You may play an Action card from your hand twice. Gain a copy of it.
|
||||
______________________
|
||||
When you discard this from play, you may exchange it for a Teacher.
|
||||
(This is not in the Supply.)
|
||||
38 Teacher Adventures Action - Reserve $6* Put this on your Tavern mat.
|
||||
______________________
|
||||
At the start of your turn, you may call this, to move your +1 Card, +1 Action, +1 Buy, or +1 Coin token to an Action Supply pile you have no tokens on (when you play a card from that pile, you first get that bonus).
|
||||
(This is not in the Supply.)
|
||||
39 Alms Adventures Event $0 Once per turn: If you have no Treasures in play, gain a card costing up to 4 Coin.
|
||||
40 Ball Adventures Event $5 Take your - 1 Coin token. Gain 2 cards each costing up to 4 Coin.
|
||||
41 Bonfire Adventures Event $3 Trash up to 2 cards you have in play.
|
||||
42 Borrow Adventures Event $0 +1 Buy
|
||||
Once per turn: If your -1 Card token isn't on your deck, put it there and +1 Coin.
|
||||
43 Expedition Adventures Event $3 Draw 2 extra cards for your next hand.
|
||||
44 Ferry Adventures Event $3 Move your - 2 Coin cost token to an Action Supply pile (cards from that pile cost 2 Coin less on your turns, but not less than 0 Coin.
|
||||
45 Inheritance Adventures Event $7 Once per game: Set aside a non-Victory Action card from the Supply costing up to 4 Coin. Move your Estate token to it (your Estates gain the abilities and types of that card).
|
||||
46 Lost Arts Adventures Event $6 Move your +1 Action token to an Action Supply pile (when you play a card from that pile, you first get +1 Action).
|
||||
47 Mission Adventures Event $4 Once per turn: If the previous turn wasn't yours, take another turn after this one, in which you can't buy cards.
|
||||
48 Pathfinding Adventures Event $8 Move your +1 Card token to an Action Supply pile (when you play a card from that pile, you first get +1 Card).
|
||||
49 Pilgrimage Adventures Event $4 Once per turn: Turn your Journey token over (it starts face up); then if it's face up, choose up to 3 differently named cards you have in play and gain a copy of each.
|
||||
50 Plan Adventures Event $3 Move your Trashing token to an Action Supply pile (when you buy a card from that pile, you may trash a card from your hand.)
|
||||
51 Quest Adventures Event $0 You may discard an Attack, two Curses, or six cards. If you do, gain a Gold.
|
||||
52 Raid Adventures Event $5 Gain a Silver per Silver you have in play. Each other player puts his -1 Card token on his deck.
|
||||
53 Save Adventures Event $1 +1 Buy
|
||||
Once per turn: Set aside a card from your hand, and put it into your hand at end of turn (after drawing).
|
||||
54 Scouting Party Adventures Event $2 +1 Buy
|
||||
Look at the top 5 cards of your deck. Discard 3 of them and put the rest back on top of your deck in any order.
|
||||
55 Seaway Adventures Event $5 Gain an Action card costing up to 4 Coin. Move your +1 Buy token to its pile (when you play a card from that pile, you first get +1 Buy).
|
||||
56 Trade Adventures Event $5 Trash up to 2 cards from your hand.
|
||||
Gain a Silver per card you trashed.
|
||||
57 Training Adventures Event $6 Move your + 1 Coin token to an Action Supply pile (when you play a card from that pile, you first get + 1 Coin).
|
||||
58 Travelling Fair Adventures Event $2 +2 Buys
|
||||
When you gain a card this turn, you may put it on top of your deck.
|
||||
59 Events Adventures Extras Event $* Events are not Kingdom cards. In a player’s Buy phase, when the player can buy a card, the player can buy an Event instead. Buying an Event means paying the cost indicated on the Event and then doing the effect of the Event. The Event just stays on the table, the player does not take it; there is no way for a player to gain one or end up with one in his deck. Buying an Event uses up a Buy; normally a player can either buy a card, or buy an Event. A player with two Buys, such as after playing Ranger, could buy two cards, or buy two Events, or buy a card and an Event (in either order). The same Event can be bought multiple times in a turn if the player has the Buys and available to do it. Some Events give +Buys and so let the player buy further cards/Events afterwards. Players cannot play further Treasures that turn after buying an Event. Buying an Event is not buying a card and so does not trigger cards like Swamp Hag or Goons (from Prosperity). Costs of Events are not affected by cards like Bridge Troll.
|
||||
2
card_db/en_us/mapping.json
Normal file
2
card_db/en_us/mapping.json
Normal file
@ -0,0 +1,2 @@
|
||||
{
|
||||
}
|
||||
@ -1,15 +0,0 @@
|
||||
"Action": "Action"
|
||||
"Victory": "Victory"
|
||||
"Attack": "Attack"
|
||||
"Treasure": "Treasure"
|
||||
"Reaction": "Reaction"
|
||||
"Duration": "Duration"
|
||||
"Prize": "Prize"
|
||||
"Shelter": "Shelter"
|
||||
"Ruins": "Ruins"
|
||||
"Looter": "Looter"
|
||||
"Curse": "Curse"
|
||||
"Blank": "Blank"
|
||||
"Reserve": "Reserve"
|
||||
"Traveller": "Traveller"
|
||||
"Event": "Event"
|
||||
52
card_db/it/card_groups.json
Normal file
52
card_db/it/card_groups.json
Normal file
@ -0,0 +1,52 @@
|
||||
{
|
||||
"Tournament": {
|
||||
"subcards": [
|
||||
"Bag of Gold",
|
||||
"Diadem",
|
||||
"Followers",
|
||||
"Princess",
|
||||
"Trusty Steed"
|
||||
],
|
||||
"new_name": "Tournament and Prizes"
|
||||
},
|
||||
"Shelters": {
|
||||
"subcards": [
|
||||
"Hovel",
|
||||
"Overgrown Estate",
|
||||
"Necropolis"
|
||||
],
|
||||
"new_name": "Shelters"
|
||||
},
|
||||
"Page": {
|
||||
"subcards": [
|
||||
"Treasure Hunter",
|
||||
"Warrior",
|
||||
"Hero",
|
||||
"Champion"
|
||||
],
|
||||
"new_name": "Page -> Champion"
|
||||
},
|
||||
"Peasant": {
|
||||
"subcards": [
|
||||
"Soldier",
|
||||
"Fugitive",
|
||||
"Disciple",
|
||||
"Teacher"
|
||||
],
|
||||
"new_name": "Peasant -> Teacher"
|
||||
},
|
||||
"Hermit \/ Madman": {
|
||||
"subcards": [
|
||||
"Hermit",
|
||||
"Madman"
|
||||
],
|
||||
"new_name": "Hermit \/ Madman"
|
||||
},
|
||||
"Urchin \/ Mercenary": {
|
||||
"subcards": [
|
||||
"Urchin",
|
||||
"Mercenary"
|
||||
],
|
||||
"new_name": "Urchin \/ Mercenary"
|
||||
}
|
||||
}
|
||||
2829
card_db/it/cards.json
Normal file
2829
card_db/it/cards.json
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,518 +0,0 @@
|
||||
1 Sotterraneo Dominion Azione $2 +1 Azione, Scarta qualsiadi numero di carte. +1 Carta per carta scartata.
|
||||
2 Cappella Dominion Azione $2 Elimina fino a 4 carte dalla tua mano.
|
||||
3 Fossato Dominion Azione - Reazione $2 +2 Carte, Quando un altro giocatore usa una carta Attacco, puoi rivelare questa carta dalla tua mano. Se lo fai, l'Attacco non ha effetto su di te.
|
||||
4 Cancelliere Dominion Azione $3 +2 Monete, Puoi mettere immediatamente il tuo mazzo nella pila degli scarti.
|
||||
5 Villaggio Dominion Azione $3 +1 Carta, +2 Azioni.
|
||||
6 Taglialegna Dominion Azione $3 +1 Acquisto, +2 Monete.
|
||||
7 Officina Dominion Azione $3 Ottieni una carta che costi fino a 4 Monete.
|
||||
8 Burocrate Dominion Azione - Attacco $4 Ottieni una carta Argento; mettila in cima al tuo mazzo. Ogni altro giocatore rivela una carta Vittoria dalla sua mano e la mette sul suo mazzo (o rivela una mano senza carte Vittoria).
|
||||
9 Banchetto Dominion Azione $4 Elimina questa carta. Ottieni una carta che costi fino a 5 Monete.
|
||||
10 Giardini Dominion Vittoria $4 Variabile, Vale 1 <VP> ogni 10 carte nel tuo mazzo (per difetto).
|
||||
11 Milizia Dominion Azione - Attacco $4 +2 Monete, Ogni altro giocatore scarta fino ad avere 3 carte nella sua mano.
|
||||
12 Usuraio Dominion Azione $4 Elimina un Rame dalla tua mano. Se lo fai, +3 Monete.
|
||||
13 Miglioria Dominion Azione $4 Elimina una carta dalla tua mano. Ottieni una carta che costi fino a 2 Monete in più della carta eliminata.
|
||||
14 Fucina Dominion Azione $4 +3 Carte.
|
||||
15 Spia Dominion Azione - Attacco $4 +1 Carta, +1 Azione, Ogni giocatore (incluso te) rivela la carta in cima al proprio mazzo, per poi scartarla o rimetterla al suo posto a tua scelta.
|
||||
16 Ladro Dominion Azione - Attacco $4 Ogni altro giocatore rivela le prime due carte del suo mazzo. Se fra le carte rivelate ci sono carte Tesoro, ne elimina una di tua scelta. Puoi ottenere le carte eliminate. Le altre carte rivelate vengono scartate.
|
||||
17 Sala del Trono Dominion Azione $4 Scegli una carta Azione dalla tua mano. Giocala due volte.
|
||||
18 Sala del Consiglio Dominion Azione $5 +4 Carte, +1 Acquisto, Ogni altro giocatore pesca una carta.
|
||||
19 Fiera Dominion Azione $5 +2 Azioni, +1 Acquisto, +2 Monete.
|
||||
20 Laboratorio Dominion Azione $5 +2 Carte, +1 Azione.
|
||||
21 Biblioteca Dominion Azione $5 Pesca fino ad avere 7 carte nella tua mano. Puoi mettere da parte qualsiasi carta Azione pescata in questo modo; scarta le carte messe da parte dopo aver finito di pescare.
|
||||
22 Mercato Dominion Azione $5 +1 Carta, +1 Azione, +1 Acquisto, +1 Moneta.
|
||||
23 Miniera Dominion Azione $5 Elimina una carta Tesoro dalla tua mano. Ottieni una carta Tesoro che costi fino a 3 Monete in più; mettila nella tua mano.
|
||||
24 Strega Dominion Azione - Attacco $5 +2 Carte, Ogni altro giocatore ottiene una carta Maledizione.
|
||||
25 Esploratore Dominion Azione $6 Rivela carte dal tuo mazzo fino a rivelare 2 carte Tesoro. Metti queste carte Tesoro nella tua mano e scarta le altre carte rivelate.
|
||||
26 Rame Dominion Tesoro $0 Vale 1 Moneta.
|
||||
27 Argento Dominion Tesoro $3 Vale 2 Monete.
|
||||
28 Oro Dominion Tesoro $6 Vale 3 Monete.
|
||||
29 Maledizione Dominion Maledizione $0 -1 <VP>
|
||||
30 Tenuta Dominion Vittoria $2 1 <VP>
|
||||
31 Ducato Dominion Vittoria $5 3 <VP>
|
||||
32 Provincia Dominion Vittoria $8 6 <VP>
|
||||
33 Carte Eliminate Dominion Azione $0 Pila delle carte eliminate.
|
||||
|
||||
1 Cortile di Campagna Intrigo Azione $2 +3 Carte, Metti una carta dalla tua mano in cima al tuo mazzo.
|
||||
2 Pedina Intrigo Azione $2 Scegli due: +1 Carta, +1 Azione, +1 Acquisto, +1 Moneta. (le scelte devono essere diverse).
|
||||
3 Stanza Segreta Intrigo Azione - Reazione $2 Scarta qualsiasi numero di carte. +1 Moneta per carta scartata. - Quando un altro giocatore usa una carta Attacco, puoi rivelare questa carta dalla tua mano. Se lo fai, +2 carte, poi metti 2 carte dalla tua mano in cima al tuo mazzo.
|
||||
4 Grande Salone Intrigo Azione - Vittoria $3 +1 Carta, +1 Azione, 1 <VP>
|
||||
5 Ballo in Maschera Intrigo Azione $3 +2 Carte, Ogni giocatore passa una carta dalla sua mano al giocatore alla propria sinistra. Puoi eliminare una carta dalla tua mano.
|
||||
6 Baraccopoli Intrigo Azione $3 +2 Azioni, Rivela la tua mano. Se non hai carte Azione in mano, +2 Carte.
|
||||
7 Maggiordomo Intrigo Azione $3 Scegli: +2 Carte; o +2 Monete; o elimina 2 carte dalla tua mano.
|
||||
8 Truffatore Intrigo Azione - Attacco $3 +2 Monete, Ogni altro giocatore elimina la carta in cima al proprio mazzo ed ottiene una carta dello stesso costo di tua scelta.
|
||||
9 Pozzo dei Desideri Intrigo Azione $3 +1 Carta, +1 Azione, Nomina una carta, quindi rivela la carta in cima al tuo mazzo. Se è la carta nominata, mettila nella tua mano.
|
||||
10 Barone Intrigo Azione $4 +1 Acquisto, Puoi scartare una carta Tenuta. Se lo fai, +4 Monete. Altrimenti, ottieni una carta Tenuta.
|
||||
11 Ponte Intrigo Azione $4 +1 Acquisto, +1 Moneta. Tutte le carte (incluse le carte in mano ai giocatori) costano 1 Moneta in meno durante questo turno, ma non meno di 0 Monete.
|
||||
12 Cospiratore Intrigo Azione $4 +2 Monete. Se hai giocato 3 o più carte Azione in questo turno (questa inclusa): +1 Carta, +1 Azione.
|
||||
13 Battirame Intrigo Azione $4 Le carte Rame valgono una Moneta in più durante questo turno.
|
||||
14 Fonderia Intrigo Azione $4 Ottieni una carta che costi fino a 4 Monete. Se è una carta Azione, +1 Azione. Se è una carta Tesoro, +1 Moneta. Se è una carta Vittoria, +1 Carta.
|
||||
15 Villaggio Minerario Intrigo Azione $4 +1 Carta, +2 Azioni. Puoi eliminare immediatamente questa carta. Se lo fai, +2 Monete.
|
||||
16 Scout Intrigo Azione $4 +1 Azione. Rivela le prime 4 carte del tuo mazzo. Metti le carte Vittoria rivelate nella tua mano. Rimetti le altre carte in cima al tuo mazzo nell'ordine che preferisci.
|
||||
17 Duca Intrigo Vittoria $5 Vale 1 <VP> per ogni Ducato in tuo possesso.
|
||||
18 Tirapiedi Intrigo Azione - Attacco $5 +1 Azione, Scegli: +2 Monete; o scarta la tua mano, +4 Carte, e ogni altro giocatore che abbia almeno 5 carte nella propria mano scarta la sua mano e pesca 4 carte.
|
||||
19 Sabotatore Intrigo Azione - Attacco $5 Ogni altro giocatore rivela carte dalla cima del suo mazzo fino a rivelarne una che costi almeno 3 Monete. Elimina quella carta e può ottenerne una che costi al massimo 2 Monete in meno di essa. Scarta le altre carte rivelate.
|
||||
20 Carceriere Intrigo Azione - Attacco $5 +3 Carte, Ogni altro giocatore sceglie: scarta 2 carte; o ottiene una carta Maledizione, mettendola nella sua mano.
|
||||
21 Stazione Commerciale Intrigo Azione $5 Elimina 2 carte dalla tua mano. Se lo fai, ottieni una carta Argento; mettila nella tua mano.
|
||||
22 Tributo Intrigo Azione $5 Il giocatore alla tua sinistra scarta le prime 2 carte del suo mazzo. Per ogni carta dal nome diverso rivelata, se è una carta Azione, +2 Azioni; carta Tesoro, +2 Monete; carta Vittoria, +2 Carte.
|
||||
23 Potenziameno Intrigo Azione $5 +1 Carta, +1 Azione, Elimina una carta dalla tua mano. Ottieni una carta che costi esattamente 1 Moneta più della carta eliminata.
|
||||
24 Harem Intrigo Tesoro - Vittoria $6 Vale 2 Monete, 2 <VP>
|
||||
25 Nobili Intrigo Azione - Vittoria $6 2 <VP>
|
||||
Scegli: +3 Carte, o +2 Azioni.
|
||||
26 Rame Intrigo Tesoro $0 Vale 1 Moneta.
|
||||
27 Argento Intrigo Tesoro $3 Vale 2 Monete.
|
||||
28 Oro Intrigo Tesoro $6 Vale 3 Monete.
|
||||
29 Maledizione Intrigo Maledizione $0 -1 <VP>
|
||||
30 Tenuta Intrigo Vittoria $2 1 <VP>
|
||||
31 Ducato Intrigo Vittoria $5 3 <VP>
|
||||
32 Provincia Intrigo Vittoria $8 6 <VP>
|
||||
33 Carte Eliminate Intrigo Azione $0 Pila delle carte eliminate.
|
||||
|
||||
1 Embargo Seaside Azione $2 +2 Monete, Elimina questa carta. Metti un segnalino Embargo in cima ad un mazzetto della Riserva. - Quando un giocatore compra una carta, ottiene una carta Maledizione per ogni segnalino Embargo su quel mazzetto.
|
||||
2 Rada Seaside Azione - Durata $2 +1 Carta, +1 Azione, Metti da parte una carta coperta dalla tua mano. All'inizio del tuo prossimo turno, mettila nella tua mano.
|
||||
3 Faro Seaside Azione - Durata $2 +1 Azione, Ora e all'inizio del tuo prossimo turno: +1 Moneta. - Mentre questa carta è in gioco, quando un altro giocatore usa una carta Attacco, quella carta non ha effetto su di te.
|
||||
4 Villaggio Indigeno Seaside Azione $2 +2 Azioni, Scegli: metti da parte una carta coperta dalla tua mano sulla tua plancia Villaggio Indigeno; o prendi in mano tutte le carte dalla tua plancia Villaggio Indigeno. Puoi guardare le carte sulla tua plancia quando vuoi; rimettile nel tuo mazzo alla fine della partita.
|
||||
5 Pescatore di Perle Seaside Azione $2 +1 Carta, +1 Azione, Guarda la carta in fondo al tuo mazzo. Puoi metterla in cima.
|
||||
6 Ambasciatore Seaside Azione - Attacco $3 Rivela una carta dalla tua mano. Rimetti fino a 2 copie di essa dalla tua mano alla Riserva. Quindi ogni altro giocatore ne ottiene una copia.
|
||||
7 Villaggio di Pescatori Seaside Azione - Durata $3 +2 Azioni, +1 Moneta, All'inizio del tuo prossimo turno: +1 Azione, +1 Moneta.
|
||||
8 Vedetta Seaside Azione $3 +1 Azione, Guarda le prime 3 carte del tuo mazzo. Eliminane una. Scartane una. Rimetti l'altra in cima al mazzo.
|
||||
9 Contrabbandieri Seaside Azione $3 Ottieni una copia di una carta che costi fino a 6 Monete che il giocatore alla tua destra abbia ottenuto nel suo ultimo turno.
|
||||
10 Magazzino Seaside Azione $3 +3 Carte, +1 Azione, scarta 3 carte.
|
||||
11 Carovana Seaside Azione - Durata $4 +1 Carta, +1 Azione
|
||||
All'inizio del tuo prossimo turno, +1 Carta.
|
||||
12 Borseggiatore Seaside Azione - Attacco $4 +2 Monete, Ogni altro giocatore scarta una carta Rame (o rivela una carta senza Rame).
|
||||
13 Isola Seaside Azione - Vittoria $4 Metti da parte questa e un'altra carta dalla tua mano sulla tua plancia Isola. Rimettile nel tuo mazzo alla fine della partita. 2 <VP>
|
||||
14 Navigatore Seaside Azione $4 +2 Monete, Guarda le prima 5 carte del tuo mazzo. Scartale tutte, o rimettile in cima al tuo mazzo nell'ordine che preferisci.
|
||||
15 Nave Pirata Seaside Azione - Attacco $4 Scegli: Ogni altro giocatore rivela le prime 2 carte del suo mazzo, elimina una carta Tesoro rivelata di tua scelta, scarta il resto e se è stata eliminata almeno una carta tesoro metti un segnalino Moneta sulla tua plancia Nave Pirata; o, +1 Moneta per ogni segnalino Moneta presente sulla tua plancia Nave Pirata.
|
||||
16 Recupero Seaside Azione $4 +1 Acquisto, Elimina una carta dalla tua mano. +X Monete, X è il costo della carta eliminata.
|
||||
17 Megera dei Mari Seaside Azione - Attacco $4 Ogni altro giocatore scarta la carta in cime al proprio mazzo, quindi ottiene una carta Maledizione che mette in cima al proprio mazzo.
|
||||
18 Mappa del Tesoro Seaside Azione $4 Elimina questa e un'altra copia di Mappa del Tesoro dalla tua mano. Se hai eliminato due carte Mappa del Tesoro, ottieni 4 carte Oro, mettendole in cima al tuo mazzo.
|
||||
19 Bazaar Seaside Azione $5 +1 Carta, +2 Azioni, +1 Moneta.
|
||||
20 Avventuriero Seaside Azione $5 Puoi rivelare una carta Provincia dalla tua mano. Se lo fai, ottieni una carta Oro e la metti nella tua mano. Altrimenti, guadagni una carta Argento e la metti nella tua mano.
|
||||
21 Nave Fantasma Seaside Azione - Attacco $5 +2 Carte, Ogni altro giocatore con 4 o più carte in mano mette carte dalla sua mano sopra al suo mazzo fino ad avere 3 carte in mano.
|
||||
22 Nave Mercantile Seaside Azione - Durata $5 Ora e all'inizio del tuo prossimo turno: +2 Monete.
|
||||
23 Avamposto Seaside Azione - Durata $5 Peschi solo 3 carte (invece di 5) nella fase Pulizia di questo turno. Gioca un turno extra al termine di questo. Questo non può portarti a fare più di due turni consecutivi.
|
||||
24 Stratega Seaside Azione - Durata $5 Scarta la tua mano. Se hai scartato almeno una carta in questo modo, all'inizio del tuo prossimo turno +5 Carte, +1 Acquisto, e +1 Azione.
|
||||
25 Tesoro Seaside Azione $5 +1 Carta, +1 Azione, +1 Moneta, Quando scarti questa carta dal gioco, se non hai comprato carte Vittoria, puoi mettere questa carta in cima al tuo mazzo.
|
||||
26 Molo Seaside Azione - Durata $5 Ora e all'inizio del tuo prossimo turno: +2 Carte, +1 Acquisto.
|
||||
|
||||
1 Trasmutazione Alchimia Azione $0 1P Elimina una carta dalla tua mano. Se è una carta Azione, ottieni un Ducato. Una carta Tesoro, ottieni una Trasmutazione. Una carta Vittoria, ottieni un Oro.
|
||||
2 Vigna Alchimia Vittoria $0 1P Vale 1 <VP> ogni 3 carte Azione nel tuo mazzo (per difetto).
|
||||
3 Farmacista Alchimia Azione $2 1P +1 Carta
|
||||
+1 Azione
|
||||
Rivela le prima 4 carte del tuo mazzo. Metti le carte Rame e Pozione così rivelate nella tua mano. Metti le altre carte in cima al mazzo nell'ordine che preferisci.
|
||||
4 Erborista Alchimia Azione $2 +1 Acquisto
|
||||
+1 Moneta
|
||||
Quando scarti questa carta dal gioco, puoi mettere una delle tue carte Tesoro dal gioco in cima al tuo mazzo.
|
||||
5 Divinazione Alchimia Azione - Attacco $2 1P +1 Azione
|
||||
Ogni giocatore (te incluso) rivela la carta in cima al proprio mazzo e la scarta o rimette a posto, tua scelta. Quindi rivela carte dalla cima del tuo mazzo fino a rivelarne una che non sia una carta Azione.
|
||||
Metti nella tua mano tutte le carte così rivelate.
|
||||
6 Università Alchimia Azione $2 1P +2 Azioni
|
||||
Puoi ottenere una carta Azione che costi fino a 5 Monete.
|
||||
7 Alchimista Alchimia Azione $3 1P +2 Carte
|
||||
+1 Azione
|
||||
Quando scarti questa carta dal gioco, puoi metterla in cima al tuo mazzo se hai una Pozione in gioco.
|
||||
8 Famiglio Alchimia Azione - Attacco $3 1P +1 Carta
|
||||
+1 Azione
|
||||
Ogni altro giocatore ottiene una Maledizione.
|
||||
9 Pietra Filosofale Alchimia Tesoro $3 1P Quando giochi questa carta, conta le carte nel tuo mazzo e nella tua pila degli scarti.
|
||||
Vale 1 Moneta per ogni 5 carte che hai contato (per difetto).
|
||||
10 Golem Alchimia Azione $4 1P Rivela carte dal tuo mazzo finchè non riveli due carte Azione che non siano Golem.
|
||||
Scarta le altre carte, quindi gioca le due carte Azione nell'ordine che preferisci.
|
||||
11 Pozione Alchimia Tesoroe $4 Vale 1 Pozione.
|
||||
12 Apprendista Alchimia Azione $5 +1 Azione
|
||||
Elimina una carta dalla tua mano.
|
||||
+1 Carta per ogni Moneta del suo costo.
|
||||
+2 Carte se ha una Pozione nel suo costo.
|
||||
13 Possessione Alchimia Azione $6 1P Il giocatore alla tua sinistra gioca un turno extra dopo di questo, in cui tu puoi vedere tutte le sue carte e prendere tutte le decisioni al posto suo. Ogni carta che otterrebbe in questo turno, la ottieni al posto suo; ogni sua carta che sarebbe eliminata viene messa da parte e rimessa nella sua pila degli scarti alla fine del turno.
|
||||
|
||||
1 Prestito Prosperità Tesoro $3 Vale 1 Moneta.
|
||||
Quando giochi questa carta, rivela carte dal tuo mazzo fino a rivelare una carta Tesoro. Scartala o eliminala. Scarta le altre carte.
|
||||
2 Mercante Prosperità Azione $3 +1 Acquisto
|
||||
+1 Moneta per ogni segnalino Moneta sulla plancia Mercante.
|
||||
Elimina una carta dalla tua mano.
|
||||
----------
|
||||
Preparazione: Metti un segnalino Moneta su ogni mazzetto di carte Vittoria nella Riserva. Quando una carta viene ottenuta da quel mazzetto, sposta il segnalino Moneta dal mazzetto alla plancia Mercante.
|
||||
3 Torre di Guardia Prosperità Reazione $3 Pesca fino ad avere 6 carte in mano.
|
||||
----------
|
||||
Quando ottieni una carta, puoi rivelare questa carta dalla tua mano. Se lo fai, elimina quella carta o mettila in cima al tuo mazzo.
|
||||
4 Vescovo Prosperità Azione $4 +1 Moneta
|
||||
+1 segnalino <VP>
|
||||
Elimina una carta dalla tua mano. + segnalini <VP> uguale alla metà del suo costo in Monete, per difetto.
|
||||
Ogni altro giocatore può eliminare una carta dalla sua mano.
|
||||
5 Monumento Prosperità Azione $4 +2 Monete; +1 segnalino <VP>
|
||||
6 Cava Prosperità Tesoro $4 Vale 1 Moneta.
|
||||
----------
|
||||
Mentre questa carta è in gioco, le carte Azione costano 2 Monete in meno, ma non meno di 0 Monete.
|
||||
7 Talismano Prosperità Tesoro $4 Vale 1 Moneta.
|
||||
----------
|
||||
Mentre questa carta è in gioco, quando acquisti una carta che costi 4 Monete o meno che non sia una carta Vittoria, ne ottieni una copia.
|
||||
8 Cantiere Prosperità Azione $4 +1 Carta
|
||||
+2 Azioni
|
||||
+1 Acquisto
|
||||
9 Città Prosperità Azione $5 +1 Carta
|
||||
+2 Azioni
|
||||
Se ci sono uno o più mazzetti vuoti nella Riserva, +1 Carta. Se ce ne sono due o più, +1 Moneta e +1 Acquisto.
|
||||
10 Contrabbando Prosperità Tesoro $5 Vale 3 Monete.
|
||||
+1 Acquisto
|
||||
Quando giochi questa carta, il giocatore alla tua sinistra nomina una carta. Non puoi comprare quella carta in questo turno.
|
||||
11 Contabilità Prosperità Azione $5 Cerca nel tuo mazzo degli scarti, rivela qualsiasi numero di carte Rame presenti in esso, e mettile nella tua mano.
|
||||
12 Zecca Prosperità Azione $5 Puoi rivelare una carta Tesoro dalla tua mano. Ne ottieni una copia.
|
||||
----------
|
||||
Quando compri questa carta, elimina tutte le carte Tesoro che hai in gioco.
|
||||
13 Ciarlatano Prosperità Azione - Attacco $5 +2 Monete
|
||||
Ogni altro giocatore può scartare una Maledizione. Se non lo fa, ottiene un Rame e una Maledizione.
|
||||
14 Tumulto Prosperità Azione - Attacco $5 +3 Carte
|
||||
Ogni altro giocatore rivela le prime 3 carte del suo mazzo, elimina le carte Azione e Tesoro rivelate, e rimette in cima le altre nell'ordine che preferisce.
|
||||
15 Sigillo Reale Prosperità Tesoro $5 Vale 2 Monete.
|
||||
----------
|
||||
Mentre questa carta è in gioco, quando ottieni una carta, puoi mettere quella carta in cima al tuo mazzo.
|
||||
16 Nascondiglio Prosperità Azione $5 +2 Carte
|
||||
Scarta qualsiasi numero di carte. +1 Moneta per carta scartata.
|
||||
Ogni altro giocatore può scartare 2 carte. Se lo fa, pesca una carta.
|
||||
17 Soldo Prosperità Tesoro $5 Vale 1 Moneta.
|
||||
Quando giochi questa carta, rivela carte dal tuo mazzo fino a rivelare una carta Tesoro. Scarta le altre carte, e gioca quella carta Tesoro.
|
||||
18 Scagnozzi Prosperità Azione - Attacco $6 +1 Acquisto
|
||||
+2 Monete
|
||||
Ogni altro giocatore scarta fino ad avere 3 carte nella propria mano.
|
||||
----------
|
||||
Mentre questa carta è in gioco, quando acquisti una carta, +1 segnalino <VP>.
|
||||
19 Mercato di Lusso Prosperità Azione $6 +1 Carta
|
||||
+1 Azione
|
||||
+1 Acquisto
|
||||
+2 Monete
|
||||
----------
|
||||
Non puoi comprare questa carta se hai delle carte Rame in gioco.
|
||||
20 Mucchio Prosperità Tesoro $6 Vale 2 Monete.
|
||||
----------
|
||||
Mentre questa carta è in gioco, quando acquisti una carta Vittoria ottieni una carta Oro.
|
||||
21 Banca Prosperità Tesoro $7 Vale ? Monete.
|
||||
Quando giochi questa carta, vale 1 Moneta per ogni carta Tesoro che hai in gioco (inclusa questa).
|
||||
22 Ampliamento Prosperità Azione $7 Elimina una carta dalla tua mano. Ottieni una carta che costi fino a 3 Monete in più della carta eliminata.
|
||||
23 Incastonare Prosperità Azione $7 Elimina qualsiasi numero di carte dalla tua mano. Ottieni una carta che costi esattamente la somma del costo totale della carte eliminate.
|
||||
24 Corte Prosperità Azione $7 Puoi scegliere una carta Azione dalla tua mano. Giocala tre volte.
|
||||
25 Ambulante Prosperità Azione $8 +1 Carta; +1 Azione; +2 Monete
|
||||
----------
|
||||
Durante la tua fase Acquisto, questa carta costas 2 Monete in meno per ogni carta Azione che hai in gioco, ma non meno di 0 Monete.
|
||||
26 Platino Prosperità Tesoro $9 Vale 5 Monete.
|
||||
27 Colonia Prosperità Vittoria $11 10 <VP>.
|
||||
|
||||
1 Black Market Promo Azione $3 +2 Coins, Reveal the top 3 cards of the Black Market deck. You may buy one of them immediately. Put the unbought carte on the bottom of the Black Market deck in any order.
|
||||
(Before the game, make a Black Market deck out of one copy of each Kingdom carta not in the supply.).
|
||||
2 Envoy Promo Azione $4 Reveal the top 5 cards of your deck. The player to your left chooses one for you to discard. Draw the rest.
|
||||
3 Stash Promo Tesoro $5 Worth 2 Coins. When you shuffle, you may put this anywhere in your deck.
|
||||
4 Walled Village Promo Azione $4 +1 Card
|
||||
+2 Actions
|
||||
At the start of Clean-up, if you have this and no more than one other Action carta in play, you may put this on top of your deck.
|
||||
5 Governor Promo Azione $5 +1 Action
|
||||
Choose one; you get the version in parentheses: Each player gets +1 (+3) Cards; or each player gains a Silver (Gold); or each player may trash a card from his hand and gain a card costing exactly 1 Coin (2 Coins) more.
|
||||
6 Prince Promo Azione $8 You may set this aside. If you do, set aside an Action card from your hand costing up to 4 coins. At the start of each of your turns, play that Action, setting it aside again when you discard it from play. (Stop playing it if you fail to set it aside on a turn you play it).
|
||||
|
||||
1 Rame Base Tesoro $0 Vale 1 Moneta.
|
||||
2 Argento Base Tesoro $3 Vale 2 Monete.
|
||||
3 Oro Base Tesoro $6 Vale 3 Monete.
|
||||
4 Platino Base Tesoro $9 Vale 5 Monete.
|
||||
5 Pozione Base Tesoro $4 Vale 1 Pozione.
|
||||
6 Maledizione Base Maledizione $0 -1 <VP>
|
||||
7 Tenuta Base Vittoria $2 1 <VP>
|
||||
8 Ducato Base Vittoria $5 3 <VP>
|
||||
9 Provincia Base Vittoria $8 6 <VP>
|
||||
10 Colonia Base Vittoria $11 10 <VP>
|
||||
11 Carte Eliminate Base Azione $0 Pila delle carte eliminate.
|
||||
|
||||
1 Borsa d'Oro Cornucopia Azione - Premio $0 +1 Azione
|
||||
Ottieni una carta Oro, mettendola in cima al tuo mazzo.
|
||||
(Questa carta non è nella Riserva.)
|
||||
2 Diadema Cornucopia Tesoro - Premio $0 Vale 2 Monete.
|
||||
Quando giochi questa carta, +1 Moneta per ogni Azione inutilizzata che ti rimane (Azioni, non carte Azione).
|
||||
(Questa carta non è nella Riserva.)
|
||||
3 Seguaci Cornucopia Azione - Attacco - Premio $0 +2 Carte
|
||||
Ottieni una Tenuta. Ogni altro giocatore ottiene una Maledizione e scarta fino ad avere 3 carte in mano.
|
||||
(Questa carta non è nella Riserva.)
|
||||
4 Principessa Cornucopia Azione - Premio $0 +1 Acquisto
|
||||
Mentre questa carta è in gioco, le carte costano 2 Monete in meno, ma non meno di 0 Monete.
|
||||
(Questa carta non è nella Riserva.)
|
||||
5 Destriero Fedele Cornucopia Azione - Premio $0 Scegli due: +2 Carte; o +2 Azioni; o +2 Monete; o ottieni 4 carte Argento e metti tutto il tuo mazzo nella pila degli scarti.
|
||||
(Questa carta non è nella Riserva.)
|
||||
6 Borgo Cornucopia Azione $2 +1 Carta
|
||||
+1 Azione
|
||||
Puoi scartare una carta; Se lo fai, +1 Azione.
|
||||
Puoi scartare una carta; Se lo fai, +1 Acquisto.
|
||||
7 Indovina Cornucopia Azione - Attacco $3 +2 Monete
|
||||
Ogni altro giocatore rivela carte dalla cima del proprio mazzo fino a rivelare una carta Vittoria o una Maledizione. La mette in cima al proprio mazzo e scarta le altre carte rivelate.
|
||||
8 Serraglio Cornucopia Azione $3 +1 Azione
|
||||
Rivela la tua mano.
|
||||
Se non ci sono carte con lo stesso nome, +3 Carte.
|
||||
Altrimenti, +1 Carta.
|
||||
9 Villaggio Agricolo Cornucopia Azione $4 +2 Azioni
|
||||
Rivela carte dalla cima del tuo mazzo fin quando non riveli una carta Azione o una Carta Tesoro. Metti quella carta nella tua mano e scarta le altre carte rivelate.
|
||||
10 Mercante di Cavalli Cornucopia Azione - Reazione $4 +1 Acquisto
|
||||
+3 Monete
|
||||
Scarta 2 Carte
|
||||
Quando un altro giocatore usa una carta Attacco, puoi mettere da parte questa carta dalla tua mano. Se lo fai, all'inizio del tuo prossimo turno +1 Carta e rimetti nella tua mano il Mercante di Cavalli.
|
||||
11 Rifacimento Cornucopia Azione $4 Fallo due volte: Elimina una carta della tua mano, quindi ottiene una carta che costi esattamente 1 Moneta in più della carta eliminata.
|
||||
12 Torneo Cornucopia Azione $4 +1 Azione
|
||||
Ogni giocatore può rivelare una carta Provincia dalla sua mano. Se tu lo fai, scartala ed ottieni un Premio (dal mazzetto Premio) o un Ducato, mettendo la carta ottenuta in cima al tuo mazzo. Se nessun'altro rivela una carta Provincia, +1 Carta +1 Moneta.
|
||||
13 Giovane Strega Cornucopia Azione - Attacco $4 +2 Carte
|
||||
Scarta 2 carte. Ogni altro giocatore può rivelare una carta Scongiuro dalla sua mano.
|
||||
Se non lo fa, ottiene una Maledizione.
|
||||
Preparazione: Aggiungi un mazzetto extra di carte Regno che costi 2 o 3 Monete alla Riserva. Le carte da quel mazzetto sono carte Scongiuro.
|
||||
14 Mietitura Cornucopia Azione $5 Rivela le prima 4 carte del tuo mazzo, quindi scartele. +1 Moneta per ogni carta dal nome differente rivelata.
|
||||
15 Cornucopia Cornucopia Tesoro $5 Vale 0 Monete
|
||||
Quando giochi questa carta, ottieni una carta che costi fino a 1 Moneta per ogni carta di nome differente che tu abbia in gioco, inclusa questa. Se usi Cornucopia per ottenere una carta Vittoria, elimina Cornucopia.
|
||||
16 Battuta di Caccia Cornucopia Azione $5 +1 Carta
|
||||
+1 Azione
|
||||
Rivela la tua mano. Rivela carte dalla cima del tuo mazzo fino a rivelare una carta che non sia un duplicato di nessuna delle tua carte in mano, metti in mano quella carta e scarta le altre carte rivelate.
|
||||
17 Giullare Cornucopia Azione - Attacco $5 +2 Monete
|
||||
Ogni altro giocatore scarta la carta in cima al proprio mazzo. Se è una carta Vittoria ottiene una Maledizione. Altrimenti, ottiene una copia della carta scartata o la ottieni tu, a tua scelta.
|
||||
18 Mercatino Cornucopia Vittoria $6 Vale 2 <VP> per ogni 5 carte dal nome diverso nel tuo mazzo (per difetto)
|
||||
|
||||
1 Incrocio Nuovi Orizzonti Azione $2 Rivela la tua mano.
|
||||
+1 Carta per ogni carta Vittoria rivelata. Se questa è la prima volta che giochi una carta Incrocio in questo turno, +3 Azioni.
|
||||
2 Duchessa Nuovi Orizzonti Azione $2 +2 Monete
|
||||
Ogni giocatore (te incluso) guarda la prima carta del suo mazzo, e sceglie se scartarla o lasciarla al suo posto.
|
||||
______________________
|
||||
In partite che usano questa carta, quando ottieni un Ducato puoi ottenere una Duchessa.
|
||||
3 Oro dello Stolto Nuovi Orizzonti Tesoro - Reazione $2 Se questa è la prima volta che giochi un Oro dello Stolto in questo turno, questa carta vale 1 Moneta, altrimenti vale 4 Monete.
|
||||
______________________
|
||||
Quando un altro giocatore ottiene una Provincia, puoi eliminare questa carta dalla tua mano. Se lo fai, ottieni un Oro, mettendolo in cima al tuo mazzo.
|
||||
4 Sviluppo Nuovi Orizzonti Azione $3 Elimina una carta dalla tua mano. Ottieni una carta che costi esattamente una Moneta più essa e una carta che costi esattamente 1 Moneta meno di essa, nell'ordine che preferisci, mettendole poi in cima al tuo mazzo.
|
||||
5 Oasi Nuovi Orizzonti Azione $3 +1 Carta
|
||||
+1 Azione
|
||||
+1 Monete
|
||||
Scarta una carta.
|
||||
6 Oracolo Nuovi Orizzonti Azione - Attacco $3 Ogni giocatore (te incluso) rivela le prima carte del proprio mazzo, e tu scegli se scartarle o lasciarle sul mazzo nell'ordine che il proprietario preferisce.
|
||||
+2 Carte
|
||||
7 Macchinazione Nuovi Orizzonti Azione $3 +1 Carta
|
||||
+1 Azione
|
||||
All'inizio della fase di Pulizia in questo turno, puoi scegliere una carta Azione che hai in gioco. Se la scarti dal gioco in questo turno, mettila sul tuo mazzo.
|
||||
8 Galleria Nuovi Orizzonti Vittoria - Reazione $3 2 <VP>
|
||||
______________________
|
||||
Quando scarti questa carta in qualsiasi momento che non sia la fase di Pulizia, puoi rivelarla. Se lo fai, ottieni un Oro.
|
||||
9 Tuttofare Nuovi Orizzonti Azione $4 Ottieni un Argento.
|
||||
Guarda la prima carta del tuo mazzo; scartala o rimettila al suo posto.
|
||||
Pesca fino ad avere 5 carte in mano.
|
||||
Puoi eliminare una carta dalla tua mano che non sia una carta Tesoro.
|
||||
10 Ladro Gentiluomo Nuovi Orizzonti Azione - Attacco $4 +1 Moneta
|
||||
Quando acquisti o giochi questa carta, ogni altro giocatore rivela le prime 2 carte del suo mazzo, elimina una carta Argento o Oro rivelata di tua scelta, e scarta il resto. Se non ha rivelato una carta Tesoro, ottiene una carta Rame. Tu ottieni le carte eliminate.
|
||||
11 Campo Nomadi Nuovi Orizzonti Azione $4 +1 Acquisto
|
||||
+2 Monete
|
||||
______________________
|
||||
Quando ottieni questa carta mettila in cima al tuo mazzo.
|
||||
12 Via della Seta Nuovi Orizzonti Vittoria $4 Vale 1 <VP> ogni 4 carte Vittoria nel tuo mazzo (per difetto).
|
||||
13 Mercante di Spezia Nuovi Orizzonti Azione $4 Puoi eliminare una carta Tesoro dalla tua mano. Se lo fai, scegli:
|
||||
+2 Carte e +1 Azione;
|
||||
o +2 Monete e +1 Acquisto.
|
||||
14 Commerciante Nuovi Orizzonti Azione - Reazione $4 Elimina una carta dalla tua mano. Guadagni tante carte Argento quanto è il suo costo in Monete.
|
||||
______________________
|
||||
Quando ottieni una carta, puoi rivelare questa carta dalla tua mano. Se lo fai, guadagni un Argento al posto della carta che dovresti ottenere.
|
||||
15 Forziere Nuovi Orizzonti Tesoro $5 Vale 3 monete
|
||||
______________________
|
||||
Quando ottieni questa carta, ottieni 2 carte Rame.
|
||||
16 Cartografo Nuovi Orizzonti Azione $5 +1 Carta
|
||||
+1 Azione
|
||||
Guarda le prima 4 carte del tuo mazzo. Scartane un qualsiasi numero. Metti il resto delle carte in cima al tuo mazzo nell'ordine che preferisci.
|
||||
17 Diplomatico Nuovi Orizzonti Azione $5 +5 Carte
|
||||
Scarta 3 carte.
|
||||
______________________
|
||||
Quando ottieni questa carta, ogni altro giocatore ottiene una carta Argento.
|
||||
18 Contrattazione Nuovi Orizzonti Azione $5 +2 Monete
|
||||
______________________
|
||||
Mentre questa carta è in gioco, quando acquisti una carta ottieni anche una carta che costi meno di quella acquistata e che non sia una carta Vittoria.
|
||||
19 Strada Maestra Nuovi Orizzonti Azione $5 +1 Carta
|
||||
+1 Azione
|
||||
______________________
|
||||
Mentre questa carta è in gioco, le carte costano una Moneta in mano, ma non meno di 0 Monete.
|
||||
20 Infame Profitto Nuovi Orizzonti Tesoro $5 Vale 1 Coin
|
||||
Quando giochi questa carta puoi ottenere una carta Rame, mettendola nella tua mano.
|
||||
______________________
|
||||
Quando ottieni questa carta, ogni altro giocatore ottiene una Maledizione.
|
||||
21 Locanda Nuovi Orizzonti Azione $5 +2 Carte
|
||||
+2 Azioni
|
||||
Scarta 2 carte.
|
||||
______________________
|
||||
Quando ottieni questa carta, cerca nel tuo mazzo degli scarti (inclusa questa carta), rivela qualsiasi numero di carte Azione da esso, e rimischiale nel tuo mazzo.
|
||||
22 Mandarino Nuovi Orizzonti Azione $5 +3 Monete
|
||||
Metti una carta dalla tua mano in cima al tuo mazzo.
|
||||
----------------------
|
||||
Quando ottieni questa carta, metti tutte le carte Tesoro che hai in gioco in cima al tuo mazzo nell'ordine che preferisci.
|
||||
23 Margravio Nuovi Orizzonti Azione - Attacco $5 +3 Carte
|
||||
+1 Acquisto
|
||||
Ogni altro giocatore pesca una carta, quindi scarta fino ad avere 3 carte nella sua mano.
|
||||
24 Stalla Nuovi Orizzonti Azione $5 Puoi scartare una carta Tesoro. Se lo fai, +3 Carte e +1 Azione.
|
||||
25 Villaggio di Frontiera Nuovi Orizzonti Azione $6 +1 Carta
|
||||
+2 Azione
|
||||
----------------------
|
||||
Quando ottieni questa carta, ottieni anche una carta che costi meno di questa carta.
|
||||
26 Terra Coltivata Nuovi Orizzonti Vittoria $6 2 <VP>
|
||||
----------
|
||||
Quando acquisti questa carta, elimina una carta dalla tua mano. Ottieni una carta che costi esattamente 2 Monete in più della carta eliminata.
|
||||
|
||||
1 Ruins Dark Ages Azione - Ruins $0 Abandoned Mine: +1 Coin
|
||||
Ruined Library: +1 Carta
|
||||
Ruined Marked: :1 Acquisto
|
||||
Ruined Village: +1 Azione
|
||||
Survivors: Look at the top 2 carte of your deck. Discarta them or put them back in any order.
|
||||
2 Madman Dark Ages Azione $0 +2 Aziones
|
||||
Return this to the Madman pile. If you do, +1 Carta per carta in your hand.
|
||||
(This carta is not in the supply.)
|
||||
3 Spoils Dark Ages Tesoro $0 Worth 3 Monete
|
||||
When you play this, return it to the Spoils pile.
|
||||
(This is not in the Supply.)
|
||||
4 Hovel Dark Ages Reazione - Shelter $1 When you buy a Vittoria carta, you may trash this from your hand.
|
||||
5 Necropolis Dark Ages Azione - Shelter $1 +2 Aziones
|
||||
6 Overgrown Estate Dark Ages Vittoria - Shelter $1 0 <VP>
|
||||
______________________
|
||||
When you trash this, +1 Carta.
|
||||
7 Poor House Dark Ages Azione $1 +4 Monete
|
||||
Reveal your hand. -1 Coin per Tesoro carta in your hand, to a minimum of 0 Monete.
|
||||
8 Squire Dark Ages Azione $2 +1 Coin
|
||||
Choose one: +2 Aziones; or +2 Acquistos; or gain a Silver.
|
||||
______________________
|
||||
When you trash this, gain an Azione carta.
|
||||
9 Vagrant Dark Ages Azione $2 +1 Carta, +1 Azione
|
||||
Reveal the top carta of your deck. If it's a Curse, Ruins, Shelter, or Vittoria carta, put it into your hand.
|
||||
10 Hermit Dark Ages Azione $3 Look through your discarta pile. You may trash a carta from your discarta pile or hand that is not a Tesoro. Gain a carta costing up to 3 Monete.
|
||||
When you discarta this from play, if you did not buy any carte this turn, trash this and gain a Madman from the Madman pile.
|
||||
11 Sage Dark Ages Azione $3 +1 Azione
|
||||
Reveal carte from the top of your deck until you reveal one costing 3 Monete or more. Put that carta into your hand and discarta the rest.
|
||||
12 Feodum Dark Ages Vittoria $4 Worth 1 <VP> for every 3 Silvers in your deck (round down).
|
||||
______________________
|
||||
When you trash this, gain 3 Silvers.
|
||||
13 Fortress Dark Ages Azione $4 +1 Carta, +2 Aziones
|
||||
______________________
|
||||
When you trash this, put it into your hand.
|
||||
14 Ironmonger Dark Ages Azione $4 +1 Carta, +1 Azione
|
||||
Reveal the top carta of your deck; you may discarta it. Either way, if it is an…
|
||||
Azione carta, +1 Azione
|
||||
Tesoro carta, +1 Coin
|
||||
Vittoria carta, +1 Carta
|
||||
15 Procession Dark Ages Azione $4 You may play an Azione carta from your hand twice. Trash it. Gain an Azione carta costing exactly 1 Coin more than it.
|
||||
16 Rats Dark Ages Azione $4 +1 Carta, +1 Azione
|
||||
Gain a Rats. Trash a carta from your hand other than a Rats (or reveal a hand of all Rats).
|
||||
______________________
|
||||
When you tash this, +1 Carta.
|
||||
17 Band of Misfits Dark Ages Azione $5 Play this as if it were an Azione carta in the Supply costing less than it that you choose.
|
||||
This is that carta until it leaves play.
|
||||
18 Bandit Camp Dark Ages Azione $5 +1 Carta, +2 Aziones
|
||||
Gain a Spoils from the Spoils pile.
|
||||
19 Count Dark Ages Azione $5 Choose one: Discarta 2 carte; or put a carta from your hand on top of your deck; or gain a Copper.
|
||||
Choose one: +3 Monete; or trash your hand; or gain a Duchy.
|
||||
20 Cultist Dark Ages Azione - Attacco - Looter $5 +2 Cartas
|
||||
Each other player gains a Ruins. You may play a Cultist from your hand.
|
||||
______________________
|
||||
When you trash this, +3 Cartas.
|
||||
21 Graverobber Dark Ages Azione $5 Choose one: Gain a carta from the trash costing from 3 Monete to 6 Monete, putting it on top of your deck; or trash an Azione carta from your hand and gain a carta costing up to 3 Monete more than it.
|
||||
22 Pillage Dark Ages Azione - Attacco $5 Trash this. Each other player with 5 or more carte in hand reveals his hand and discarte a carta that you choose.
|
||||
Gain 2 Spoils from the Spoils pile.
|
||||
23 Scavenger Dark Ages Azione $5 +1 Monete
|
||||
You may put your deck into your discarta pile. Look through your discarta pile and put one carta from it on top of your deck.
|
||||
24 Altar Dark Ages Azione $6 Trash a carta from your hand. Gain a carta costing up to 5 Monete.
|
||||
29 Armory Dark Ages Azione $4 Gain a carta costing up to 4 Monete,putting it on top of your deck.
|
||||
25 Beggar Dark Ages Azione - Reazione $2 Gain 3 Coppers, putting them into your hand.
|
||||
______________________
|
||||
When another player plays an Attacco carta, you may discarta this.
|
||||
If you do, gain two Silvers, putting one on top of your deck.
|
||||
26 Catacombs Dark Ages Azione $5 Look at the top 3 carte of your deck.
|
||||
Choose one: Put them into your hand;
|
||||
or discarta them and +3 Cartas.
|
||||
______________________
|
||||
When you trash this, gain a cheaper carta.
|
||||
27 Counterfeit Dark Ages Tesoro $5 Worth 1 Coin
|
||||
+1 Acquisto
|
||||
When you play this, you may play a Tesoro from your hand twice. If you do, trash that Tesoro
|
||||
28 Death Cart Dark Ages Azione - Looter $4 +5 Monete
|
||||
You may trash an Azione carta from your hand. If you don’t, trash this.
|
||||
______________________
|
||||
When you gain this, gain 2 Ruins.
|
||||
29 Forager Dark Ages Azione $3 +1 Azione
|
||||
+1 Acquisto
|
||||
Trash a carta from your hand.
|
||||
+1 Coin per differently named Tesoro
|
||||
in the trash.
|
||||
30 Junk Dealer Dark Ages Azione $5 +1 Carta
|
||||
+1 Azione
|
||||
+1 Coin
|
||||
Trash a carta from your hand.
|
||||
31 Knights Dark Ages Azione $5 This is a pile in which each carta is different. There is the same basic ability on each carta, but also another ability unique to that carta in the pile, and they all have different names. Shuffle the Knights pile before playing with it, keeping it face down except for the top one, which is the only carta that can be gained from the pile. See Additional Rules for Dark Ages and Preparation. Follow the rules on Knights in order from top to bottom; Sir Michael causes players to discarta before it trashes carte.
|
||||
32 Marauder Dark Ages Azione $4 Gain a Spoils from the Spoils pile.
|
||||
Each other player gains a Ruins.
|
||||
33 Market Square Dark Ages Azione - Reazione $3 +1 Carta
|
||||
+1 Azione
|
||||
+1 Acquisto
|
||||
______________________
|
||||
When one of your carte is trashed,
|
||||
you may discarta this from your
|
||||
hand. If you do, gain a Gold.
|
||||
34 Rebuild Dark Ages Azione $5 + 1Azione
|
||||
Name a carta. Reveal carte from the top of your deck until you reveal a Vittoria carta that is not the named carta. Discarta the other carte. Trash the Vittoria carta and gain a Vittoria carta costing up to 3 Monete more than it.
|
||||
35 Rogue Dark Ages Azione - Attacco $5 + 2 Monete
|
||||
If there are any carte in the trash costing from 3 Monete to 6 Monete, gain one of them. Otherwise, each other player reveals the top 2 carte of his deck, trashes one of them costing from 3 Monete to 6 Monete, and discarte the rest.
|
||||
36 Storeroom Dark Ages Azione $3 + 1 Acquisto
|
||||
Discarta any number of carte.
|
||||
+1 Carta per carta discartaed.
|
||||
Discarta any number of carte.
|
||||
+ 1 Monete per carta discartaed the second time.
|
||||
37 Urchin Dark Ages Azione - Attacco $3 +1 Carta
|
||||
+1 Azione
|
||||
Each other player discarte down to 4 carte in hand.
|
||||
______________________
|
||||
When you play another Attacco carta with this in play, you may trash this.
|
||||
If you do, gain a Mercenary from the Mercenary pile.
|
||||
38 Wandering Minstrel Dark Ages Azione $4 +1 Carta
|
||||
+2 Aziones
|
||||
Reveal the top 3 carte of your deck.
|
||||
Put the Aziones back on top in any order and discarta the rest.
|
||||
39 Hunting Grounds Dark Ages Azione $6 + 4 Cartas
|
||||
______________________
|
||||
When you trash this,
|
||||
gain a Duchy or 3 Estates.
|
||||
40 Mercenary Dark Ages Azione - Attacco $0 You may trash 2 carte from your hand.
|
||||
If you do, +2 Cartas, + 2 Monete,
|
||||
and each other player discarte down to 3 carte in hand.
|
||||
(This is not in the Supply.)
|
||||
41 Mystic Dark Ages Azione $5 +1Azione
|
||||
+ 2 Monete
|
||||
Name a carta.
|
||||
Reveal the top carta of your deck.
|
||||
If it’s the named carta, put it into your hand.
|
||||
42 Shelters Dark Ages Extras Azione - Shelter $1 Hovel: When you buy a Vittoria carta, you may trash this from your hand.
|
||||
Necropolis: +2 Aziones
|
||||
Overgrown Estate: 0 <VP>; when you trash this, +1 Carta.
|
||||
43 Urchin / Mercenary Dark Ages Extras Azione $3 Urchin: When you play this, you draw a carta and get +1 Azione, then each other player discarte down to 4 carte in hand. Players who already have 4 or fewer carte in hand do not do anything. While Urchin is in play, when you play another Attacco carta, before resolving it, you may trash the Urchin. If you do, you gain a Mercenary. If there are no Mercenaries left you do not gain one. If you play the same Urchin twice in one turn, such as via Procession, that does not let you trash it for a Mercenary. If you play two different Urchins however, playing the second one will let you trash the first one.
|
||||
44 Hermit / Madman Dark Ages Extras Azione $3 Hermit: When you play this, look through your discarta pile, and then you may choose to trash a carta that is not a Tesoro, from either your hand or your discarta pile. You do not have to trash a carta and cannot trash Tesoros. A carta with multiple types, one of which is Tesoro (such as Harem from Intrigo), is a Tesoro. After trashing or not, you gain a carta costing up to 3 Monete. The carta you gain comes from the Supply and is put into your discarta pile. Gaining a carta is mandatory if it is possible. Then, when you discarta Hermit from play - normally, in Clean-up, after playing it in your Azione phase - if you did not buy any carte this turn, you trash Hermit and gain a Madman. It does not matter whether or not you gained carte other ways, only whether or not you bought a carta. If there are no Madman carte left, you do not gain one. If Hermit is not discartaed from play during Clean-up - for example, if you put it on your deck with Scheme (from Nuovi Orizzonti) - then the ability that trashes it will not trigger.
|
||||
|
||||
1 Advisor Guilds Azione $4 +1 Azione
|
||||
Reveal the top 3 carte of your deck. The player to your left chooses one of them. Discarta that carta. Put the other carte into your hand.
|
||||
2 Baker Guilds Azione $5 +1 Carta
|
||||
+1 Azione
|
||||
Take a Coin token.
|
||||
______________________
|
||||
Setup: Each player takes a Coin token.
|
||||
3 Butcher Guilds Azione $5 Take two Coin tokens. You may trash a carta from your hand and then pay any number of Coin tokens. If you did trash a carta, gain a carta with a cost of up to the cost of the trashed carta plus the number of Coin tokens you paid.
|
||||
4 Candlestick Maker Guilds Azione $2 +1 Azione
|
||||
+1 Acquisto
|
||||
Take a Coin token.
|
||||
5 Doctor Guilds Azione $3 Name a carta. Reveal the top 3 carte of your deck. Trash the matches. Put the rest back on top in any order.
|
||||
______________________
|
||||
When you buy this, you may overpay for it. For each 1 Coin you overpaid, look at the top carta of your deck; trash it, discarta it, or put it back.
|
||||
6 Herald Guilds Azione $4 +1 Carta
|
||||
+1 Azione
|
||||
Reveal the top carta of your deck. If it is an Azione, play it.
|
||||
______________________
|
||||
When you buy this, you may overpay for it. For each 1 Coin you overpaid, look through your discarta pile and put a carta from it on top of your deck.
|
||||
7 Journeyman Guilds Azione $5 Name a carta. Reveal carte from the top of your deck until you reveal 3 carte that are not the named carta. Put those carte into your hand and discarta the rest.
|
||||
8 Masterpiece Guilds Tesoro $3 Worth 1 Coin.
|
||||
______________________
|
||||
When you buy this, you may overpay for it. If you do, gain a Silver per 1 Coin you overpaid.
|
||||
9 Merchant Guild Guilds Azione $5 +1 Acquisto
|
||||
+1 Coin
|
||||
______________________
|
||||
While this is in play, when you buy a carta, take a Coin token.
|
||||
10 Plaza Guilds Azione $4 +1 Carta
|
||||
+2 Aziones
|
||||
You may discarta a Tesoro carta. If you do, take a Coin token.
|
||||
11 Soothsayer Guilds Azione - Attacco $5 Gain a Gold. Each other player gains a Curse. Each player who did draws a carta.
|
||||
12 Stonemason Guilds Azione $2 Trash a carta from your hand. Gain 2 carte each costing less than it.
|
||||
______________________
|
||||
When you buy this, you may overpay for it. If you do, gain 2 Azione carte each costing the amount you overpaid.
|
||||
13 Taxman Guilds Azione - Attacco $4 You may trash a Tesoro from your hand. Each other player with 5 or more carte in hand discarte a copy of it (or reveals a hand without it). Gain a Tesoro carta costing up to 3 Monete more than the trashed carta, putting it on top of your deck.
|
||||
7
card_db/it/mapping.json
Normal file
7
card_db/it/mapping.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"alchimia": "alchemy",
|
||||
"intrigo": "intrigue",
|
||||
"nuovi orizzonti": "hinterlands",
|
||||
"prosperità": "prosperity"
|
||||
}
|
||||
|
||||
@ -1,15 +0,0 @@
|
||||
"Azione": "Action"
|
||||
"Vittoria": "Victory"
|
||||
"Attacco": "Attack"
|
||||
"Tesoro": "Treasure"
|
||||
"Reazione": "Reaction"
|
||||
"Durata": "Duration"
|
||||
"Premio": "Prize"
|
||||
"Looter": "Looter"
|
||||
"Shelter": "Shelter"
|
||||
"Ruins": "Ruins"
|
||||
"Maledizione": "Curse"
|
||||
"alchimia": "alchemy"
|
||||
"intrigo": "intrigue"
|
||||
"nuovi orizzonti": "hinterlands"
|
||||
"prosperità": "prosperity"
|
||||
33
convert_csv.py
Normal file
33
convert_csv.py
Normal file
@ -0,0 +1,33 @@
|
||||
# coding=utf-8
|
||||
import csv
|
||||
import sys
|
||||
import json
|
||||
import chardet
|
||||
|
||||
converted = []
|
||||
|
||||
typemap = {'Aktion': 'Action',
|
||||
'Geld': 'Treasure',
|
||||
'Fluch': 'Curse',
|
||||
'Punkte': 'Victory',
|
||||
'Reaktion': 'Reaction',
|
||||
'Angriff': 'Attack',
|
||||
'Dauer': 'Duration'}
|
||||
|
||||
with open(sys.argv[1], 'U') as csvfile:
|
||||
reader = csv.DictReader(csvfile)
|
||||
for row in reader:
|
||||
if not ''.join(row.itervalues()):
|
||||
continue
|
||||
# row = {k: v.decode('ISO-8859-2').encode('utf-8') if type(v) == str else v for k, v in row.iteritems()}
|
||||
print chardet.detect(row['Kartentext'])
|
||||
print row['Kartentext']
|
||||
converted_row = {'name': row['Kartenname'],
|
||||
'cost': row['Kosten'],
|
||||
'cardset': row['Edition'],
|
||||
'description': row['Kartentext'],
|
||||
'extra': row['Lange Erklärung'],
|
||||
'types': [typemap[t.strip()] for t in row['Typ'].split('/')],
|
||||
'potcost': row.get('potcost', 0)}
|
||||
converted.append(converted_row)
|
||||
json.dump(converted, open(sys.argv[2], 'wb'), indent=True)
|
||||
@ -1,515 +0,0 @@
|
||||
#!python
|
||||
"""Bootstrap distribute installation
|
||||
|
||||
If you want to use setuptools in your package's setup.py, just include this
|
||||
file in the same directory with it, and add this to the top of your setup.py::
|
||||
|
||||
from distribute_setup import use_setuptools
|
||||
use_setuptools()
|
||||
|
||||
If you want to require a specific version of setuptools, set a download
|
||||
mirror, or use an alternate download directory, you can do so by supplying
|
||||
the appropriate options to ``use_setuptools()``.
|
||||
|
||||
This file can also be run as a script to install or upgrade setuptools.
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import fnmatch
|
||||
import tempfile
|
||||
import tarfile
|
||||
from distutils import log
|
||||
|
||||
try:
|
||||
from site import USER_SITE
|
||||
except ImportError:
|
||||
USER_SITE = None
|
||||
|
||||
try:
|
||||
import subprocess
|
||||
|
||||
def _python_cmd(*args):
|
||||
args = (sys.executable,) + args
|
||||
return subprocess.call(args) == 0
|
||||
|
||||
except ImportError:
|
||||
# will be used for python 2.3
|
||||
def _python_cmd(*args):
|
||||
args = (sys.executable,) + args
|
||||
# quoting arguments if windows
|
||||
if sys.platform == 'win32':
|
||||
def quote(arg):
|
||||
if ' ' in arg:
|
||||
return '"%s"' % arg
|
||||
return arg
|
||||
args = [quote(arg) for arg in args]
|
||||
return os.spawnl(os.P_WAIT, sys.executable, *args) == 0
|
||||
|
||||
DEFAULT_VERSION = "0.6.28"
|
||||
DEFAULT_URL = "http://pypi.python.org/packages/source/d/distribute/"
|
||||
SETUPTOOLS_FAKED_VERSION = "0.6c11"
|
||||
|
||||
SETUPTOOLS_PKG_INFO = """\
|
||||
Metadata-Version: 1.0
|
||||
Name: setuptools
|
||||
Version: %s
|
||||
Summary: xxxx
|
||||
Home-page: xxx
|
||||
Author: xxx
|
||||
Author-email: xxx
|
||||
License: xxx
|
||||
Description: xxx
|
||||
""" % SETUPTOOLS_FAKED_VERSION
|
||||
|
||||
|
||||
def _install(tarball, install_args=()):
|
||||
# extracting the tarball
|
||||
tmpdir = tempfile.mkdtemp()
|
||||
log.warn('Extracting in %s', tmpdir)
|
||||
old_wd = os.getcwd()
|
||||
try:
|
||||
os.chdir(tmpdir)
|
||||
tar = tarfile.open(tarball)
|
||||
_extractall(tar)
|
||||
tar.close()
|
||||
|
||||
# going in the directory
|
||||
subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
|
||||
os.chdir(subdir)
|
||||
log.warn('Now working in %s', subdir)
|
||||
|
||||
# installing
|
||||
log.warn('Installing Distribute')
|
||||
if not _python_cmd('setup.py', 'install', *install_args):
|
||||
log.warn('Something went wrong during the installation.')
|
||||
log.warn('See the error message above.')
|
||||
finally:
|
||||
os.chdir(old_wd)
|
||||
|
||||
|
||||
def _build_egg(egg, tarball, to_dir):
|
||||
# extracting the tarball
|
||||
tmpdir = tempfile.mkdtemp()
|
||||
log.warn('Extracting in %s', tmpdir)
|
||||
old_wd = os.getcwd()
|
||||
try:
|
||||
os.chdir(tmpdir)
|
||||
tar = tarfile.open(tarball)
|
||||
_extractall(tar)
|
||||
tar.close()
|
||||
|
||||
# going in the directory
|
||||
subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
|
||||
os.chdir(subdir)
|
||||
log.warn('Now working in %s', subdir)
|
||||
|
||||
# building an egg
|
||||
log.warn('Building a Distribute egg in %s', to_dir)
|
||||
_python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir)
|
||||
|
||||
finally:
|
||||
os.chdir(old_wd)
|
||||
# returning the result
|
||||
log.warn(egg)
|
||||
if not os.path.exists(egg):
|
||||
raise IOError('Could not build the egg.')
|
||||
|
||||
|
||||
def _do_download(version, download_base, to_dir, download_delay):
|
||||
egg = os.path.join(to_dir, 'distribute-%s-py%d.%d.egg'
|
||||
% (version, sys.version_info[0], sys.version_info[1]))
|
||||
if not os.path.exists(egg):
|
||||
tarball = download_setuptools(version, download_base,
|
||||
to_dir, download_delay)
|
||||
_build_egg(egg, tarball, to_dir)
|
||||
sys.path.insert(0, egg)
|
||||
import setuptools
|
||||
setuptools.bootstrap_install_from = egg
|
||||
|
||||
|
||||
def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
|
||||
to_dir=os.curdir, download_delay=15, no_fake=True):
|
||||
# making sure we use the absolute path
|
||||
to_dir = os.path.abspath(to_dir)
|
||||
was_imported = 'pkg_resources' in sys.modules or \
|
||||
'setuptools' in sys.modules
|
||||
try:
|
||||
try:
|
||||
import pkg_resources
|
||||
if not hasattr(pkg_resources, '_distribute'):
|
||||
if not no_fake:
|
||||
_fake_setuptools()
|
||||
raise ImportError
|
||||
except ImportError:
|
||||
return _do_download(version, download_base, to_dir, download_delay)
|
||||
try:
|
||||
pkg_resources.require("distribute>=" + version)
|
||||
return
|
||||
except pkg_resources.VersionConflict:
|
||||
e = sys.exc_info()[1]
|
||||
if was_imported:
|
||||
sys.stderr.write(
|
||||
"The required version of distribute (>=%s) is not available,\n"
|
||||
"and can't be installed while this script is running. Please\n"
|
||||
"install a more recent version first, using\n"
|
||||
"'easy_install -U distribute'."
|
||||
"\n\n(Currently using %r)\n" % (version, e.args[0]))
|
||||
sys.exit(2)
|
||||
else:
|
||||
del pkg_resources, sys.modules['pkg_resources'] # reload ok
|
||||
return _do_download(version, download_base, to_dir,
|
||||
download_delay)
|
||||
except pkg_resources.DistributionNotFound:
|
||||
return _do_download(version, download_base, to_dir,
|
||||
download_delay)
|
||||
finally:
|
||||
if not no_fake:
|
||||
_create_fake_setuptools_pkg_info(to_dir)
|
||||
|
||||
|
||||
def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
|
||||
to_dir=os.curdir, delay=15):
|
||||
"""Download distribute from a specified location and return its filename
|
||||
|
||||
`version` should be a valid distribute version number that is available
|
||||
as an egg for download under the `download_base` URL (which should end
|
||||
with a '/'). `to_dir` is the directory where the egg will be downloaded.
|
||||
`delay` is the number of seconds to pause before an actual download
|
||||
attempt.
|
||||
"""
|
||||
# making sure we use the absolute path
|
||||
to_dir = os.path.abspath(to_dir)
|
||||
try:
|
||||
from urllib.request import urlopen
|
||||
except ImportError:
|
||||
from urllib2 import urlopen
|
||||
tgz_name = "distribute-%s.tar.gz" % version
|
||||
url = download_base + tgz_name
|
||||
saveto = os.path.join(to_dir, tgz_name)
|
||||
src = dst = None
|
||||
if not os.path.exists(saveto): # Avoid repeated downloads
|
||||
try:
|
||||
log.warn("Downloading %s", url)
|
||||
src = urlopen(url)
|
||||
# Read/write all in one block, so we don't create a corrupt file
|
||||
# if the download is interrupted.
|
||||
data = src.read()
|
||||
dst = open(saveto, "wb")
|
||||
dst.write(data)
|
||||
finally:
|
||||
if src:
|
||||
src.close()
|
||||
if dst:
|
||||
dst.close()
|
||||
return os.path.realpath(saveto)
|
||||
|
||||
|
||||
def _no_sandbox(function):
|
||||
def __no_sandbox(*args, **kw):
|
||||
try:
|
||||
from setuptools.sandbox import DirectorySandbox
|
||||
if not hasattr(DirectorySandbox, '_old'):
|
||||
def violation(*args):
|
||||
pass
|
||||
DirectorySandbox._old = DirectorySandbox._violation
|
||||
DirectorySandbox._violation = violation
|
||||
patched = True
|
||||
else:
|
||||
patched = False
|
||||
except ImportError:
|
||||
patched = False
|
||||
|
||||
try:
|
||||
return function(*args, **kw)
|
||||
finally:
|
||||
if patched:
|
||||
DirectorySandbox._violation = DirectorySandbox._old
|
||||
del DirectorySandbox._old
|
||||
|
||||
return __no_sandbox
|
||||
|
||||
|
||||
def _patch_file(path, content):
|
||||
"""Will backup the file then patch it"""
|
||||
existing_content = open(path).read()
|
||||
if existing_content == content:
|
||||
# already patched
|
||||
log.warn('Already patched.')
|
||||
return False
|
||||
log.warn('Patching...')
|
||||
_rename_path(path)
|
||||
f = open(path, 'w')
|
||||
try:
|
||||
f.write(content)
|
||||
finally:
|
||||
f.close()
|
||||
return True
|
||||
|
||||
_patch_file = _no_sandbox(_patch_file)
|
||||
|
||||
|
||||
def _same_content(path, content):
|
||||
return open(path).read() == content
|
||||
|
||||
|
||||
def _rename_path(path):
|
||||
new_name = path + '.OLD.%s' % time.time()
|
||||
log.warn('Renaming %s into %s', path, new_name)
|
||||
os.rename(path, new_name)
|
||||
return new_name
|
||||
|
||||
|
||||
def _remove_flat_installation(placeholder):
|
||||
if not os.path.isdir(placeholder):
|
||||
log.warn('Unkown installation at %s', placeholder)
|
||||
return False
|
||||
found = False
|
||||
for file in os.listdir(placeholder):
|
||||
if fnmatch.fnmatch(file, 'setuptools*.egg-info'):
|
||||
found = True
|
||||
break
|
||||
if not found:
|
||||
log.warn('Could not locate setuptools*.egg-info')
|
||||
return
|
||||
|
||||
log.warn('Removing elements out of the way...')
|
||||
pkg_info = os.path.join(placeholder, file)
|
||||
if os.path.isdir(pkg_info):
|
||||
patched = _patch_egg_dir(pkg_info)
|
||||
else:
|
||||
patched = _patch_file(pkg_info, SETUPTOOLS_PKG_INFO)
|
||||
|
||||
if not patched:
|
||||
log.warn('%s already patched.', pkg_info)
|
||||
return False
|
||||
# now let's move the files out of the way
|
||||
for element in ('setuptools', 'pkg_resources.py', 'site.py'):
|
||||
element = os.path.join(placeholder, element)
|
||||
if os.path.exists(element):
|
||||
_rename_path(element)
|
||||
else:
|
||||
log.warn('Could not find the %s element of the '
|
||||
'Setuptools distribution', element)
|
||||
return True
|
||||
|
||||
_remove_flat_installation = _no_sandbox(_remove_flat_installation)
|
||||
|
||||
|
||||
def _after_install(dist):
|
||||
log.warn('After install bootstrap.')
|
||||
placeholder = dist.get_command_obj('install').install_purelib
|
||||
_create_fake_setuptools_pkg_info(placeholder)
|
||||
|
||||
|
||||
def _create_fake_setuptools_pkg_info(placeholder):
|
||||
if not placeholder or not os.path.exists(placeholder):
|
||||
log.warn('Could not find the install location')
|
||||
return
|
||||
pyver = '%s.%s' % (sys.version_info[0], sys.version_info[1])
|
||||
setuptools_file = 'setuptools-%s-py%s.egg-info' % \
|
||||
(SETUPTOOLS_FAKED_VERSION, pyver)
|
||||
pkg_info = os.path.join(placeholder, setuptools_file)
|
||||
if os.path.exists(pkg_info):
|
||||
log.warn('%s already exists', pkg_info)
|
||||
return
|
||||
|
||||
if not os.access(pkg_info, os.W_OK):
|
||||
log.warn("Don't have permissions to write %s, skipping", pkg_info)
|
||||
|
||||
log.warn('Creating %s', pkg_info)
|
||||
f = open(pkg_info, 'w')
|
||||
try:
|
||||
f.write(SETUPTOOLS_PKG_INFO)
|
||||
finally:
|
||||
f.close()
|
||||
|
||||
pth_file = os.path.join(placeholder, 'setuptools.pth')
|
||||
log.warn('Creating %s', pth_file)
|
||||
f = open(pth_file, 'w')
|
||||
try:
|
||||
f.write(os.path.join(os.curdir, setuptools_file))
|
||||
finally:
|
||||
f.close()
|
||||
|
||||
_create_fake_setuptools_pkg_info = _no_sandbox(
|
||||
_create_fake_setuptools_pkg_info
|
||||
)
|
||||
|
||||
|
||||
def _patch_egg_dir(path):
|
||||
# let's check if it's already patched
|
||||
pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO')
|
||||
if os.path.exists(pkg_info):
|
||||
if _same_content(pkg_info, SETUPTOOLS_PKG_INFO):
|
||||
log.warn('%s already patched.', pkg_info)
|
||||
return False
|
||||
_rename_path(path)
|
||||
os.mkdir(path)
|
||||
os.mkdir(os.path.join(path, 'EGG-INFO'))
|
||||
pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO')
|
||||
f = open(pkg_info, 'w')
|
||||
try:
|
||||
f.write(SETUPTOOLS_PKG_INFO)
|
||||
finally:
|
||||
f.close()
|
||||
return True
|
||||
|
||||
_patch_egg_dir = _no_sandbox(_patch_egg_dir)
|
||||
|
||||
|
||||
def _before_install():
|
||||
log.warn('Before install bootstrap.')
|
||||
_fake_setuptools()
|
||||
|
||||
|
||||
def _under_prefix(location):
|
||||
if 'install' not in sys.argv:
|
||||
return True
|
||||
args = sys.argv[sys.argv.index('install') + 1:]
|
||||
for index, arg in enumerate(args):
|
||||
for option in ('--root', '--prefix'):
|
||||
if arg.startswith('%s=' % option):
|
||||
top_dir = arg.split('root=')[-1]
|
||||
return location.startswith(top_dir)
|
||||
elif arg == option:
|
||||
if len(args) > index:
|
||||
top_dir = args[index + 1]
|
||||
return location.startswith(top_dir)
|
||||
if arg == '--user' and USER_SITE is not None:
|
||||
return location.startswith(USER_SITE)
|
||||
return True
|
||||
|
||||
|
||||
def _fake_setuptools():
|
||||
log.warn('Scanning installed packages')
|
||||
try:
|
||||
import pkg_resources
|
||||
except ImportError:
|
||||
# we're cool
|
||||
log.warn('Setuptools or Distribute does not seem to be installed.')
|
||||
return
|
||||
ws = pkg_resources.working_set
|
||||
try:
|
||||
setuptools_dist = ws.find(
|
||||
pkg_resources.Requirement.parse('setuptools', replacement=False)
|
||||
)
|
||||
except TypeError:
|
||||
# old distribute API
|
||||
setuptools_dist = ws.find(
|
||||
pkg_resources.Requirement.parse('setuptools')
|
||||
)
|
||||
|
||||
if setuptools_dist is None:
|
||||
log.warn('No setuptools distribution found')
|
||||
return
|
||||
# detecting if it was already faked
|
||||
setuptools_location = setuptools_dist.location
|
||||
log.warn('Setuptools installation detected at %s', setuptools_location)
|
||||
|
||||
# if --root or --preix was provided, and if
|
||||
# setuptools is not located in them, we don't patch it
|
||||
if not _under_prefix(setuptools_location):
|
||||
log.warn('Not patching, --root or --prefix is installing Distribute'
|
||||
' in another location')
|
||||
return
|
||||
|
||||
# let's see if its an egg
|
||||
if not setuptools_location.endswith('.egg'):
|
||||
log.warn('Non-egg installation')
|
||||
res = _remove_flat_installation(setuptools_location)
|
||||
if not res:
|
||||
return
|
||||
else:
|
||||
log.warn('Egg installation')
|
||||
pkg_info = os.path.join(setuptools_location, 'EGG-INFO', 'PKG-INFO')
|
||||
if (os.path.exists(pkg_info) and
|
||||
_same_content(pkg_info, SETUPTOOLS_PKG_INFO)):
|
||||
log.warn('Already patched.')
|
||||
return
|
||||
log.warn('Patching...')
|
||||
# let's create a fake egg replacing setuptools one
|
||||
res = _patch_egg_dir(setuptools_location)
|
||||
if not res:
|
||||
return
|
||||
log.warn('Patched done.')
|
||||
_relaunch()
|
||||
|
||||
|
||||
def _relaunch():
|
||||
log.warn('Relaunching...')
|
||||
# we have to relaunch the process
|
||||
# pip marker to avoid a relaunch bug
|
||||
_cmd = ['-c', 'install', '--single-version-externally-managed']
|
||||
if sys.argv[:3] == _cmd:
|
||||
sys.argv[0] = 'setup.py'
|
||||
args = [sys.executable] + sys.argv
|
||||
sys.exit(subprocess.call(args))
|
||||
|
||||
|
||||
def _extractall(self, path=".", members=None):
|
||||
"""Extract all members from the archive to the current working
|
||||
directory and set owner, modification time and permissions on
|
||||
directories afterwards. `path' specifies a different directory
|
||||
to extract to. `members' is optional and must be a subset of the
|
||||
list returned by getmembers().
|
||||
"""
|
||||
import copy
|
||||
import operator
|
||||
from tarfile import ExtractError
|
||||
directories = []
|
||||
|
||||
if members is None:
|
||||
members = self
|
||||
|
||||
for tarinfo in members:
|
||||
if tarinfo.isdir():
|
||||
# Extract directories with a safe mode.
|
||||
directories.append(tarinfo)
|
||||
tarinfo = copy.copy(tarinfo)
|
||||
tarinfo.mode = 448 # decimal for oct 0700
|
||||
self.extract(tarinfo, path)
|
||||
|
||||
# Reverse sort directories.
|
||||
if sys.version_info < (2, 4):
|
||||
def sorter(dir1, dir2):
|
||||
return cmp(dir1.name, dir2.name)
|
||||
directories.sort(sorter)
|
||||
directories.reverse()
|
||||
else:
|
||||
directories.sort(key=operator.attrgetter('name'), reverse=True)
|
||||
|
||||
# Set correct owner, mtime and filemode on directories.
|
||||
for tarinfo in directories:
|
||||
dirpath = os.path.join(path, tarinfo.name)
|
||||
try:
|
||||
self.chown(tarinfo, dirpath)
|
||||
self.utime(tarinfo, dirpath)
|
||||
self.chmod(tarinfo, dirpath)
|
||||
except ExtractError:
|
||||
e = sys.exc_info()[1]
|
||||
if self.errorlevel > 1:
|
||||
raise
|
||||
else:
|
||||
self._dbg(1, "tarfile: %s" % e)
|
||||
|
||||
|
||||
def _build_install_args(argv):
|
||||
install_args = []
|
||||
user_install = '--user' in argv
|
||||
if user_install and sys.version_info < (2, 6):
|
||||
log.warn("--user requires Python 2.6 or later")
|
||||
raise SystemExit(1)
|
||||
if user_install:
|
||||
install_args.append('--user')
|
||||
return install_args
|
||||
|
||||
|
||||
def main(argv, version=DEFAULT_VERSION):
|
||||
"""Install or upgrade setuptools and EasyInstall"""
|
||||
tarball = download_setuptools()
|
||||
_install(tarball, _build_install_args(argv))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(sys.argv[1:])
|
||||
433
domdiv/__init__.py
Normal file
433
domdiv/__init__.py
Normal file
@ -0,0 +1,433 @@
|
||||
from optparse import OptionParser
|
||||
import os
|
||||
import codecs
|
||||
import json
|
||||
import sys
|
||||
|
||||
import reportlab.lib.pagesizes as pagesizes
|
||||
from reportlab.lib.units import cm
|
||||
|
||||
from cards import Card
|
||||
from draw import DividerDrawer
|
||||
|
||||
LOCATION_CHOICES = ["tab", "body-top", "hide"]
|
||||
NAME_ALIGN_CHOICES = ["left", "right", "centre", "edge"]
|
||||
TAB_SIDE_CHOICES = ["left", "right", "left-alternate", "right-alternate", "full"]
|
||||
|
||||
|
||||
def add_opt(options, option, value):
|
||||
assert not hasattr(options, option)
|
||||
setattr(options, option, value)
|
||||
|
||||
|
||||
def parse_opts(argstring):
|
||||
parser = OptionParser()
|
||||
parser.add_option("--back_offset", type="float", dest="back_offset", default=0,
|
||||
help="Points to offset the back page to the right; needed for some printers")
|
||||
parser.add_option("--back_offset_height", type="float", dest="back_offset_height", default=0,
|
||||
help="Points to offset the back page upward; needed for some printers")
|
||||
parser.add_option("--orientation", type="choice", choices=["horizontal", "vertical"],
|
||||
dest="orientation", default="horizontal",
|
||||
help="horizontal or vertical, default:horizontal")
|
||||
parser.add_option("--sleeved", action="store_true",
|
||||
dest="sleeved", help="use --size=sleeved instead")
|
||||
parser.add_option("--size", type="string", dest="size", default='normal',
|
||||
help="'<%f>x<%f>' (size in cm), or 'normal' = '9.1x5.9', or 'sleeved' = '9.4x6.15'")
|
||||
parser.add_option("--minmargin", type="string", dest="minmargin", default="1x1",
|
||||
help="'<%f>x<%f>' (size in cm, left/right, top/bottom), default: 1x1")
|
||||
parser.add_option("--papersize", type="string", dest="papersize", default=None,
|
||||
help="'<%f>x<%f>' (size in cm), or 'A4', or 'LETTER'")
|
||||
parser.add_option("--tab_name_align", type="choice", choices=NAME_ALIGN_CHOICES + ["center"],
|
||||
dest="tab_name_align", default="left",
|
||||
help="Alignment of text on the tab. choices: left, right, centre (or center), edge."
|
||||
" The edge option will align the card name to the outside edge of the"
|
||||
" tab, so that when using tabs on alternating sides,"
|
||||
" the name is less likely to be hidden by the tab in front"
|
||||
" (edge will revert to left when tab_side is full since there is no edge in that case);"
|
||||
" default:left")
|
||||
parser.add_option("--tab_side", type="choice", choices=TAB_SIDE_CHOICES,
|
||||
dest="tab_side", default="right-alternate",
|
||||
help="Alignment of tab. choices: left, right, left-alternate, right-alternate, full;"
|
||||
" left/right forces all tabs to left/right side;"
|
||||
" left-alternate will start on the left and then toggle between left and right for the tabs;"
|
||||
" right-alternate will start on the right and then toggle between right and left for the tabs;" # noqa
|
||||
" full will force all label tabs to be full width of the divider"
|
||||
" default:right-alternate")
|
||||
parser.add_option("--tabwidth", type="float", default=4,
|
||||
help="width in cm of stick-up tab (ignored if tab_side is full or tabs-only is used)")
|
||||
parser.add_option("--cost", action="append", type="choice",
|
||||
choices=LOCATION_CHOICES, default=[],
|
||||
help="where to display the card cost; may be set to"
|
||||
" 'hide' to indicate it should not be displayed, or"
|
||||
" given multiple times to show it in multiple"
|
||||
" places; valid values are: %s; defaults to 'tab'"
|
||||
% ", ".join("'%s'" % x for x in LOCATION_CHOICES))
|
||||
parser.add_option("--set_icon", action="append", type="choice",
|
||||
choices=LOCATION_CHOICES, default=[],
|
||||
help="where to display the set icon; may be set to"
|
||||
" 'hide' to indicate it should not be displayed, or"
|
||||
" given multiple times to show it in multiple"
|
||||
" places; valid values are: %s; defaults to 'tab'"
|
||||
% ", ".join("'%s'" % x for x in LOCATION_CHOICES))
|
||||
parser.add_option("--expansions", action="append", type="string",
|
||||
help="subset of dominion expansions to produce tabs for")
|
||||
parser.add_option("--cropmarks", action="store_true", dest="cropmarks",
|
||||
help="print crop marks on both sides, rather than tab outlines on one")
|
||||
parser.add_option("--linewidth", type="float", default=.1,
|
||||
help="width of lines for card outlines/crop marks")
|
||||
parser.add_option("--write_json", action="store_true", dest="write_json",
|
||||
help="write json version of card definitions and extras")
|
||||
parser.add_option("--tabs-only", action="store_true", dest="tabs_only",
|
||||
help="draw only tabs to be printed on labels, no divider outlines")
|
||||
parser.add_option("--order", type="choice", choices=["expansion", "global"], dest="order",
|
||||
help="sort order for the cards, whether by expansion or globally alphabetical")
|
||||
parser.add_option("--expansion_dividers", action="store_true", dest="expansion_dividers",
|
||||
help="add dividers describing each expansion set")
|
||||
parser.add_option("--base_cards_with_expansion", action="store_true",
|
||||
help='print the base cards as part of the expansion; ie, a divider for "Silver"'
|
||||
' will be printed as both a "Dominion" card and as an "Intrigue" card; if this'
|
||||
' option is not given, all base cards are placed in their own "Base" expansion')
|
||||
parser.add_option("--centre_expansion_dividers", action="store_true", dest="centre_expansion_dividers",
|
||||
help='centre the tabs on expansion dividers')
|
||||
parser.add_option("--num_pages", type="int", default=-1,
|
||||
help="stop generating after this many pages, -1 for all")
|
||||
parser.add_option("--language", default='en_us', help="language of card texts")
|
||||
parser.add_option("--include_blanks", action="store_true",
|
||||
help="include a few dividers with extra text")
|
||||
parser.add_option("--exclude_events", action="store_true",
|
||||
default=False, help="exclude individual dividers for events")
|
||||
parser.add_option("--special_card_groups", action="store_true",
|
||||
default=False, help="group some cards under special dividers (e.g. Shelters, Prizes)")
|
||||
parser.add_option("--exclude_prizes", action="store_true",
|
||||
default=False, help="exclude individual dividers for prizes (cornucopia)")
|
||||
parser.add_option("--cardlist", type="string", dest="cardlist", default=None,
|
||||
help="Path to file that enumerates each card to be printed on its own line.")
|
||||
parser.add_option("--no-tab-artwork", action="store_true", dest="no_tab_artwork",
|
||||
help="don't show background artwork on tabs")
|
||||
parser.add_option("--no-card-rules", action="store_true", dest="no_card_rules",
|
||||
help="don't print the card's rules on the tab body")
|
||||
parser.add_option("--use-text-set-icon", action="store_true", dest="use_text_set_icon",
|
||||
help="use text/letters to represent a card's set instead of the set icon")
|
||||
parser.add_option("--no-page-footer", action="store_true", dest="no_page_footer",
|
||||
help="don't print the set name at the bottom of the page.")
|
||||
parser.add_option("--no-card-backs", action="store_true", dest="no_card_backs",
|
||||
help="don't print the back page of the card sheets.")
|
||||
|
||||
options, args = parser.parse_args(argstring)
|
||||
if not options.cost:
|
||||
options.cost = ['tab']
|
||||
if not options.set_icon:
|
||||
options.set_icon = ['tab']
|
||||
return options, args
|
||||
|
||||
|
||||
def parseDimensions(dimensionsStr):
|
||||
x, y = dimensionsStr.upper().split('X', 1)
|
||||
return (float(x) * cm, float(y) * cm)
|
||||
|
||||
|
||||
def generate_sample(options):
|
||||
import cStringIO
|
||||
from wand.image import Image
|
||||
buf = cStringIO.StringIO()
|
||||
options.num_pages = 1
|
||||
generate(options, '.', buf)
|
||||
with Image(blob=buf.getvalue()) as sample:
|
||||
sample.format = 'png'
|
||||
sample.save(filename='sample.png')
|
||||
|
||||
|
||||
def parse_papersize(spec):
|
||||
papersize = None
|
||||
if not spec:
|
||||
if os.path.exists("/etc/papersize"):
|
||||
papersize = open("/etc/papersize").readline().upper()
|
||||
else:
|
||||
papersize = 'LETTER'
|
||||
else:
|
||||
papersize = spec.upper()
|
||||
|
||||
try:
|
||||
paperwidth, paperheight = getattr(pagesizes, papersize)
|
||||
except AttributeError:
|
||||
try:
|
||||
paperwidth, paperheight = parseDimensions(papersize)
|
||||
print 'Using custom paper size, %.2fcm x %.2fcm' % (paperwidth / cm, paperheight / cm)
|
||||
except ValueError:
|
||||
paperwidth, paperheight = pagesizes.LETTER
|
||||
return paperwidth, paperheight
|
||||
|
||||
|
||||
def parse_cardsize(spec, sleeved):
|
||||
spec = spec.upper()
|
||||
if spec == 'SLEEVED' or sleeved:
|
||||
dominionCardWidth, dominionCardHeight = (9.4 * cm, 6.15 * cm)
|
||||
print 'Using sleeved card size, %.2fcm x %.2fcm' % (dominionCardWidth / cm,
|
||||
dominionCardHeight / cm)
|
||||
elif spec in ['NORMAL', 'UNSLEEVED']:
|
||||
dominionCardWidth, dominionCardHeight = (9.1 * cm, 5.9 * cm)
|
||||
print 'Using normal card size, %.2fcm x%.2fcm' % (dominionCardWidth / cm,
|
||||
dominionCardHeight / cm)
|
||||
else:
|
||||
dominionCardWidth, dominionCardHeight = parseDimensions(spec)
|
||||
print 'Using custom card size, %.2fcm x %.2fcm' % (dominionCardWidth / cm,
|
||||
dominionCardHeight / cm)
|
||||
return dominionCardWidth, dominionCardHeight
|
||||
|
||||
|
||||
def read_write_card_data(options):
|
||||
data_dir = os.path.join(options.data_path, "card_db", options.language)
|
||||
card_db_filepath = os.path.join(data_dir, "cards.json")
|
||||
with codecs.open(card_db_filepath, "r", "utf-8") as cardfile:
|
||||
cards = json.load(cardfile, object_hook=Card.decode_json)
|
||||
|
||||
language_mapping_filepath = os.path.join(data_dir, "mapping.json")
|
||||
with codecs.open(language_mapping_filepath, 'r', 'utf-8') as mapping_file:
|
||||
Card.language_mapping = json.load(mapping_file)
|
||||
|
||||
if options.write_json:
|
||||
fpath = "cards.json"
|
||||
with codecs.open(fpath, 'w', encoding='utf-8') as ofile:
|
||||
json.dump(cards,
|
||||
ofile,
|
||||
cls=Card.CardJSONEncoder,
|
||||
ensure_ascii=False,
|
||||
indent=True,
|
||||
sort_keys=True)
|
||||
return cards
|
||||
|
||||
|
||||
class CardSorter(object):
|
||||
|
||||
def __init__(self, order, baseCards):
|
||||
self.order = order
|
||||
if order == "global":
|
||||
self.sort_key = self.global_sort_key
|
||||
else:
|
||||
self.sort_key = self.by_expansion_sort_key
|
||||
|
||||
self.baseCards = baseCards
|
||||
|
||||
# When sorting cards, want to always put "base" cards after all
|
||||
# kingdom cards, and order the base cards in a set order - the
|
||||
# order they are listed in the database (ie, all normal treasures
|
||||
# by worth, then potion, then all normal VP cards by worth, then
|
||||
# trash)
|
||||
def baseIndex(self, name):
|
||||
try:
|
||||
return self.baseCards.index(name)
|
||||
except Exception:
|
||||
return -1
|
||||
|
||||
def isBaseExpansionCard(self, card):
|
||||
return card.cardset.lower() != 'base' and card.name in self.baseCards
|
||||
|
||||
def global_sort_key(self, card):
|
||||
return int(card.isExpansion()), self.baseIndex(card.name), card.name
|
||||
|
||||
def by_expansion_sort_key(self, card):
|
||||
return card.cardset, int(card.isExpansion()), self.baseIndex(card.name), card.name
|
||||
|
||||
def __call__(self, card):
|
||||
return self.sort_key(card)
|
||||
|
||||
|
||||
def filter_sort_cards(cards, options):
|
||||
|
||||
cardSorter = CardSorter(options.order,
|
||||
[card.name for card in cards if card.cardset.lower() == 'base'])
|
||||
if options.base_cards_with_expansion:
|
||||
cards = [card for card in cards if card.cardset.lower() != 'base']
|
||||
else:
|
||||
cards = [card for card in cards if not cardSorter.isBaseExpansionCard(card)]
|
||||
|
||||
if options.special_card_groups:
|
||||
# Load the card groups file
|
||||
card_groups_file = os.path.join(options.data_dir, "card_groups.json")
|
||||
with codecs.open(card_groups_file, 'r', 'utf-8') as cardgroup_file:
|
||||
card_groups = json.load(cardgroup_file)
|
||||
# pull out any cards which are a subcard, and rename the master card
|
||||
new_cards = []
|
||||
all_subcards = []
|
||||
for subs in [card_groups[x]["subcards"] for x in card_groups]:
|
||||
all_subcards += subs
|
||||
for card in cards:
|
||||
if card.name in card_groups.keys():
|
||||
card.name = card_groups[card.name]["new_name"]
|
||||
elif card.name in all_subcards:
|
||||
continue
|
||||
new_cards.append(card)
|
||||
cards = new_cards
|
||||
|
||||
if options.expansions:
|
||||
options.expansions = [o.lower()
|
||||
for o in options.expansions]
|
||||
reverseMapping = {
|
||||
v: k for k, v in Card.language_mapping.iteritems()}
|
||||
options.expansions = [
|
||||
reverseMapping.get(e, e) for e in options.expansions]
|
||||
filteredCards = []
|
||||
knownExpansions = set()
|
||||
for c in cards:
|
||||
knownExpansions.add(c.cardset)
|
||||
if next((e for e in options.expansions if c.cardset.startswith(e)), None):
|
||||
filteredCards.append(c)
|
||||
unknownExpansions = set(options.expansions) - knownExpansions
|
||||
if unknownExpansions:
|
||||
print "Error - unknown expansion(s): %s" % ", ".join(unknownExpansions)
|
||||
return
|
||||
|
||||
cards = filteredCards
|
||||
|
||||
if options.exclude_events:
|
||||
cards = [card for card in cards if not card.isEvent() or card.name == 'Events']
|
||||
|
||||
if options.exclude_prizes:
|
||||
cards = [card for card in cards if not card.isPrize()]
|
||||
|
||||
if options.cardlist:
|
||||
cardlist = set()
|
||||
with open(options.cardlist) as cardfile:
|
||||
for line in cardfile:
|
||||
cardlist.add(line.strip())
|
||||
if cardlist:
|
||||
cards = [card for card in cards if card.name in cardlist]
|
||||
|
||||
if options.expansion_dividers:
|
||||
cardnamesByExpansion = {}
|
||||
for c in cards:
|
||||
if cardSorter.isBaseExpansionCard(c):
|
||||
continue
|
||||
cardnamesByExpansion.setdefault(
|
||||
c.cardset, []).append(c.name.strip())
|
||||
for exp, names in cardnamesByExpansion.iteritems():
|
||||
c = Card(
|
||||
exp, exp, ("Expansion",), None, ' | '.join(sorted(names)))
|
||||
cards.append(c)
|
||||
|
||||
cards.sort(key=cardSorter)
|
||||
|
||||
return cards
|
||||
|
||||
|
||||
def calculate_layout(options):
|
||||
|
||||
dominionCardWidth, dominionCardHeight = parse_cardsize(options.size, options.sleeved)
|
||||
paperwidth, paperheight = parse_papersize(options.papersize)
|
||||
|
||||
if options.orientation == "vertical":
|
||||
dividerWidth, dividerBaseHeight = dominionCardHeight, dominionCardWidth
|
||||
else:
|
||||
dividerWidth, dividerBaseHeight = dominionCardWidth, dominionCardHeight
|
||||
|
||||
if options.tab_name_align == "center":
|
||||
options.tab_name_align = "centre"
|
||||
|
||||
if options.tab_side == "full" and options.tab_name_align == "edge":
|
||||
# This case does not make sense since there are two tab edges in this case. So picking left edge.
|
||||
print >>sys.stderr, "** Warning: Aligning card name as 'left' for 'full' tabs **"
|
||||
options.tab_name_align == "left"
|
||||
|
||||
fixedMargins = False
|
||||
if options.tabs_only:
|
||||
# fixed for Avery 8867 for now
|
||||
minmarginwidth = 0.86 * cm # was 0.76
|
||||
minmarginheight = 1.37 * cm # was 1.27
|
||||
labelHeight = 1.07 * cm # was 1.27
|
||||
labelWidth = 4.24 * cm # was 4.44
|
||||
horizontalBorderSpace = 0.96 * cm # was 0.76
|
||||
verticalBorderSpace = 0.20 * cm # was 0.01
|
||||
dividerBaseHeight = 0
|
||||
dividerWidth = labelWidth
|
||||
fixedMargins = True
|
||||
else:
|
||||
minmarginwidth, minmarginheight = parseDimensions(
|
||||
options.minmargin)
|
||||
if options.tab_side == "full":
|
||||
labelWidth = dividerWidth
|
||||
else:
|
||||
labelWidth = options.tabwidth * cm
|
||||
labelHeight = .9 * cm
|
||||
horizontalBorderSpace = 0 * cm
|
||||
verticalBorderSpace = 0 * cm
|
||||
|
||||
dividerHeight = dividerBaseHeight + labelHeight
|
||||
|
||||
add_opt(options, 'dividerWidth', dividerWidth)
|
||||
add_opt(options, 'dividerHeight', dividerHeight)
|
||||
add_opt(options, 'dividerWidthReserved', dividerWidth + horizontalBorderSpace)
|
||||
add_opt(options, 'dividerHeightReserved', dividerHeight + verticalBorderSpace)
|
||||
add_opt(options, 'labelWidth', labelWidth)
|
||||
add_opt(options, 'labelHeight', labelHeight)
|
||||
|
||||
# as we don't draw anything in the final border, it shouldn't count towards how many tabs we can fit
|
||||
# so it gets added back in to the page size here
|
||||
numDividersVerticalP = int(
|
||||
(paperheight - 2 * minmarginheight + verticalBorderSpace) / options.dividerHeightReserved)
|
||||
numDividersHorizontalP = int(
|
||||
(paperwidth - 2 * minmarginwidth + horizontalBorderSpace) / options.dividerWidthReserved)
|
||||
numDividersVerticalL = int(
|
||||
(paperwidth - 2 * minmarginwidth + verticalBorderSpace) / options.dividerHeightReserved)
|
||||
numDividersHorizontalL = int(
|
||||
(paperheight - 2 * minmarginheight + horizontalBorderSpace) / options.dividerWidthReserved)
|
||||
|
||||
if ((numDividersVerticalL * numDividersHorizontalL >
|
||||
numDividersVerticalP * numDividersHorizontalP) and not fixedMargins):
|
||||
add_opt(options, 'numDividersVertical', numDividersVerticalL)
|
||||
add_opt(options, 'numDividersHorizontal', numDividersHorizontalL)
|
||||
add_opt(options, 'paperheight', paperwidth)
|
||||
add_opt(options, 'paperwidth', paperheight)
|
||||
add_opt(options, 'minHorizontalMargin', minmarginheight)
|
||||
add_opt(options, 'minVerticalMargin', minmarginwidth)
|
||||
else:
|
||||
add_opt(options, 'numDividersVertical', numDividersVerticalP)
|
||||
add_opt(options, 'numDividersHorizontal', numDividersHorizontalP)
|
||||
add_opt(options, 'paperheight', paperheight)
|
||||
add_opt(options, 'paperwidth', paperwidth)
|
||||
add_opt(options, 'minHorizontalMargin', minmarginheight)
|
||||
add_opt(options, 'minVerticalMargin', minmarginwidth)
|
||||
|
||||
if not fixedMargins:
|
||||
# dynamically max margins
|
||||
add_opt(options, 'horizontalMargin',
|
||||
(options.paperwidth -
|
||||
options.numDividersHorizontal * options.dividerWidthReserved) / 2)
|
||||
add_opt(options, 'verticalMargin',
|
||||
(options.paperheight -
|
||||
options.numDividersVertical * options.dividerHeightReserved) / 2)
|
||||
else:
|
||||
add_opt(options, 'horizontalMargin', minmarginwidth)
|
||||
add_opt(options, 'verticalMargin', minmarginheight)
|
||||
|
||||
|
||||
def generate(options, data_path, f):
|
||||
|
||||
add_opt(options, 'data_path', data_path)
|
||||
|
||||
calculate_layout(options)
|
||||
|
||||
print "Paper dimensions: {:.2f}cm (w) x {:.2f}cm (h)".format(options.paperwidth / cm,
|
||||
options.paperheight / cm)
|
||||
print "Tab dimensions: {:.2f}cm (w) x {:.2f}cm (h)".format(options.dividerWidthReserved / cm,
|
||||
options.dividerHeightReserved / cm)
|
||||
print '{} dividers horizontally, {} vertically'.format(options.numDividersHorizontal,
|
||||
options.numDividersVertical)
|
||||
print "Margins: {:.2f}cm h, {:.2f}cm v\n".format(options.horizontalMargin / cm,
|
||||
options.verticalMargin / cm)
|
||||
|
||||
cards = read_write_card_data(options)
|
||||
cards = filter_sort_cards(cards, options)
|
||||
|
||||
if not f:
|
||||
f = "dominion_dividers.pdf"
|
||||
|
||||
dd = DividerDrawer()
|
||||
dd.draw(f, cards, options)
|
||||
|
||||
|
||||
def main(argstring, data_path):
|
||||
options, args = parse_opts(argstring)
|
||||
fname = None
|
||||
if args:
|
||||
fname = args[0]
|
||||
return generate(options, data_path, fname)
|
||||
219
domdiv/cards.py
Normal file
219
domdiv/cards.py
Normal file
@ -0,0 +1,219 @@
|
||||
import json
|
||||
import os
|
||||
|
||||
|
||||
def getType(typespec):
|
||||
return cardTypes[tuple(typespec)]
|
||||
|
||||
setImages = {
|
||||
'dominion': 'base_set.png',
|
||||
'intrigue': 'intrigue_set.png',
|
||||
'seaside': 'seaside_set.png',
|
||||
'prosperity': 'prosperity_set.png',
|
||||
'alchemy': 'alchemy_set.png',
|
||||
'cornucopia': 'cornucopia_set.png',
|
||||
'cornucopia extras': 'cornucopia_set.png',
|
||||
'hinterlands': 'hinterlands_set.png',
|
||||
'dark ages': 'dark_ages_set.png',
|
||||
'dark ages extras': 'dark_ages_set.png',
|
||||
'guilds': 'guilds_set.png',
|
||||
'adventures': 'adventures_set.png',
|
||||
'adventures extras': 'adventures_set.png'
|
||||
}
|
||||
promoImages = {
|
||||
'walled village': 'walled_village_set.png',
|
||||
'stash': 'stash_set.png',
|
||||
'governor': 'governor_set.png',
|
||||
'black market': 'black_market_set.png',
|
||||
'envoy': 'envoy_set.png',
|
||||
'prince': 'prince_set.png'
|
||||
}
|
||||
|
||||
setTextIcons = {
|
||||
'dominion': 'D',
|
||||
'intrigue': 'I',
|
||||
'seaside': 'S',
|
||||
'prosperity': 'P',
|
||||
'alchemy': 'A',
|
||||
'cornucopia': 'C',
|
||||
'cornucopia extras': 'C',
|
||||
'hinterlands': 'H',
|
||||
'dark ages': 'DA',
|
||||
'dark ages extras': 'DA',
|
||||
'guilds': 'G',
|
||||
'adventures': 'Ad',
|
||||
'adventures extras': 'Ad'
|
||||
}
|
||||
|
||||
promoTextIcons = {
|
||||
'walled village': '',
|
||||
'stash': '',
|
||||
'governor': '',
|
||||
'black market': '',
|
||||
'envoy': '',
|
||||
'prince': ''
|
||||
}
|
||||
|
||||
language_mapping = None
|
||||
|
||||
|
||||
class Card(object):
|
||||
|
||||
language_mapping = None
|
||||
|
||||
class CardJSONEncoder(json.JSONEncoder):
|
||||
|
||||
def default(self, obj):
|
||||
if isinstance(obj, Card):
|
||||
return obj.__dict__
|
||||
return json.JSONEncoder.default(self, obj)
|
||||
|
||||
@staticmethod
|
||||
def decode_json(obj):
|
||||
return Card(**obj)
|
||||
|
||||
@classmethod
|
||||
def getSetImage(cls, setName, cardName):
|
||||
if setName in setImages:
|
||||
return setImages[setName]
|
||||
if cardName.lower() in promoImages:
|
||||
return promoImages[cardName.lower()]
|
||||
if setName in cls.language_mapping:
|
||||
trans = cls.language_mapping[setName]
|
||||
if trans in setImages:
|
||||
return setImages[trans]
|
||||
if cardName in cls.language_mapping:
|
||||
trans = cls.language_mapping[cardName]
|
||||
if trans.lower() in promoImages:
|
||||
return promoImages[trans.lower()]
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def getSetText(cls, setName, cardName):
|
||||
if setName in cls.setTextIcons:
|
||||
return cls.setTextIcons[setName]
|
||||
if cardName.lower() in cls.promoTextIcons:
|
||||
return cls.promoTextIcons[cardName.lower()]
|
||||
return None
|
||||
|
||||
def __init__(self, name, cardset, types, cost, description='', potcost=0, extra=''):
|
||||
self.name = name.strip()
|
||||
self.cardset = cardset.strip()
|
||||
self.types = types
|
||||
self.cost = cost
|
||||
self.potcost = potcost
|
||||
self.description = description
|
||||
self.extra = extra
|
||||
|
||||
def getType(self):
|
||||
return getType(self.types)
|
||||
|
||||
def __repr__(self):
|
||||
return '"' + self.name + '"'
|
||||
|
||||
def toString(self):
|
||||
return self.name + ' ' + self.cardset + ' ' + '-'.join(self.types)\
|
||||
+ ' ' + self.cost + ' ' + self.description + ' ' + self.extra
|
||||
|
||||
def isExpansion(self):
|
||||
return self.getType().getTypeNames() == ('Expansion',)
|
||||
|
||||
def isEvent(self):
|
||||
return self.getType().getTypeNames() == ('Event',)
|
||||
|
||||
def isPrize(self):
|
||||
return 'Prize' in self.getType().getTypeNames()
|
||||
|
||||
def setImage(self):
|
||||
setImage = Card.getSetImage(self.cardset, self.name)
|
||||
if setImage is None and self.cardset not in ['base', 'extra'] and not self.isExpansion():
|
||||
print 'warning, no set image for set "%s" card "%s"' % (self.cardset, self.name)
|
||||
setImages[self.cardset] = 0
|
||||
promoImages[self.name.lower()] = 0
|
||||
return setImage
|
||||
|
||||
def setTextIcon(self):
|
||||
setTextIcon = getSetText(self.cardset, self.name)
|
||||
if setTextIcon is None and self.cardset not in ['base', 'extra'] and not self.isExpansion():
|
||||
print 'warning, no set text for set "%s" card "%s"' % (self.cardset, self.name)
|
||||
setTextIcons[self.cardset] = 0
|
||||
promoTextIcons[self.name.lower()] = 0
|
||||
return setTextIcon
|
||||
|
||||
def isBlank(self):
|
||||
return False
|
||||
|
||||
|
||||
class BlankCard(Card):
|
||||
|
||||
def __init__(self, num):
|
||||
Card.__init__(self, str(num), 'extra', ('Blank',), 0)
|
||||
|
||||
def isBlank(self):
|
||||
return True
|
||||
|
||||
|
||||
class CardType(object):
|
||||
|
||||
def __init__(self, typeNames, tabImageFile, tabTextHeightOffset=0, tabCostHeightOffset=-1):
|
||||
self.typeNames = typeNames
|
||||
self.tabImageFile = tabImageFile
|
||||
self.tabTextHeightOffset = tabTextHeightOffset
|
||||
self.tabCostHeightOffset = tabCostHeightOffset
|
||||
|
||||
def getTypeNames(self):
|
||||
return self.typeNames
|
||||
|
||||
def getTabImageFile(self):
|
||||
if not self.tabImageFile:
|
||||
return None
|
||||
return self.tabImageFile
|
||||
|
||||
def getNoCoinTabImageFile(self):
|
||||
if not self.tabImageFile:
|
||||
return None
|
||||
return ''.join(os.path.splitext(self.tabImageFile)[0] + '_nc' + os.path.splitext(self.tabImageFile)[1])
|
||||
|
||||
def getTabTextHeightOffset(self):
|
||||
return self.tabTextHeightOffset
|
||||
|
||||
def getTabCostHeightOffset(self):
|
||||
return self.tabCostHeightOffset
|
||||
|
||||
cardTypes = [
|
||||
CardType(('Action',), 'action.png'),
|
||||
CardType(('Action', 'Attack'), 'action.png'),
|
||||
CardType(('Action', 'Attack', 'Prize'), 'action.png'),
|
||||
CardType(('Action', 'Reaction'), 'reaction.png'),
|
||||
CardType(('Action', 'Victory'), 'action-victory.png'),
|
||||
CardType(('Action', 'Duration'), 'duration.png'),
|
||||
CardType(('Action', 'Duration', 'Reaction'), 'duration-reaction.png'),
|
||||
CardType(('Action', 'Attack', 'Duration'), 'duration.png'),
|
||||
CardType(('Action', 'Looter'), 'action.png'),
|
||||
CardType(('Action', 'Prize'), 'action.png'),
|
||||
CardType(('Action', 'Ruins'), 'ruins.png', 0, 1),
|
||||
CardType(('Action', 'Shelter'), 'action-shelter.png'),
|
||||
CardType(('Action', 'Attack', 'Looter'), 'action.png'),
|
||||
CardType(('Action', 'Attack', 'Traveller'), 'action.png'),
|
||||
CardType(('Action', 'Reserve'), 'reserve.png'),
|
||||
CardType(('Action', 'Reserve', 'Victory'), 'reserve-victory.png'),
|
||||
CardType(('Action', 'Traveller'), 'action.png'),
|
||||
CardType(('Prize',), 'action.png'),
|
||||
CardType(('Event',), 'event.png'),
|
||||
CardType(('Reaction',), 'reaction.png'),
|
||||
CardType(('Reaction', 'Shelter'), 'reaction-shelter.png'),
|
||||
CardType(('Treasure',), 'treasure.png', 3, 0),
|
||||
CardType(('Treasure', 'Attack'), 'treasure.png'),
|
||||
CardType(('Treasure', 'Victory'), 'treasure-victory.png'),
|
||||
CardType(('Treasure', 'Prize'), 'treasure.png', 3, 0),
|
||||
CardType(('Treasure', 'Reaction'), 'treasure-reaction.png', 0, 1),
|
||||
CardType(('Treasure', 'Reserve'), 'reserve-treasure.png'),
|
||||
CardType(('Victory',), 'victory.png'),
|
||||
CardType(('Victory', 'Reaction'), 'victory-reaction.png', 0, 1),
|
||||
CardType(('Victory', 'Shelter'), 'victory-shelter.png'),
|
||||
CardType(('Curse',), 'curse.png', 3),
|
||||
CardType(('Expansion',), 'expansion.png', 4),
|
||||
CardType(('Blank',), '')
|
||||
]
|
||||
|
||||
cardTypes = dict(((c.getTypeNames(), c) for c in cardTypes))
|
||||
531
domdiv/draw.py
Normal file
531
domdiv/draw.py
Normal file
@ -0,0 +1,531 @@
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
from reportlab.lib.units import cm
|
||||
from reportlab.pdfbase import pdfmetrics
|
||||
from reportlab.lib.styles import getSampleStyleSheet
|
||||
from reportlab.platypus import Paragraph
|
||||
from reportlab.lib.enums import TA_JUSTIFY
|
||||
from reportlab.pdfgen import canvas
|
||||
from reportlab.pdfbase.ttfonts import TTFont
|
||||
|
||||
|
||||
def split(l, n):
|
||||
i = 0
|
||||
while i < len(l) - n:
|
||||
yield l[i:i + n]
|
||||
i += n
|
||||
yield l[i:]
|
||||
|
||||
|
||||
class DividerDrawer(object):
|
||||
|
||||
def __init__(self):
|
||||
self.odd = True
|
||||
self.canvas = None
|
||||
|
||||
def registerFonts(self):
|
||||
try:
|
||||
dirn = os.path.join(self.options.data_path, 'fonts')
|
||||
self.fontNameRegular = 'MinionPro-Regular'
|
||||
pdfmetrics.registerFont(
|
||||
TTFont(self.fontNameRegular, os.path.join(dirn, 'MinionPro-Regular.ttf')))
|
||||
self.fontNameBold = 'MinionPro-Bold'
|
||||
pdfmetrics.registerFont(
|
||||
TTFont(self.fontNameBold, os.path.join(dirn, 'MinionPro-Bold.ttf')))
|
||||
self.fontNameOblique = 'MinionPro-Oblique'
|
||||
pdfmetrics.registerFont(
|
||||
TTFont(self.fontNameOblique, os.path.join(dirn, 'MinionPro-It.ttf')))
|
||||
except:
|
||||
print >>sys.stderr, "Warning, Minion Pro Font ttf file not found! Falling back on Times"
|
||||
self.fontNameRegular = 'Times-Roman'
|
||||
self.fontNameBold = 'Times-Bold'
|
||||
self.fontNameOblique = 'Times-Oblique'
|
||||
|
||||
def draw(self, fname, cards, options):
|
||||
self.options = options
|
||||
|
||||
self.registerFonts()
|
||||
|
||||
dividerWidth = options.dividerWidth
|
||||
dividerHeight = options.dividerHeight
|
||||
tabLabelWidth = options.labelWidth
|
||||
|
||||
self.tabOutline = [(0, 0, dividerWidth, 0),
|
||||
(dividerWidth, 0, dividerWidth, dividerHeight),
|
||||
(dividerWidth, dividerHeight,
|
||||
dividerWidth - tabLabelWidth, dividerHeight),
|
||||
(dividerWidth - tabLabelWidth,
|
||||
dividerHeight, dividerWidth - tabLabelWidth,
|
||||
dividerHeight),
|
||||
(dividerWidth - tabLabelWidth,
|
||||
dividerHeight, 0, dividerHeight),
|
||||
(0, dividerHeight, 0, 0)]
|
||||
|
||||
self.expansionTabOutline = [(0, 0, dividerWidth, 0),
|
||||
(dividerWidth, 0, dividerWidth,
|
||||
dividerHeight),
|
||||
(dividerWidth, dividerHeight,
|
||||
dividerWidth / 2 + tabLabelWidth / 2, dividerHeight),
|
||||
(dividerWidth / 2 + tabLabelWidth / 2, dividerHeight,
|
||||
dividerWidth / 2 + tabLabelWidth / 2, dividerHeight),
|
||||
(dividerWidth / 2 + tabLabelWidth / 2, dividerHeight,
|
||||
dividerWidth / 2 - tabLabelWidth / 2, dividerHeight),
|
||||
(dividerWidth / 2 - tabLabelWidth / 2, dividerHeight,
|
||||
dividerWidth / 2 - tabLabelWidth / 2, dividerHeight),
|
||||
(dividerWidth / 2 - tabLabelWidth / 2, dividerHeight,
|
||||
0, dividerHeight),
|
||||
(0, dividerHeight, 0, 0)]
|
||||
|
||||
self.canvas = canvas.Canvas(
|
||||
fname, pagesize=(options.paperwidth, options.paperheight))
|
||||
self.drawDividers(cards)
|
||||
self.canvas.save()
|
||||
|
||||
def add_inline_images(self, text, fontsize):
|
||||
path = os.path.join(self.options.data_path, 'images')
|
||||
replace = '<img src='"'%s/coin_small_\\1.png'"' width=%d height='"'100%%'"' valign='"'middle'"'/>' % (
|
||||
path, fontsize * 1.2)
|
||||
text = re.sub('(\d)\s(c|C)oin(s)?', replace, text)
|
||||
replace = '<img src='"'%s/coin_small_question.png'"' width=%d height='"'100%%'"' valign='"'middle'"'/>' % (
|
||||
path, fontsize * 1.2)
|
||||
text = re.sub('\?\s(c|C)oin(s)?', replace, text)
|
||||
replace = '<img src='"'%s/victory_emblem.png'"' width=%d height='"'120%%'"' valign='"'middle'"'/>' % (
|
||||
path, fontsize * 1.5)
|
||||
text = re.sub('\<VP\>', replace, text)
|
||||
return text
|
||||
|
||||
def drawOutline(self, x, y, rightSide, isBack=False, isExpansionDivider=False):
|
||||
# draw outline or cropmarks
|
||||
self.canvas.saveState()
|
||||
self.canvas.setLineWidth(self.options.linewidth)
|
||||
cropmarksright = (x == self.options.numDividersHorizontal - 1)
|
||||
cropmarksleft = (x == 0)
|
||||
if rightSide:
|
||||
self.canvas.translate(self.options.dividerWidth, 0)
|
||||
self.canvas.scale(-1, 1)
|
||||
if not self.options.cropmarks and not isBack:
|
||||
# don't draw outline on back, in case lines don't line up with
|
||||
# front
|
||||
if isExpansionDivider and self.options.centre_expansion_dividers:
|
||||
outline = self.expansionTabOutline
|
||||
else:
|
||||
outline = self.tabOutline
|
||||
self.canvas.lines(outline)
|
||||
elif self.options.cropmarks:
|
||||
cmw = 0.5 * cm
|
||||
|
||||
# Horizontal-line cropmarks
|
||||
mirror = cropmarksright and not rightSide or cropmarksleft and rightSide
|
||||
if mirror:
|
||||
self.canvas.saveState()
|
||||
self.canvas.translate(self.options.dividerWidth, 0)
|
||||
self.canvas.scale(-1, 1)
|
||||
if cropmarksleft or cropmarksright:
|
||||
self.canvas.line(-2 * cmw, 0, -cmw, 0)
|
||||
self.canvas.line(-2 * cmw,
|
||||
self.dividerHeight, -cmw, self.dividerHeight)
|
||||
if y > 0:
|
||||
self.canvas.line(-2 * cmw,
|
||||
self.options.dividerHeight, -cmw, self.options.dividerHeight)
|
||||
if mirror:
|
||||
self.canvas.restoreState()
|
||||
|
||||
# Vertical-line cropmarks
|
||||
|
||||
# want to always draw the right-edge and middle-label-edge lines..
|
||||
# ...and draw the left-edge if this is the first card on the left
|
||||
|
||||
# ...but we need to take mirroring into account, to know "where"
|
||||
# to draw the left / right lines...
|
||||
if rightSide:
|
||||
leftLine = self.options.dividerWidth
|
||||
rightLine = 0
|
||||
else:
|
||||
leftLine = 0
|
||||
rightLine = self.options.dividerWidth
|
||||
middleLine = self.options.dividerWidth - self.options.labelWidth
|
||||
|
||||
if y == 0:
|
||||
self.canvas.line(rightLine, -2 * cmw, rightLine, -cmw)
|
||||
self.canvas.line(middleLine, -2 * cmw, middleLine, -cmw)
|
||||
if cropmarksleft:
|
||||
self.canvas.line(leftLine, -2 * cmw, leftLine, -cmw)
|
||||
if y == self.options.numDividersVertical - 1:
|
||||
self.canvas.line(rightLine, self.options.dividerHeight + cmw,
|
||||
rightLine, self.options.dividerHeight + 2 * cmw)
|
||||
self.canvas.line(middleLine, self.options.dividerHeight + cmw,
|
||||
middleLine, self.options.dividerHeight + 2 * cmw)
|
||||
if cropmarksleft:
|
||||
self.canvas.line(leftLine, self.options.dividerHeight + cmw,
|
||||
leftLine, self.options.dividerHeight + 2 * cmw)
|
||||
|
||||
self.canvas.restoreState()
|
||||
|
||||
def drawCost(self, card, x, y, costOffset=-1):
|
||||
# base width is 16 (for image) + 2 (1 pt border on each side)
|
||||
width = 18
|
||||
|
||||
costHeight = y + costOffset
|
||||
coinHeight = costHeight - 5
|
||||
potHeight = y - 3
|
||||
potSize = 11
|
||||
|
||||
self.canvas.drawImage(os.path.join(self.options.data_path, 'images', 'coin_small.png'),
|
||||
x, coinHeight, 16, 16, preserveAspectRatio=True, mask='auto')
|
||||
if card.potcost:
|
||||
self.canvas.drawImage(os.path.join(self.options.data_path, 'images', 'potion.png'), x + 17,
|
||||
potHeight, potSize, potSize, preserveAspectRatio=True,
|
||||
mask=[255, 255, 255, 255, 255, 255])
|
||||
width += potSize
|
||||
|
||||
self.canvas.setFont(self.fontNameBold, 12)
|
||||
cost = str(card.cost)
|
||||
self.canvas.drawCentredString(x + 8, costHeight, cost)
|
||||
return width
|
||||
|
||||
def drawSetIcon(self, setImage, x, y):
|
||||
# set image
|
||||
self.canvas.drawImage(
|
||||
os.path.join(self.options.data_path, 'images', setImage), x, y, 14, 12, mask='auto')
|
||||
|
||||
def nameWidth(self, name, fontSize):
|
||||
w = 0
|
||||
name_parts = name.split()
|
||||
for i, part in enumerate(name_parts):
|
||||
if i != 0:
|
||||
w += pdfmetrics.stringWidth(' ', self.fontNameRegular, fontSize)
|
||||
w += pdfmetrics.stringWidth(part[0], self.fontNameRegular, fontSize)
|
||||
w += pdfmetrics.stringWidth(part[1:],
|
||||
self.fontNameRegular, fontSize - 2)
|
||||
return w
|
||||
|
||||
def drawTab(self, card, rightSide):
|
||||
# draw tab flap
|
||||
self.canvas.saveState()
|
||||
if card.isExpansion() and self.options.centre_expansion_dividers:
|
||||
self.canvas.translate(self.options.dividerWidth / 2 - self.options.labelWidth / 2,
|
||||
self.options.dividerHeight - self.options.labelHeight)
|
||||
elif not rightSide:
|
||||
self.canvas.translate(self.options.dividerWidth - self.options.labelWidth,
|
||||
self.options.dividerHeight - self.options.labelHeight)
|
||||
else:
|
||||
self.canvas.translate(0, self.options.dividerHeight - self.options.labelHeight)
|
||||
|
||||
# allow for 3 pt border on each side
|
||||
textWidth = self.options.labelWidth - 6
|
||||
textHeight = 7
|
||||
if self.options.no_tab_artwork:
|
||||
textHeight = 4
|
||||
textHeight = self.options.labelHeight / 2 - textHeight + \
|
||||
card.getType().getTabTextHeightOffset()
|
||||
|
||||
# draw banner
|
||||
img = card.getType().getNoCoinTabImageFile()
|
||||
if not self.options.no_tab_artwork and img:
|
||||
self.canvas.drawImage(os.path.join(self.options.data_path, 'images', img), 1, 0,
|
||||
self.options.labelWidth -
|
||||
2, self.options.labelHeight - 1,
|
||||
preserveAspectRatio=False, anchor='n', mask='auto')
|
||||
|
||||
# draw cost
|
||||
if not card.isExpansion() and not card.isBlank():
|
||||
if 'tab' in self.options.cost:
|
||||
textInset = 4
|
||||
textInset += self.drawCost(card, textInset, textHeight,
|
||||
card.getType().getTabCostHeightOffset())
|
||||
else:
|
||||
textInset = 6
|
||||
else:
|
||||
textInset = 13
|
||||
|
||||
# draw set image
|
||||
# always need to offset from right edge, to make sure it stays on
|
||||
# banner
|
||||
textInsetRight = 6
|
||||
if self.options.use_text_set_icon:
|
||||
setImageHeight = card.getType().getTabTextHeightOffset()
|
||||
setText = card.setTextIcon()
|
||||
self.canvas.setFont(self.fontNameOblique, 8)
|
||||
if setText is None:
|
||||
setText = ""
|
||||
|
||||
self.canvas.drawCentredString(self.options.labelWidth - 10, textHeight + 2, setText)
|
||||
textInsetRight = 15
|
||||
else:
|
||||
setImage = card.setImage()
|
||||
if setImage and 'tab' in self.options.set_icon:
|
||||
setImageHeight = 3 + card.getType().getTabTextHeightOffset()
|
||||
|
||||
self.drawSetIcon(setImage, self.options.labelWidth - 20,
|
||||
setImageHeight)
|
||||
|
||||
textInsetRight = 20
|
||||
|
||||
# draw name
|
||||
fontSize = 12
|
||||
name = card.name.upper()
|
||||
|
||||
textWidth -= textInset
|
||||
textWidth -= textInsetRight
|
||||
|
||||
width = self.nameWidth(name, fontSize)
|
||||
while width > textWidth and fontSize > 8:
|
||||
fontSize -= .01
|
||||
# print 'decreasing font size for tab of',name,'now',fontSize
|
||||
width = self.nameWidth(name, fontSize)
|
||||
tooLong = width > textWidth
|
||||
if tooLong:
|
||||
name_lines = name.partition(' / ')
|
||||
if name_lines[1]:
|
||||
name_lines = (name_lines[0] + ' /', name_lines[2])
|
||||
else:
|
||||
name_lines = name.split(None, 1)
|
||||
else:
|
||||
name_lines = [name]
|
||||
# if tooLong:
|
||||
# print name
|
||||
|
||||
for linenum, line in enumerate(name_lines):
|
||||
h = textHeight
|
||||
if tooLong and len(name_lines) > 1:
|
||||
if linenum == 0:
|
||||
h += h / 2
|
||||
else:
|
||||
h -= h / 2
|
||||
|
||||
words = line.split()
|
||||
if (not self.options.tab_name_align == "right") and (self.options.tab_name_align == "centre" or
|
||||
rightSide or
|
||||
not self.options.tab_name_align == "edge"):
|
||||
if self.options.tab_name_align == "centre":
|
||||
w = self.options.labelWidth / 2 - self.nameWidth(line, fontSize) / 2
|
||||
else:
|
||||
w = textInset
|
||||
|
||||
def drawWordPiece(text, fontSize):
|
||||
self.canvas.setFont(self.fontNameRegular, fontSize)
|
||||
if text != ' ':
|
||||
self.canvas.drawString(w, h, text)
|
||||
return pdfmetrics.stringWidth(text, self.fontNameRegular, fontSize)
|
||||
for i, word in enumerate(words):
|
||||
if i != 0:
|
||||
w += drawWordPiece(' ', fontSize)
|
||||
w += drawWordPiece(word[0], fontSize)
|
||||
w += drawWordPiece(word[1:], fontSize - 2)
|
||||
else:
|
||||
# align text to the right if tab is on right side, to make
|
||||
# tabs easier to read when grouped together extra 3pt is for
|
||||
# space between text + set symbol
|
||||
|
||||
w = self.options.labelWidth - textInsetRight - 3
|
||||
words.reverse()
|
||||
|
||||
def drawWordPiece(text, fontSize):
|
||||
self.canvas.setFont(self.fontNameRegular, fontSize)
|
||||
if text != ' ':
|
||||
self.canvas.drawRightString(w, h, text)
|
||||
return -pdfmetrics.stringWidth(text, self.fontNameRegular, fontSize)
|
||||
for i, word in enumerate(words):
|
||||
w += drawWordPiece(word[1:], fontSize - 2)
|
||||
w += drawWordPiece(word[0], fontSize)
|
||||
if i != len(words) - 1:
|
||||
w += drawWordPiece(' ', fontSize)
|
||||
self.canvas.restoreState()
|
||||
|
||||
def drawText(self, card, useExtra=False):
|
||||
usedHeight = 0
|
||||
totalHeight = self.options.dividerHeight - self.options.labelHeight
|
||||
|
||||
drewTopIcon = False
|
||||
if 'body-top' in self.options.cost and not card.isExpansion():
|
||||
self.drawCost(card, cm / 4.0, totalHeight - 0.5 * cm)
|
||||
drewTopIcon = True
|
||||
|
||||
if 'body-top' in self.options.set_icon and not card.isExpansion():
|
||||
setImage = card.setImage()
|
||||
if setImage:
|
||||
self.drawSetIcon(setImage, self.options.dividerWidth - 16,
|
||||
totalHeight - 0.5 * cm - 3)
|
||||
drewTopIcon = True
|
||||
if drewTopIcon:
|
||||
usedHeight += 15
|
||||
|
||||
if self.options.no_card_rules:
|
||||
return
|
||||
|
||||
# draw text
|
||||
if useExtra and card.extra:
|
||||
descriptions = (card.extra,)
|
||||
else:
|
||||
descriptions = re.split("\n", card.description)
|
||||
|
||||
s = getSampleStyleSheet()['BodyText']
|
||||
s.fontName = "Times-Roman"
|
||||
s.alignment = TA_JUSTIFY
|
||||
|
||||
textHorizontalMargin = .5 * cm
|
||||
textVerticalMargin = .3 * cm
|
||||
textBoxWidth = self.options.dividerWidth - 2 * textHorizontalMargin
|
||||
textBoxHeight = totalHeight - usedHeight - 2 * textVerticalMargin
|
||||
spacerHeight = 0.2 * cm
|
||||
minSpacerHeight = 0.05 * cm
|
||||
|
||||
while True:
|
||||
paragraphs = []
|
||||
# this accounts for the spacers we insert between paragraphs
|
||||
h = (len(descriptions) - 1) * spacerHeight
|
||||
for d in descriptions:
|
||||
dmod = self.add_inline_images(d, s.fontSize)
|
||||
p = Paragraph(dmod, s)
|
||||
h += p.wrap(textBoxWidth, textBoxHeight)[1]
|
||||
paragraphs.append(p)
|
||||
|
||||
if h <= textBoxHeight or s.fontSize <= 1 or s.leading <= 1:
|
||||
break
|
||||
else:
|
||||
s.fontSize -= 1
|
||||
s.leading -= 1
|
||||
spacerHeight = max(spacerHeight - 1, minSpacerHeight)
|
||||
|
||||
h = totalHeight - usedHeight - textVerticalMargin
|
||||
for p in paragraphs:
|
||||
h -= p.height
|
||||
p.drawOn(self.canvas, textHorizontalMargin, h)
|
||||
h -= spacerHeight
|
||||
|
||||
def drawDivider(self, card, x, y, useExtra=False):
|
||||
# figure out whether the tab should go on the right side or not
|
||||
if self.options.tab_side == "right":
|
||||
rightSide = useExtra
|
||||
elif self.options.tab_side in ["left", "full"]:
|
||||
rightSide = not useExtra
|
||||
else:
|
||||
# alternate the cards
|
||||
if not useExtra:
|
||||
rightSide = not self.odd
|
||||
else:
|
||||
rightSide = self.odd
|
||||
|
||||
# apply the transforms to get us to the corner of the current card
|
||||
self.canvas.resetTransforms()
|
||||
self.canvas.translate(self.options.horizontalMargin, self.options.verticalMargin)
|
||||
if useExtra:
|
||||
self.canvas.translate(self.options.back_offset, self.options.back_offset_height)
|
||||
self.canvas.translate(x * self.options.dividerWidthReserved,
|
||||
y * self.options.dividerHeightReserved)
|
||||
|
||||
# actual drawing
|
||||
if not self.options.tabs_only:
|
||||
self.drawOutline(
|
||||
x, y, rightSide, useExtra, card.getType().getTypeNames() == ('Expansion',))
|
||||
self.drawTab(card, rightSide)
|
||||
if not self.options.tabs_only:
|
||||
self.drawText(card, useExtra)
|
||||
|
||||
def drawSetNames(self, pageCards):
|
||||
# print sets for this page
|
||||
self.canvas.saveState()
|
||||
|
||||
try:
|
||||
# calculate the text height, font size, and orientation
|
||||
maxFontsize = 12
|
||||
minFontsize = 6
|
||||
fontname = self.fontNameRegular
|
||||
font = pdfmetrics.getFont(fontname)
|
||||
fontHeightRelative = (font.face.ascent + abs(font.face.descent)) / 1000.0
|
||||
|
||||
canFit = False
|
||||
|
||||
layouts = [{'rotation': 0,
|
||||
'minMarginHeight': self.options.minVerticalMargin,
|
||||
'totalMarginHeight': self.options.verticalMargin,
|
||||
'width': self.options.paperwidth},
|
||||
{'rotation': 90,
|
||||
'minMarginHeight': self.options.minHorizontalMargin,
|
||||
'totalMarginHeight': self.options.horizontalMargin,
|
||||
'width': self.options.paperheight}]
|
||||
|
||||
for layout in layouts:
|
||||
availableMargin = layout[
|
||||
'totalMarginHeight'] - layout['minMarginHeight']
|
||||
fontsize = availableMargin / fontHeightRelative
|
||||
fontsize = min(maxFontsize, fontsize)
|
||||
if fontsize >= minFontsize:
|
||||
canFit = True
|
||||
break
|
||||
|
||||
if not canFit:
|
||||
import warnings
|
||||
warnings.warn("Not enough space to display set names")
|
||||
return
|
||||
|
||||
self.canvas.setFont(fontname, fontsize)
|
||||
|
||||
sets = []
|
||||
for c in pageCards:
|
||||
setTitle = c.cardset.title()
|
||||
if setTitle not in sets:
|
||||
sets.append(setTitle)
|
||||
|
||||
# Centered on page
|
||||
xPos = layout['width'] / 2
|
||||
# Place at the very edge of the margin
|
||||
yPos = layout['minMarginHeight']
|
||||
|
||||
if layout['rotation']:
|
||||
self.canvas.rotate(layout['rotation'])
|
||||
yPos = -yPos
|
||||
|
||||
self.canvas.drawCentredString(xPos, yPos, '/'.join(sets))
|
||||
finally:
|
||||
self.canvas.restoreState()
|
||||
|
||||
def drawDividers(self, cards):
|
||||
# split into pages
|
||||
cards = split(cards, self.options.numDividersVertical * self.options.numDividersHorizontal)
|
||||
|
||||
# Starting with tabs on the left or the right?
|
||||
if self.options.tab_side in ["right-alternate", "right"]:
|
||||
self.odd = True
|
||||
else:
|
||||
# left-alternate, left, full
|
||||
self.odd = False
|
||||
|
||||
for pageNum, pageCards in enumerate(cards):
|
||||
# remember whether we start with odd or even divider for tab
|
||||
# location
|
||||
pageStartOdd = self.odd
|
||||
if not self.options.no_page_footer and (not self.options.tabs_only and self.options.order != "global"):
|
||||
self.drawSetNames(pageCards)
|
||||
for i, card in enumerate(pageCards):
|
||||
# print card
|
||||
x = i % self.options.numDividersHorizontal
|
||||
y = i / self.options.numDividersHorizontal
|
||||
self.canvas.saveState()
|
||||
self.drawDivider(card, x, self.options.numDividersVertical - 1 - y)
|
||||
self.canvas.restoreState()
|
||||
self.odd = not self.odd
|
||||
self.canvas.showPage()
|
||||
if pageNum + 1 == self.options.num_pages:
|
||||
break
|
||||
if self.options.tabs_only or self.options.no_card_backs:
|
||||
# no set names or card backs for label-only sheets
|
||||
continue
|
||||
if not self.options.no_page_footer and self.options.order != "global":
|
||||
self.drawSetNames(pageCards)
|
||||
# start at same oddness
|
||||
self.odd = pageStartOdd
|
||||
for i, card in enumerate(pageCards):
|
||||
# print card
|
||||
x = (self.options.numDividersHorizontal - 1 - i) % self.options.numDividersHorizontal
|
||||
y = i / self.options.numDividersHorizontal
|
||||
self.canvas.saveState()
|
||||
self.drawDivider(
|
||||
card, x, self.options.numDividersVertical - 1 - y, useExtra=True)
|
||||
self.canvas.restoreState()
|
||||
self.odd = not self.odd
|
||||
self.canvas.showPage()
|
||||
if pageNum + 1 == self.options.num_pages:
|
||||
break
|
||||
6
dominion_dividers.py
Normal file
6
dominion_dividers.py
Normal file
@ -0,0 +1,6 @@
|
||||
import domdiv
|
||||
import os
|
||||
import sys
|
||||
|
||||
if __name__ == '__main__':
|
||||
domdiv.main(sys.argv[1:], os.path.dirname(__file__))
|
||||
1213
dominion_tabs.py
1213
dominion_tabs.py
File diff suppressed because it is too large
Load Diff
391
ez_setup.py
Normal file
391
ez_setup.py
Normal file
@ -0,0 +1,391 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Setuptools bootstrapping installer.
|
||||
|
||||
Run this script to install or upgrade setuptools.
|
||||
"""
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import tempfile
|
||||
import zipfile
|
||||
import optparse
|
||||
import subprocess
|
||||
import platform
|
||||
import textwrap
|
||||
import contextlib
|
||||
import warnings
|
||||
|
||||
from distutils import log
|
||||
|
||||
try:
|
||||
from urllib.request import urlopen
|
||||
except ImportError:
|
||||
from urllib2 import urlopen
|
||||
|
||||
try:
|
||||
from site import USER_SITE
|
||||
except ImportError:
|
||||
USER_SITE = None
|
||||
|
||||
DEFAULT_VERSION = "18.5"
|
||||
DEFAULT_URL = "https://pypi.python.org/packages/source/s/setuptools/"
|
||||
DEFAULT_SAVE_DIR = os.curdir
|
||||
|
||||
|
||||
def _python_cmd(*args):
|
||||
"""
|
||||
Execute a command.
|
||||
|
||||
Return True if the command succeeded.
|
||||
"""
|
||||
args = (sys.executable,) + args
|
||||
return subprocess.call(args) == 0
|
||||
|
||||
|
||||
def _install(archive_filename, install_args=()):
|
||||
"""Install Setuptools."""
|
||||
with archive_context(archive_filename):
|
||||
# installing
|
||||
log.warn('Installing Setuptools')
|
||||
if not _python_cmd('setup.py', 'install', *install_args):
|
||||
log.warn('Something went wrong during the installation.')
|
||||
log.warn('See the error message above.')
|
||||
# exitcode will be 2
|
||||
return 2
|
||||
|
||||
|
||||
def _build_egg(egg, archive_filename, to_dir):
|
||||
"""Build Setuptools egg."""
|
||||
with archive_context(archive_filename):
|
||||
# building an egg
|
||||
log.warn('Building a Setuptools egg in %s', to_dir)
|
||||
_python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir)
|
||||
# returning the result
|
||||
log.warn(egg)
|
||||
if not os.path.exists(egg):
|
||||
raise IOError('Could not build the egg.')
|
||||
|
||||
|
||||
class ContextualZipFile(zipfile.ZipFile):
|
||||
|
||||
"""Supplement ZipFile class to support context manager for Python 2.6."""
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, type, value, traceback):
|
||||
self.close()
|
||||
|
||||
def __new__(cls, *args, **kwargs):
|
||||
"""Construct a ZipFile or ContextualZipFile as appropriate."""
|
||||
if hasattr(zipfile.ZipFile, '__exit__'):
|
||||
return zipfile.ZipFile(*args, **kwargs)
|
||||
return super(ContextualZipFile, cls).__new__(cls)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def archive_context(filename):
|
||||
"""
|
||||
Unzip filename to a temporary directory, set to the cwd.
|
||||
|
||||
The unzipped target is cleaned up after.
|
||||
"""
|
||||
tmpdir = tempfile.mkdtemp()
|
||||
log.warn('Extracting in %s', tmpdir)
|
||||
old_wd = os.getcwd()
|
||||
try:
|
||||
os.chdir(tmpdir)
|
||||
with ContextualZipFile(filename) as archive:
|
||||
archive.extractall()
|
||||
|
||||
# going in the directory
|
||||
subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
|
||||
os.chdir(subdir)
|
||||
log.warn('Now working in %s', subdir)
|
||||
yield
|
||||
|
||||
finally:
|
||||
os.chdir(old_wd)
|
||||
shutil.rmtree(tmpdir)
|
||||
|
||||
|
||||
def _do_download(version, download_base, to_dir, download_delay):
|
||||
"""Download Setuptools."""
|
||||
egg = os.path.join(to_dir, 'setuptools-%s-py%d.%d.egg'
|
||||
% (version, sys.version_info[0], sys.version_info[1]))
|
||||
if not os.path.exists(egg):
|
||||
archive = download_setuptools(version, download_base,
|
||||
to_dir, download_delay)
|
||||
_build_egg(egg, archive, to_dir)
|
||||
sys.path.insert(0, egg)
|
||||
|
||||
# Remove previously-imported pkg_resources if present (see
|
||||
# https://bitbucket.org/pypa/setuptools/pull-request/7/ for details).
|
||||
if 'pkg_resources' in sys.modules:
|
||||
del sys.modules['pkg_resources']
|
||||
|
||||
import setuptools
|
||||
setuptools.bootstrap_install_from = egg
|
||||
|
||||
|
||||
def use_setuptools(
|
||||
version=DEFAULT_VERSION, download_base=DEFAULT_URL,
|
||||
to_dir=DEFAULT_SAVE_DIR, download_delay=15):
|
||||
"""
|
||||
Ensure that a setuptools version is installed.
|
||||
|
||||
Return None. Raise SystemExit if the requested version
|
||||
or later cannot be installed.
|
||||
"""
|
||||
to_dir = os.path.abspath(to_dir)
|
||||
|
||||
# prior to importing, capture the module state for
|
||||
# representative modules.
|
||||
rep_modules = 'pkg_resources', 'setuptools'
|
||||
imported = set(sys.modules).intersection(rep_modules)
|
||||
|
||||
try:
|
||||
import pkg_resources
|
||||
pkg_resources.require("setuptools>=" + version)
|
||||
# a suitable version is already installed
|
||||
return
|
||||
except ImportError:
|
||||
# pkg_resources not available; setuptools is not installed; download
|
||||
pass
|
||||
except pkg_resources.DistributionNotFound:
|
||||
# no version of setuptools was found; allow download
|
||||
pass
|
||||
except pkg_resources.VersionConflict as VC_err:
|
||||
if imported:
|
||||
_conflict_bail(VC_err, version)
|
||||
|
||||
# otherwise, unload pkg_resources to allow the downloaded version to
|
||||
# take precedence.
|
||||
del pkg_resources
|
||||
_unload_pkg_resources()
|
||||
|
||||
return _do_download(version, download_base, to_dir, download_delay)
|
||||
|
||||
|
||||
def _conflict_bail(VC_err, version):
|
||||
"""
|
||||
Setuptools was imported prior to invocation, so it is
|
||||
unsafe to unload it. Bail out.
|
||||
"""
|
||||
conflict_tmpl = textwrap.dedent("""
|
||||
The required version of setuptools (>={version}) is not available,
|
||||
and can't be installed while this script is running. Please
|
||||
install a more recent version first, using
|
||||
'easy_install -U setuptools'.
|
||||
|
||||
(Currently using {VC_err.args[0]!r})
|
||||
""")
|
||||
msg = conflict_tmpl.format(**locals())
|
||||
sys.stderr.write(msg)
|
||||
sys.exit(2)
|
||||
|
||||
|
||||
def _unload_pkg_resources():
|
||||
del_modules = [
|
||||
name for name in sys.modules
|
||||
if name.startswith('pkg_resources')
|
||||
]
|
||||
for mod_name in del_modules:
|
||||
del sys.modules[mod_name]
|
||||
|
||||
|
||||
def _clean_check(cmd, target):
|
||||
"""
|
||||
Run the command to download target.
|
||||
|
||||
If the command fails, clean up before re-raising the error.
|
||||
"""
|
||||
try:
|
||||
subprocess.check_call(cmd)
|
||||
except subprocess.CalledProcessError:
|
||||
if os.access(target, os.F_OK):
|
||||
os.unlink(target)
|
||||
raise
|
||||
|
||||
|
||||
def download_file_powershell(url, target):
|
||||
"""
|
||||
Download the file at url to target using Powershell.
|
||||
|
||||
Powershell will validate trust.
|
||||
Raise an exception if the command cannot complete.
|
||||
"""
|
||||
target = os.path.abspath(target)
|
||||
ps_cmd = (
|
||||
"[System.Net.WebRequest]::DefaultWebProxy.Credentials = "
|
||||
"[System.Net.CredentialCache]::DefaultCredentials; "
|
||||
"(new-object System.Net.WebClient).DownloadFile(%(url)r, %(target)r)"
|
||||
% vars()
|
||||
)
|
||||
cmd = [
|
||||
'powershell',
|
||||
'-Command',
|
||||
ps_cmd,
|
||||
]
|
||||
_clean_check(cmd, target)
|
||||
|
||||
|
||||
def has_powershell():
|
||||
"""Determine if Powershell is available."""
|
||||
if platform.system() != 'Windows':
|
||||
return False
|
||||
cmd = ['powershell', '-Command', 'echo test']
|
||||
with open(os.path.devnull, 'wb') as devnull:
|
||||
try:
|
||||
subprocess.check_call(cmd, stdout=devnull, stderr=devnull)
|
||||
except Exception:
|
||||
return False
|
||||
return True
|
||||
download_file_powershell.viable = has_powershell
|
||||
|
||||
|
||||
def download_file_curl(url, target):
|
||||
cmd = ['curl', url, '--silent', '--output', target]
|
||||
_clean_check(cmd, target)
|
||||
|
||||
|
||||
def has_curl():
|
||||
cmd = ['curl', '--version']
|
||||
with open(os.path.devnull, 'wb') as devnull:
|
||||
try:
|
||||
subprocess.check_call(cmd, stdout=devnull, stderr=devnull)
|
||||
except Exception:
|
||||
return False
|
||||
return True
|
||||
download_file_curl.viable = has_curl
|
||||
|
||||
|
||||
def download_file_wget(url, target):
|
||||
cmd = ['wget', url, '--quiet', '--output-document', target]
|
||||
_clean_check(cmd, target)
|
||||
|
||||
|
||||
def has_wget():
|
||||
cmd = ['wget', '--version']
|
||||
with open(os.path.devnull, 'wb') as devnull:
|
||||
try:
|
||||
subprocess.check_call(cmd, stdout=devnull, stderr=devnull)
|
||||
except Exception:
|
||||
return False
|
||||
return True
|
||||
download_file_wget.viable = has_wget
|
||||
|
||||
|
||||
def download_file_insecure(url, target):
|
||||
"""Use Python to download the file, without connection authentication."""
|
||||
src = urlopen(url)
|
||||
try:
|
||||
# Read all the data in one block.
|
||||
data = src.read()
|
||||
finally:
|
||||
src.close()
|
||||
|
||||
# Write all the data in one block to avoid creating a partial file.
|
||||
with open(target, "wb") as dst:
|
||||
dst.write(data)
|
||||
download_file_insecure.viable = lambda: True
|
||||
|
||||
|
||||
def get_best_downloader():
|
||||
downloaders = (
|
||||
download_file_powershell,
|
||||
download_file_curl,
|
||||
download_file_wget,
|
||||
download_file_insecure,
|
||||
)
|
||||
viable_downloaders = (dl for dl in downloaders if dl.viable())
|
||||
return next(viable_downloaders, None)
|
||||
|
||||
|
||||
def download_setuptools(
|
||||
version=DEFAULT_VERSION, download_base=DEFAULT_URL,
|
||||
to_dir=DEFAULT_SAVE_DIR, delay=15,
|
||||
downloader_factory=get_best_downloader):
|
||||
"""
|
||||
Download setuptools from a specified location and return its filename.
|
||||
|
||||
`version` should be a valid setuptools version number that is available
|
||||
as an sdist for download under the `download_base` URL (which should end
|
||||
with a '/'). `to_dir` is the directory where the egg will be downloaded.
|
||||
`delay` is the number of seconds to pause before an actual download
|
||||
attempt.
|
||||
|
||||
``downloader_factory`` should be a function taking no arguments and
|
||||
returning a function for downloading a URL to a target.
|
||||
"""
|
||||
# making sure we use the absolute path
|
||||
to_dir = os.path.abspath(to_dir)
|
||||
zip_name = "setuptools-%s.zip" % version
|
||||
url = download_base + zip_name
|
||||
saveto = os.path.join(to_dir, zip_name)
|
||||
if not os.path.exists(saveto): # Avoid repeated downloads
|
||||
log.warn("Downloading %s", url)
|
||||
downloader = downloader_factory()
|
||||
downloader(url, saveto)
|
||||
return os.path.realpath(saveto)
|
||||
|
||||
|
||||
def _build_install_args(options):
|
||||
"""
|
||||
Build the arguments to 'python setup.py install' on the setuptools package.
|
||||
|
||||
Returns list of command line arguments.
|
||||
"""
|
||||
return ['--user'] if options.user_install else []
|
||||
|
||||
|
||||
def _parse_args():
|
||||
"""Parse the command line for options."""
|
||||
parser = optparse.OptionParser()
|
||||
parser.add_option(
|
||||
'--user', dest='user_install', action='store_true', default=False,
|
||||
help='install in user site package (requires Python 2.6 or later)')
|
||||
parser.add_option(
|
||||
'--download-base', dest='download_base', metavar="URL",
|
||||
default=DEFAULT_URL,
|
||||
help='alternative URL from where to download the setuptools package')
|
||||
parser.add_option(
|
||||
'--insecure', dest='downloader_factory', action='store_const',
|
||||
const=lambda: download_file_insecure, default=get_best_downloader,
|
||||
help='Use internal, non-validating downloader'
|
||||
)
|
||||
parser.add_option(
|
||||
'--version', help="Specify which version to download",
|
||||
default=DEFAULT_VERSION,
|
||||
)
|
||||
parser.add_option(
|
||||
'--to-dir',
|
||||
help="Directory to save (and re-use) package",
|
||||
default=DEFAULT_SAVE_DIR,
|
||||
)
|
||||
options, args = parser.parse_args()
|
||||
# positional arguments are ignored
|
||||
return options
|
||||
|
||||
|
||||
def _download_args(options):
|
||||
"""Return args for download_setuptools function from cmdline args."""
|
||||
return dict(
|
||||
version=options.version,
|
||||
download_base=options.download_base,
|
||||
downloader_factory=options.downloader_factory,
|
||||
to_dir=options.to_dir,
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
"""Install or upgrade setuptools and EasyInstall."""
|
||||
options = _parse_args()
|
||||
archive = download_setuptools(**_download_args(options))
|
||||
return _install(archive, _build_install_args(options))
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
17
setup.py
17
setup.py
@ -1,5 +1,5 @@
|
||||
from __init__ import __version__
|
||||
from distribute_setup import use_setuptools
|
||||
from ez_setup import use_setuptools
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
use_setuptools()
|
||||
@ -8,16 +8,19 @@ use_setuptools()
|
||||
setup(
|
||||
name="dominiontabs",
|
||||
version=__version__,
|
||||
scripts=["dominion_tabs.py"],
|
||||
packages=find_packages(),
|
||||
entry_points={
|
||||
'console_scripts': [
|
||||
"dominion_dividers = domdiv.main:main"
|
||||
],
|
||||
},
|
||||
packages=find_packages(exclude=['tests']),
|
||||
install_requires=["reportlab>=2.5",
|
||||
"Pillow>=2.1.0",
|
||||
"PyYAML"],
|
||||
"Pillow>=2.1.0"],
|
||||
package_data={
|
||||
'': ['*.txt', '*.png']
|
||||
'domdiv': ['images/*.png', 'card_db/*/*.json']
|
||||
},
|
||||
author="Sumpfork",
|
||||
author_email="sumpfork@mailmight.net",
|
||||
description="Tab Divider Generation for the Dominion Card Game"
|
||||
description="Divider Generation for the Dominion Card Game"
|
||||
)
|
||||
|
||||
|
||||
0
tests/__init__.py
Normal file
0
tests/__init__.py
Normal file
47
tests/carddb_tests.py
Normal file
47
tests/carddb_tests.py
Normal file
@ -0,0 +1,47 @@
|
||||
import unittest
|
||||
from .. import domdiv
|
||||
from ..domdiv import cards as domdiv_cards
|
||||
|
||||
|
||||
class TestCardDB(unittest.TestCase):
|
||||
|
||||
def test_cardread(self):
|
||||
options, args = domdiv.parse_opts(['commandname'])
|
||||
options.data_path = '.'
|
||||
cards = domdiv.read_write_card_data(options)
|
||||
self.assertEquals(len(cards), 312)
|
||||
print set(c.cardset for c in cards)
|
||||
valid_cardsets = {
|
||||
u'prosperity',
|
||||
u'cornucopia extras',
|
||||
u'cornucopia',
|
||||
u'promo',
|
||||
u'adventures extras',
|
||||
u'seaside',
|
||||
u'adventures',
|
||||
u'dark ages',
|
||||
u'hinterlands',
|
||||
u'dark ages extras',
|
||||
u'alchemy',
|
||||
u'base',
|
||||
u'dominion',
|
||||
u'guilds',
|
||||
u'intrigue'
|
||||
}
|
||||
for c in cards:
|
||||
self.assertIsInstance(c, domdiv_cards.Card)
|
||||
self.assertIn(c.cardset, valid_cardsets)
|
||||
|
||||
def test_languages(self):
|
||||
# for now, just test that they load
|
||||
options, args = domdiv.parse_opts(['commandname', '--language', 'it'])
|
||||
options.data_path = '.'
|
||||
cards = domdiv.read_write_card_data(options)
|
||||
self.assertTrue(cards, 'Italians cards did not read properly')
|
||||
self.assertIn("Maledizione", [card.name for card in cards])
|
||||
|
||||
options, args = domdiv.parse_opts(['commandname', '--language', 'de'])
|
||||
options.data_path = '.'
|
||||
cards = domdiv.read_write_card_data(options)
|
||||
self.assertTrue(cards, 'German cards did not read properly')
|
||||
self.assertIn("Fluch", [card.name for card in cards])
|
||||
35
tests/layout_tests.py
Normal file
35
tests/layout_tests.py
Normal file
@ -0,0 +1,35 @@
|
||||
import unittest
|
||||
from .. import domdiv
|
||||
from reportlab.lib.units import cm
|
||||
|
||||
|
||||
class TestLayout(unittest.TestCase):
|
||||
|
||||
def test_horizontal(self):
|
||||
# should be the default
|
||||
options, args = domdiv.parse_opts(['commandname'])
|
||||
self.assertEquals(options.orientation, 'horizontal')
|
||||
domdiv.calculate_layout(options)
|
||||
self.assertEquals(options.numDividersHorizontal, 2)
|
||||
self.assertEquals(options.numDividersVertical, 3)
|
||||
self.assertEquals(options.dividerWidth, 9.1 * cm)
|
||||
self.assertEquals(options.labelHeight, 0.9 * cm)
|
||||
self.assertEquals(options.dividerHeight, 5.9 * cm + options.labelHeight)
|
||||
|
||||
def test_vertical(self):
|
||||
options, args = domdiv.parse_opts(['commandname', '--orientation', 'vertical'])
|
||||
self.assertEquals(options.orientation, 'vertical')
|
||||
domdiv.calculate_layout(options)
|
||||
self.assertEquals(options.numDividersHorizontal, 3)
|
||||
self.assertEquals(options.numDividersVertical, 2)
|
||||
self.assertEquals(options.dividerWidth, 5.9 * cm)
|
||||
self.assertEquals(options.labelHeight, 0.9 * cm)
|
||||
self.assertEquals(options.dividerHeight, 9.1 * cm + options.labelHeight)
|
||||
|
||||
def test_sleeved(self):
|
||||
options, args = domdiv.parse_opts(['commandname', '--size', 'sleeved'])
|
||||
domdiv.calculate_layout(options)
|
||||
self.assertEquals(options.dividerWidth, 9.4 * cm)
|
||||
self.assertEquals(options.labelHeight, 0.9 * cm)
|
||||
self.assertEquals(options.dividerHeight, 6.15 * cm + options.labelHeight)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user