stsdb 0.1.2__tar.gz → 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: stsdb
3
- Version: 0.1.2
3
+ Version: 0.2.0
4
4
  Summary: Deterministic Slay the Spire card and relic query toolset
5
5
  Author: Taardisaa
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "stsdb"
7
- version = "0.1.2"
7
+ version = "0.2.0"
8
8
  description = "Deterministic Slay the Spire card and relic query toolset"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -0,0 +1,3 @@
1
+ from .core import query_card, query_potion, query_relic
2
+
3
+ __all__ = ["query_card", "query_potion", "query_relic"]
@@ -95,7 +95,10 @@ def _apply_searing_blow_upgrades(base_card, upgrade_times: int):
95
95
  return upgraded_card
96
96
 
97
97
 
98
- def query_card(name: str, upgrade_times: int = 0):
98
+ _CHARACTER_CLASSES = ("Ironclad", "Silent", "Defect", "Watcher")
99
+
100
+
101
+ def query_card(name: str, upgrade_times: int = 0, character_class: str = ""):
99
102
  if upgrade_times < 0:
100
103
  return {"found": False, "error": "INVALID_UPGRADE_TIMES"}
101
104
 
@@ -109,6 +112,18 @@ def query_card(name: str, upgrade_times: int = 0):
109
112
  canonical_name = entry["name"]
110
113
  upgrade_info = _card_upgrade_by_name().get(normalized_name)
111
114
 
115
+ # If the base entry isn't upgradeable, try character-specific variant
116
+ # e.g. "Strike" -> "Strike (Watcher)" which has upgrade data
117
+ if not (upgrade_info and upgrade_info["has_upgrade"]):
118
+ variant_name = _resolve_character_variant(normalized_name, character_class)
119
+ if variant_name:
120
+ variant_card = _cards_by_name().get(variant_name)
121
+ variant_upgrade = _card_upgrade_by_name().get(variant_name)
122
+ if variant_card and variant_upgrade and variant_upgrade["has_upgrade"]:
123
+ entry = dict(variant_card)
124
+ canonical_name = entry["name"]
125
+ upgrade_info = variant_upgrade
126
+
112
127
  applied_upgrade_times = 0
113
128
  max_upgrade_times = 0
114
129
 
@@ -130,6 +145,22 @@ def query_card(name: str, upgrade_times: int = 0):
130
145
  return {"found": True, "entry": entry}
131
146
 
132
147
 
148
+ def _resolve_character_variant(normalized_name: str, character_class: str) -> str:
149
+ """Try to find a character-specific card variant, e.g. 'strike' -> 'strike (watcher)'."""
150
+ cards = _cards_by_name()
151
+ # If character_class is provided, try that first
152
+ if character_class:
153
+ variant = f"{normalized_name} ({character_class.lower()})"
154
+ if variant in cards:
155
+ return variant
156
+ # Otherwise try all character classes
157
+ for cls in _CHARACTER_CLASSES:
158
+ variant = f"{normalized_name} ({cls.lower()})"
159
+ if variant in cards:
160
+ return variant
161
+ return ""
162
+
163
+
133
164
  def query_relic(name: str):
134
165
  relic = _relics_by_name().get(name.lower())
135
166
  if relic is None:
@@ -138,3 +169,26 @@ def query_relic(name: str):
138
169
  entry = dict(relic)
139
170
  entry["available_to"] = _relic_available_to().get(entry["name"], [])
140
171
  return {"found": True, "entry": entry}
172
+
173
+
174
+ @lru_cache(maxsize=1)
175
+ def _potions_by_name():
176
+ potions = {}
177
+ with _data_path("potion.csv").open("r", encoding="utf-8", newline="") as f:
178
+ reader = csv.reader(f, delimiter=";")
179
+ for row in reader:
180
+ name, rarity, playable_by, description = row
181
+ potions[name.lower()] = {
182
+ "name": name,
183
+ "rarity": rarity,
184
+ "playable_by": playable_by,
185
+ "description": description,
186
+ }
187
+ return potions
188
+
189
+
190
+ def query_potion(name: str):
191
+ potion = _potions_by_name().get(name.lower())
192
+ if potion is None:
193
+ return {"found": False, "error": "POTION_NOT_FOUND"}
194
+ return {"found": True, "entry": dict(potion)}
@@ -0,0 +1,42 @@
1
+ Ambrosia;Rare;Watcher;Enter Divinity Stance.
2
+ Ancient Potion;Uncommon;Any;Gain 1 Artifact.
3
+ Attack Potion;Common;Any;Choose 1 of 3 random Attack cards to add to your hand, it costs 0 this turn.
4
+ Blessing of the Forge;Common;Any;Upgrade all cards in your hand for the rest of combat.
5
+ Block Potion;Common;Any;Gain 12 Block.
6
+ Blood Potion;Common;Ironclad;Heal for 20% of your Max HP.
7
+ Bottled Miracle;Common;Watcher;Add 2 Miracles to your hand.
8
+ Colorless Potion;Common;Any;Choose 1 of 3 random Colorless cards to add to your hand, it costs 0 this turn.
9
+ Cultist Potion;Rare;Any;Gain 1 Ritual.
10
+ Cunning Potion;Uncommon;Silent;Add 3 Shiv+ to your hand.
11
+ Dexterity Potion;Common;Any;Gain 2 Dexterity.
12
+ Distilled Chaos;Uncommon;Any;Play the top 3 cards of your draw pile.
13
+ Duplication Potion;Uncommon;Any;This turn, your next card is played twice.
14
+ Elixir;Uncommon;Ironclad;Exhaust any number of cards in your hand.
15
+ Energy Potion;Common;Any;Gain 2 Energy.
16
+ Entropic Brew;Rare;Any;Fill all your empty potion slots with random potions.
17
+ Essence Of Darkness;Rare;Defect;Channel 1 Dark for each orb slot.
18
+ Essence of Steel;Uncommon;Any;Gain 4 Plated Armor.
19
+ Explosive Potion;Common;Any;Deal 10 damage to ALL enemies.
20
+ Fairy in a Bottle;Rare;Any;When you would die, heal to 30% of your Max HP instead and discard this potion.
21
+ Fear Potion;Common;Any;Apply 3 Vulnerable.
22
+ Fire Potion;Common;Any;Deal 20 damage.
23
+ Flex Potion;Common;Any;Gain 5 Strength. At the end of your turn, lose 5 Strength.
24
+ Focus Potion;Common;Defect;Gain 2 Focus.
25
+ Fruit Juice;Rare;Any;Gain 5 Max HP.
26
+ Gambler's Brew;Uncommon;Any;Discard any number of cards then draw that many.
27
+ Ghost in a Jar;Rare;Any;Gain 1 Intangible.
28
+ Heart of Iron;Rare;Ironclad;Gain 6 Metallicize.
29
+ Liquid Bronze;Uncommon;Any;Gain 3 Thorns.
30
+ Liquid Memories;Uncommon;Any;Choose a card in your discard pile and return it to your hand. It costs 0 this turn.
31
+ Poison Potion;Common;Silent;Apply 6 Poison.
32
+ Potion Of Capacity;Uncommon;Defect;Gain 2 Orb slots.
33
+ Power Potion;Common;Any;Choose 1 of 3 random Power cards to add to your hand, it costs 0 this turn.
34
+ Regen Potion;Uncommon;Any;Gain 5 Regen.
35
+ Skill Potion;Common;Any;Choose 1 of 3 random Skill cards to add to your hand, it costs 0 this turn.
36
+ Smoke Bomb;Rare;Any;Escape from a non-boss combat. Receive no rewards.
37
+ Snecko Oil;Rare;Any;Draw 5 cards. Randomize the cost of cards in your hand.
38
+ Speed Potion;Common;Any;Gain 5 Dexterity. At the end of your turn, lose 5 Dexterity.
39
+ Stance Potion;Uncommon;Watcher;Enter Calm or Wrath.
40
+ Strength Potion;Common;Any;Gain 2 Strength.
41
+ Swift Potion;Common;Any;Draw 3 cards.
42
+ Weak Potion;Common;Any;Apply 3 Weak.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: stsdb
3
- Version: 0.1.2
3
+ Version: 0.2.0
4
4
  Summary: Deterministic Slay the Spire card and relic query toolset
5
5
  Author: Taardisaa
6
6
  License: MIT
@@ -13,6 +13,7 @@ stsdb/data/card.csv
13
13
  stsdb/data/card_upgrade.csv
14
14
  stsdb/data/hero.csv
15
15
  stsdb/data/play.csv
16
+ stsdb/data/potion.csv
16
17
  stsdb/data/relic.csv
17
18
  stsdb/data/relic_availability.csv
18
19
  tests/test_stsdb.py
@@ -1,3 +0,0 @@
1
- from .core import query_card, query_relic
2
-
3
- __all__ = ["query_card", "query_relic"]
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes