def printClasses(): from hearthstone import cardxml print('') print('from ..utils import *') print('') myCardSet = CardSet.STORMWIND myCardClass = CardClass.NEUTRAL print('#%s_%s=' % (myCardSet, myCardClass), end='[') # db, xml = cardxml.load(locale='enUS') for _id in db.keys(): _card = db[_id] if _card.card_set == myCardSet and _card.card_class == myCardClass: print("'%s'" % (_card.id), end=",") pass pass print(']') for _id in db.keys(): _card = db[_id] if _card.card_set == myCardSet and _card.card_class == myCardClass: print('class %s:# <%d>[%d]' % (_card.id, _card.card_class, _card.card_set)) print('\t""" %s' % (_card.name)) print('\t%s """' % (_card.description.replace('\n', '').replace( '[x]', '').replace('<b>', '[').replace('</b>', ']'))) print('\t#' % ()) print('\tpass' % ()) print('' % ()) pass pass
def load_cards(locale_str, ids, card_set, collectible): """Load card data from XML. locale_str -- the hearthstone.enums.Locale data to load ids -- a list of card ids, takes precedence over set and collectible card_set -- restrict generation to a hearthstone.enums.CardSet collectible -- when True only generate collectible cards """ db, xml = load(DB_XML, locale_str) cards = [] if ids == None: for card in db.values(): include = True if collectible: include = True if card.collectible else False if card_set: if card_set == card.card_set: include = include and True else: include = include and False if include: cards.append(card) else: for id in ids: if id in db: cards.append(db[id]) else: print("Unknown card id {}, Skipping".format(id)) return cards
def printCards(): from hearthstone import cardxml from fireplace.cards.cardlist import All CARD_SETS = [ 'core', 'hero_dream', 'aoo', 'scholo', 'darkmoon', 'barrens', 'stormwind', 'faceHunter', 'clownDruid', 'bigWarrior', ] myCardSchool = SpellSchool.NATURE myCardSet = CardSet.STORMWIND myCardClass = CardClass.NEUTRAL print('#%s_%s=' % (myCardSet, myCardClass), end='[') # db, xml = cardxml.load(locale='enUS') for cardIDlist in All: for id in cardIDlist: card = db[id] tag = card.tags.get(GameTag.CARDRACE) if card.tags.get( GameTag.CARDTYPE ) == CardType.MINION and card.tags.get( GameTag.TAUNT, 0 ) != 0: #tag == Race.ELEMENTAL:#card.card_set== myCardSet and card.card_class == myCardClass: print("'%s'" % (card.id), end=",") pass pass pass print(']')
def initialize(self, locale="jaJP"): log.info("Initializing card database") self.initialized = True db, xml = cardxml.load(locale=locale) for id, card in db.items(): self[id] = self.merge(id, card) log.info("Merged %i cards", len(self))
def initialize(self): log.info("Initializing card database") self.initialized = True db, xml = cardxml.load() for id, card in db.items(): self[id] = self.merge(id, card) log.info("Merged %i cards", len(self))
def test_upgradable_card_map(): cardid_db, _ = cardxml.load() for upgraded, original in UPGRADABLE_CARDS_MAP.items(): assert cardid_db[original] assert cardid_db[original].collectible assert cardid_db[upgraded] assert not cardid_db[upgraded].collectible
def main(): parser = ArgumentParser() parser.add_argument( "-o", "--output-dir", type=str, dest="output_dir", default="out", help="Output directory" ) parser.add_argument( "-i", "--input-dir", type=str, dest="input_dir", default="hsdata", help="Input hsdata directory" ) args = parser.parse_args(sys.argv[1:]) db, xml = load(os.path.join(args.input_dir, "CardDefs.xml")) dbf_path = os.path.join(args.input_dir, "DBF", "CARD_BACK.xml") if not os.path.exists(dbf_path): print("Skipping card back generation (%s does not exist)" % (dbf_path)) dbf = None else: dbf = Dbf.load(dbf_path) cards = db.values() collectible_cards = [card for card in cards if card.collectible] for locale in Locale: if locale.unused: continue basedir = os.path.join(args.output_dir, locale.name) if not os.path.exists(basedir): os.makedirs(basedir) filename = os.path.join(basedir, "cards.json") export_cards_to_file(cards, filename, locale.name) filename = os.path.join(basedir, "cards.collectible.json") export_cards_to_file(collectible_cards, filename, locale.name) if dbf is not None: filename = os.path.join(basedir, "cardbacks.json") write_cardbacks(dbf, filename, locale) # Generate merged locales basedir = os.path.join(args.output_dir, "all") if not os.path.exists(basedir): os.makedirs(basedir) filename = os.path.join(basedir, "cards.json") export_all_locales_cards_to_file(cards, filename) filename = os.path.join(basedir, "cards.collectible.json") export_all_locales_cards_to_file(collectible_cards, filename)
def infer_child_card_id(parent_id: str) -> str: db, _ = load() candidates = [ key for key in db.keys() if key.startswith(parent_id) and key != parent_id ] if len(candidates) != 1: raise AttributeError( f"Child ID not defined and cannot be inferred. Candidates: {candidates}" ) return candidates[0]
def initialize(self): log.info("Initializing card database") self.initialized = True if not os.path.exists(self.filename): raise RuntimeError("%r does not exist. Create it with `bootstrap`." % (self.filename)) db, xml = cardxml.load(self.filename) for id, card in db.items(): self[id] = self.merge(id, card) log.info("Merged %i cards", len(self))
def main(): parser = ArgumentParser() parser.add_argument("-o", "--output-dir", type=str, dest="output_dir", default="out", help="Output directory") parser.add_argument("-i", "--input-dir", type=str, dest="input_dir", default="hsdata", help="Input hsdata directory") args = parser.parse_args(sys.argv[1:]) db, xml = load(os.path.join(args.input_dir, "CardDefs.xml")) dbf_path = os.path.join(args.input_dir, "DBF", "CARD_BACK.xml") if not os.path.exists(dbf_path): print("Skipping card back generation (%s does not exist)" % (dbf_path)) dbf = None else: dbf = Dbf.load(dbf_path) cards = db.values() collectible_cards = [card for card in cards if card.collectible] for locale in Locale: if locale.unused: continue basedir = os.path.join(args.output_dir, locale.name) if not os.path.exists(basedir): os.makedirs(basedir) filename = os.path.join(basedir, "cards.json") export_cards_to_file(cards, filename, locale.name) filename = os.path.join(basedir, "cards.collectible.json") export_cards_to_file(collectible_cards, filename, locale.name) if dbf is not None: filename = os.path.join(basedir, "cardbacks.json") write_cardbacks(dbf, filename, locale) # Generate merged locales basedir = os.path.join(args.output_dir, "all") if not os.path.exists(basedir): os.makedirs(basedir) filename = os.path.join(basedir, "cards.json") export_all_locales_cards_to_file(cards, filename) filename = os.path.join(basedir, "cards.collectible.json") export_all_locales_cards_to_file(collectible_cards, filename)
def test_cardxml_load(): cardid_db, _ = cardxml.load() dbf_db, _ = cardxml.load_dbf() assert cardid_db assert dbf_db for card_id, card in cardid_db.items(): assert dbf_db[card.dbf_id].id == card_id for dbf_id, card in dbf_db.items(): assert cardid_db[card.id].dbf_id == dbf_id
def main(): parser = ArgumentParser() parser.add_argument("-o", "--output-dir", type=str, dest="output_dir", default="out", help="Output directory") parser.add_argument("-i", "--input-dir", type=str, required=True, dest="input_dir", help="Input hsdata directory") parser.add_argument("--locale", type=str, nargs="*", help="Only generate one locale") args = parser.parse_args(sys.argv[1:]) db, xml = load(os.path.join(args.input_dir, "CardDefs.xml")) cards = db.values() collectible_cards = [card for card in cards if card.collectible] filter_locales = [loc.lower() for loc in args.locale or []] for locale in Locale: if locale.unused: continue if filter_locales and locale.name.lower() not in filter_locales: continue basedir = os.path.join(args.output_dir, locale.name) if not os.path.exists(basedir): os.makedirs(basedir) filename = os.path.join(basedir, "cards.json") export_cards_to_file(cards, filename, locale.name) filename = os.path.join(basedir, "cards.collectible.json") export_cards_to_file(collectible_cards, filename, locale.name) # Generate merged locales if "all" in filter_locales or not filter_locales: basedir = os.path.join(args.output_dir, "all") if not os.path.exists(basedir): os.makedirs(basedir) filename = os.path.join(basedir, "cards.json") export_all_locales_cards_to_file(cards, filename) filename = os.path.join(basedir, "cards.collectible.json") export_all_locales_cards_to_file(collectible_cards, filename)
def main(): from hearthstone.cardxml import load from fireplace.utils import _custom_cards, get_script_definition if len(sys.argv) < 3: print("Usage: %s <in> <out/CardDefs.xml>" % (sys.argv[0])) exit(1) db, xml = load(os.path.join(sys.argv[1], "CardDefs.xml")) guids, hero_powers = load_dbf(os.path.join(sys.argv[1], "DBF", "CARD.xml")) for id, card in db.items(): if id in hero_powers: add_hero_power(card, hero_powers[id]) if card.tags.get(GameTag.SPELLPOWER): guess_spellpower(card) if card.tags.get(GameTag.RECALL): guess_overload(card) if "Can't be targeted by spells or Hero Powers." in card.description: set_tag(card, GameTag.CANT_BE_TARGETED_BY_ABILITIES, True) set_tag(card, GameTag.CANT_BE_TARGETED_BY_HERO_POWERS, True) if "50% chance to attack the wrong enemy." in card.description: if not card.forgetful and id != "GVG_112": set_tag(card, GameTag.FORGETFUL, True) # xml = db[next(db.__iter__())].xml path = os.path.realpath(sys.argv[2]) with open(path, "w", encoding="utf8") as f: root = ElementTree.Element("CardDefs") for e in xml.findall("Entity"): # We want to retain the order so we can't just use db.keys() id = e.attrib["CardID"] card = db[id] root.append(card.xml) # dummy call get_script_definition("") # Create all registered custom cards for id, cls in _custom_cards.items(): e = create_card(id, cls.tags) root.append(e) outstr = ElementTree.tostring(root) # Reparse for clean indentation outstr = minidom.parseString(outstr).toprettyxml(indent="\t") outstr = "\n".join(line for line in outstr.split("\n") if line.strip()) f.write(outstr) print("Written to", path)
def main(): parser = ArgumentParser() parser.add_argument( "-o", "--output-dir", type=str, dest="output_dir", default="out", help="Output directory" ) parser.add_argument( "-i", "--input-dir", type=str, required=True, dest="input_dir", help="Input hsdata directory" ) parser.add_argument("--locale", type=str, nargs="*", help="Only generate one locale") args = parser.parse_args(sys.argv[1:]) db, xml = load(os.path.join(args.input_dir, "CardDefs.xml")) cards = db.values() collectible_cards = [card for card in cards if card.collectible] filter_locales = [loc.lower() for loc in args.locale or []] for locale in Locale: if locale.unused: continue if filter_locales and locale.name.lower() not in filter_locales: continue basedir = os.path.join(args.output_dir, locale.name) if not os.path.exists(basedir): os.makedirs(basedir) filename = os.path.join(basedir, "cards.json") export_cards_to_file(cards, filename, locale.name) filename = os.path.join(basedir, "cards.collectible.json") export_cards_to_file(collectible_cards, filename, locale.name) # Generate merged locales if "all" in filter_locales or not filter_locales: basedir = os.path.join(args.output_dir, "all") if not os.path.exists(basedir): os.makedirs(basedir) filename = os.path.join(basedir, "cards.json") export_all_locales_cards_to_file(cards, filename) filename = os.path.join(basedir, "cards.collectible.json") export_all_locales_cards_to_file(collectible_cards, filename)
def handle(self, *args, **options): db, _ = cardxml.load() created = 0 self.stdout.write("%i cards available" % (len(db))) for card in db.values(): obj, created = Card.objects.get_or_create_from_cardxml(card) if created: self.stdout.write("New card: %r (%s)" % (obj, obj.id)) created += 1 self.stdout.write("%i new cards" % (created))
def initialize(self): log.info("Initializing card database") self.initialized = True if not os.path.exists(self.filename): raise RuntimeError( "%r does not exist. Create it with `bootstrap`." % (self.filename)) db, xml = cardxml.load(self.filename) for id, card in db.items(): self[id] = self.merge(id, card) log.info("Merged %i cards", len(self))
def handle(self, *args, **options): path = options["path"] db, _ = cardxml.load(path, locale=options["locale"]) self.stdout.write("%i cards available" % (len(db))) qs = Card.objects.all().values_list("id") known_ids = [item[0] for item in qs] missing = [id for id in db if id not in known_ids] self.stdout.write("%i known cards" % (len(known_ids))) new_cards = [Card.from_cardxml(db[id]) for id in missing] Card.objects.bulk_create(new_cards) self.stdout.write("%i new cards" % (len(new_cards)))
def test_cardxml_load(): cardid_db, _ = cardxml.load() dbf_db, _ = cardxml.load_dbf() assert cardid_db assert dbf_db for card_id, card in cardid_db.items(): assert dbf_db[card.dbf_id].id == card_id for dbf_id, card in dbf_db.items(): assert cardid_db[card.id].dbf_id == dbf_id assert cardid_db["EX1_001"].quest_reward == "" assert cardid_db["UNG_940"].quest_reward == "UNG_940t8"
def initDatabaseFromXml(path, locale="zhCN"): """Load card database from CardDefs.xml and use it to initialize DBF database Args: path: The xml file to load for init locale: The language setting for database Returns: db_dbf: The all-cards database """ db, xml = load(path, locale=locale) db_dbf = {} for card in db: db_dbf[db[card].dbf_id] = db[card] return db_dbf
def main(): for locale in Locale: if locale.unused: continue db, xml = load("hs-data/CardDefs.xml", locale=locale.name) basedir = os.path.join("out", "latest", locale.name) if not os.path.exists(basedir): os.makedirs(basedir) filename = os.path.join(basedir, "collectible.json") export_to_file([card for card in db.values() if card.collectible], filename) filename = os.path.join(basedir, "all.json") export_to_file(db.values(), filename)
def fromid(game: Game, card_id: str, **kwargs): try: db, _ = load() card_data = db[card_id] except KeyError: logging.error("Card %d not found.", card_id) return None for tag, value in card_data.tags.items(): if isinstance(tag, GameTag): kwargs.setdefault(tag.name.lower(), value) kwargs.setdefault("zone", Zone.SETASIDE) cls = Card.load_effect(card_data.name, card_data.tags[GameTag.CARDTYPE]) card: Card = cls(card_id=card_id, **kwargs) game.register_entity(card) return card
def random(**kwargs): db, _ = load() conditions = [( re.sub("__.*", "", key), getattr(operator, re.search("(__[a-z]*)?$", key).group()[2:], operator.eq), value, ) for key, value in kwargs.items()] candidates = [ card.id for card in db.values() if GameTag.TECH_LEVEL in card.tags and all( op(getattr(card, key), value) for key, op, value in conditions) ] if not candidates: return None return choice(candidates)
def initialize(self, locale="jaJP"): #locale="enUS"):# log.info("Load card database") self.initialized = True db, xml = cardxml.load(locale=locale) log.info("Initializing card database") from .cardlist import All for cardIDlist in All: for id in cardIDlist: card = db[id] spellpowervalue = card.tags.get(GameTag.SPELLPOWER) if spellpowervalue is not None: setattr(card, 'spellpower', spellpowervalue) else: setattr(card, 'spellpower', 0) self[id] = self.merge(id, card) #if card.multiple_classes and card.type==CardType.SPELL and card.card_class==CardClass.NEUTRAL: # print ("%s"%(id)) pass log.info("Merged %i cards", len(self))
def main(): for locale in Locale: if locale.unused: continue db, xml = load("hs-data/CardDefs.xml", locale=locale.name) basedir = os.path.join("out", "latest", locale.name) if not os.path.exists(basedir): os.makedirs(basedir) filename = os.path.join(basedir, "cards.json") export_cards_to_file(db.values(), filename) filename = os.path.join(basedir, "cards.collectible.json") export_cards_to_file([card for card in db.values() if card.collectible], filename) filename = os.path.join(basedir, "cardbacks.json") dbf = Dbf.load("hs-data/DBF/CARD_BACK.xml") write_cardbacks(dbf, filename, locale)
def __repr__(self): from hearthstone.cardxml import load db, _ = load(locale=locale.get()) def minion_repr(card: "Minion"): return "%s%d/%d" % ( db[card.card_id].name, card.atk, card.health - card.damage, ) state_repr = "Turn %d\n" % self.game.turn friendly_minions = self.players[0].minions state_repr += " ".join(map(minion_repr, friendly_minions)) state_repr += "\n" enemy_minions = self.players[1].minions state_repr += " ".join(map(minion_repr, enemy_minions)) return state_repr
def print_deck(): from tkinter import filedialog from hearthstone import cardxml db, xml = cardxml.load(locale='jaJP') typ = [('テキストファイル', '*.txt')] dir = 'D:\\' fle = filedialog.askopenfilename(filetypes=typ, initialdir=dir) try: f = open(fle, 'r') datalist = f.readlines() print("[", end='') for line in datalist: if len(line) > 10: number = line[2:4] if number == '1x': name = line[9:-1] for id in db.keys(): card = db[id] if card.name == name: print("'%s'" % (card.id), end=",") break pass pass elif number == '2x': name = line[9:-1] for id in db.keys(): card = db[id] if card.name == name: print("'%s'" % (card.id), end=",") print("'%s'" % (card.id), end=",") break pass pass pass f.close() print("]") except FileNotFoundError: pass
def handle(self, *args, **options): path = options["path"] db, _ = cardxml.load(path, locale=options["locale"]) self.stdout.write("%i cards available" % (len(db))) qs = Card.objects.all().values_list("id") known_ids = [item[0] for item in qs] missing = [id for id in db if id not in known_ids] self.stdout.write("%i known cards" % (len(known_ids))) new_cards = [Card.from_cardxml(db[id]) for id in missing] Card.objects.bulk_create(new_cards) self.stdout.write("%i new cards" % (len(new_cards))) if options["force"]: existing = Card.objects.filter(id__in=known_ids) for card in existing: if card.id not in db: self.stderr.write("WARNING: %r (%s) not in CardDefs.xml. Skipping." % (card, card.id)) continue c = db[card.id] if c: card.update_from_cardxml(c, save=True) self.stdout.write("%i updated cards" % (len(existing)))
import re from hearthstone import cardxml from hearthstone.cardxml import CardXML from hearthstone.enums import CardType, GameTag, Race, Rarity ERR_LANG_NOT_FOUND = "Language not found. Supported language keys are e.g. `enUS` or `deDE`" db, _ = cardxml.load() def loc_name(self, locale): return self.strings[GameTag.CARDNAME][locale] def loc_text(self, locale): return self.strings[GameTag.CARDTEXT_INHAND][locale] def loc_flavor(self, locale): return self.strings[GameTag.FLAVORTEXT][locale] CardXML.loc_name = loc_name CardXML.loc_text = loc_text CardXML.loc_flavor = loc_flavor class CardHandler(): def __init__(self):
from hearthstone import cardxml, enums from hsreplaynet.cards.models import Card carddb = cardxml.load()[0] def test_load_al_akir(): id = "NEW1_010" card = carddb[id] obj = Card.from_cardxml(card) assert obj.id == id assert obj.name == "Al'Akir the Windlord" assert obj.divine_shield assert obj.taunt assert obj.windfury assert obj.card_class == enums.CardClass.SHAMAN assert obj.card_set == enums.CardSet.EXPERT1 assert not obj.spell_damage def test_load_evolved_kobold(): id = "OG_082" card = carddb[id] obj = Card.from_cardxml(card) assert obj.id == id assert obj.name == "Evolved Kobold" assert obj.card_class == enums.CardClass.NEUTRAL assert obj.card_set == enums.CardSet.OG
# Create a deck from a deckstring deck = Deck() deck.heroes = [7] # Garrosh Hellscream deck.format = FormatType.FT_WILD # Nonsense cards, but the deckstring doesn't validate. deck.cards = [(1, 3), (2, 3), (3, 3), (4, 3)] # id, count pairs print(deck.as_deckstring) # "AAEBAQcAAAQBAwIDAwMEAw==" # Import a deck from a deckstring deck = Deck.from_deckstring( "AAEBAf0ECMAB5gT7BPsFigbYE5KsAv2uAgucArsClQONBKsEtAThBJYF7Ae8CImsAgA=") print(deck.cards) # load card database from CardDefs.xml and use it to initialize DBF database db, xml = load(os.path.join("hsdata", "CardDefs.xml"), locale="zhCN") db_dbf = {} for card in db: #print (card) db_dbf[db[card].dbf_id] = db[card] #print (db) for cardPair in deck.cards: # print (cardPair[0]) card = db_dbf[cardPair[0]] print(cardPair[1], "x(", card.cost, ")", card.name, card.rarity) #print (type(deck.cards)) #col = Collection()
\a rarity: The rarity of the card (hearthstone.enums.Rarity) \a cost: The mana cost of the card """ cards = db.values() for attr, value in kwargs.items(): if value is not None: # What? this doesn't work? # cards = __builtins__["filter"](lambda c: getattr(c, attr) == value, cards) cards = [card for card in cards if getattr(card, attr) == value] return [card.id for card in cards] # Here we import every card from every set and load the cardxml database. # For every card, we will "merge" the class with its Python definition if # it exists. # This code is only ran once, at initial import. if "cardlist" not in globals(): xmlfile = resource_filename(__name__, "data/CardDefs.xml") if not os.path.exists(xmlfile): raise RuntimeError("%r does not exist - generate it!" % (xmlfile)) with open(xmlfile, "r") as f: db, xml = cardxml.load(xmlfile) cardlist = [] for id in db: globals()[id] = merge(id) cardlist.append(id)
from hearthstone import cardxml, enums from hsreplaynet.cards.models import Card carddb = cardxml.load()[0] def test_load_al_akir(): id = "NEW1_010" card = carddb[id] obj = Card.from_cardxml(card) assert obj.id == id assert obj.name == "Al'Akir the Windlord" assert obj.divine_shield assert obj.taunt assert obj.windfury assert obj.card_class == enums.CardClass.SHAMAN assert obj.card_set == enums.CardSet.EXPERT1 assert not obj.spell_damage def test_load_evolved_kobold(): id = "OG_082" card = carddb[id] obj = Card.from_cardxml(card) assert obj.id == id assert obj.name == "Evolved Kobold" assert obj.card_class == enums.CardClass.NEUTRAL assert obj.card_set == enums.CardSet.OG assert obj.spell_damage == 2
def main(): from hearthstone.cardxml import load from fireplace.utils import _custom_cards, get_script_definition if len(sys.argv) < 3: print("Usage: %s <in> <out/CardDefs.xml>" % (sys.argv[0])) exit(1) db, xml = load(os.path.join(sys.argv[1], "CardDefs.xml")) guids, hero_powers = load_dbf(os.path.join(sys.argv[1], "DBF", "CARD.xml")) for id, card in db.items(): carddef = get_script_definition(id) if carddef: if hasattr(carddef, "tags"): for tag, value in carddef.tags.items(): set_tag(card, tag, value) if hasattr(carddef, "choose"): add_chooseone_tags(card, carddef.choose) if id in hero_powers: add_hero_power(card, hero_powers[id]) if re.match(r"^PART_\d+$", id): # Hearthstone uses entourage data to identify Spare Parts # We're better than that. set_tag(card, GameTag.SPARE_PART, True) if card.tags.get(GameTag.SPELLPOWER): guess_spellpower(card) if card.tags.get(GameTag.RECALL): guess_overload(card) if "Can't attack." in card.description: set_tag(card, GameTag.CANT_ATTACK, True) if "Can't be targeted by spells or Hero Powers." in card.description: set_tag(card, GameTag.CANT_BE_TARGETED_BY_ABILITIES, True) set_tag(card, GameTag.CANT_BE_TARGETED_BY_HERO_POWERS, True) # xml = db[next(db.__iter__())].xml with open(sys.argv[2], "w", encoding="utf8") as f: root = ElementTree.Element("CardDefs") for e in xml.findall("Entity"): # We want to retain the order so we can't just use db.keys() id = e.attrib["CardID"] card = db[id] root.append(card.xml) # Create all registered custom cards for id, cls in _custom_cards.items(): e = create_card(id, cls.tags) root.append(e) outstr = ElementTree.tostring(root) # Reparse for clean indentation outstr = minidom.parseString(outstr).toprettyxml(indent="\t") outstr = "\n".join(line for line in outstr.split("\n") if line.strip()) f.write(outstr) print("Written to", f.name)
def main(): from hearthstone.cardxml import load if len(sys.argv) < 3: print("Usage: %s <in> <out/CardDefs.xml>" % (sys.argv[0])) exit(1) db, xml = load(os.path.join(sys.argv[1], "CardDefs.xml")) guids, hero_powers = load_dbf(os.path.join(sys.argv[1], "DBF", "CARD.xml")) for id, card in db.items(): if hasattr(buffs, id): for tag, value in getattr(buffs, id).items(): set_tag(card, tag, value) if hasattr(chooseone, id): add_chooseone_tags(card, getattr(chooseone, id)) if id in hero_powers: add_hero_power(card, hero_powers[id]) if re.match(r"^PART_\d+$", id): # Hearthstone uses entourage data to identify Spare Parts # We're better than that. set_tag(card, GameTag.SPARE_PART, True) if card.xml.findall("EntourageCard"): fix_entourage(card, guids) if card.tags.get(GameTag.SPELLPOWER): guess_spellpower(card) if card.tags.get(GameTag.RECALL): guess_overload(card) if "Can't attack." in card.description: set_tag(card, GameTag.CANT_ATTACK, True) if "Can't be targeted by spells or Hero Powers." in card.description: set_tag(card, GameTag.CANT_BE_TARGETED_BY_ABILITIES, True) set_tag(card, GameTag.CANT_BE_TARGETED_BY_HERO_POWERS, True) if id in italicize: description = card.description assert description and not description.startswith("<i>") print("%s: Italicizing description %r" % (id, description)) e = card._find_tag(GameTag.CARDTEXT_INHAND) if e is not None: for desc in e: desc.text = "<i>%s</i>" % (desc.text) else: print("WARNING: No CARDTEXT_INHAND tag found on %r" % (card)) # xml = db[next(db.__iter__())].xml with open(sys.argv[2], "w", encoding="utf8") as f: root = ElementTree.Element("CardDefs") for e in xml.findall("Entity"): # We want to retain the order so we can't just use db.keys() id = e.attrib["CardID"] card = db[id] root.append(card.xml) for id, obj in missing_cards.__dict__.items(): if id.startswith("_") or not isinstance(obj, dict): # skip the imports continue e = create_card(id, obj) root.append(e) outstr = ElementTree.tostring(root) # Reparse for clean indentation outstr = minidom.parseString(outstr).toprettyxml(indent="\t") outstr = "\n".join(line for line in outstr.split("\n") if line.strip()) f.write(outstr) print("Written to", f.name)
def _build_card_map(): cards, xml_ = cardxml.load('hs-data/CardDefs.xml') return {card_id: card.name for card_id, card in cards.items()}
def setUp(self): self.carddb, _ = cardxml.load()
import logging from collections import Counter from copy import deepcopy from hearthstone import enums from hearthstone.cardxml import load from ..simulator.battle import battle from .logfile import LogStream, get_log_path from .parser import BattlegroundParser db, _ = load(locale="zhCN") logging.getLogger().setLevel(logging.ERROR) def card_repr(card) -> str: return "%s%d/%d" % ( db[card.card_id].name, getattr(card, "atk", 0), card.health - getattr(card, "damage", 0), ) def combat_callback(parser: BattlegroundParser): game = parser.export_game() turn = game.turn // 2 print(f"Combat of turn {turn} starts.") friendly_minions = game.players[0].minions print(" ".join(map(card_repr, friendly_minions)))
cards = db.values() if "type" not in kwargs: kwargs["type"] = [CardType.SPELL, CardType.WEAPON, CardType.MINION] for attr, value in kwargs.items(): if value is not None: # What? this doesn't work? # cards = __builtins__["filter"](lambda c: getattr(c, attr) == value, cards) cards = [card for card in cards if (isinstance(value, list) and getattr(card, attr) in value) or getattr(card, attr) == value] return [card.id for card in cards] # Here we import every card from every set and load the cardxml database. # For every card, we will "merge" the class with its Python definition if # it exists. # This code is only ran once, at initial import. if "cardlist" not in globals(): xmlfile = resource_filename(__name__, "data/CardDefs.xml") if not os.path.exists(xmlfile): raise RuntimeError("%r does not exist - generate it!" % (xmlfile)) with open(xmlfile, "r") as f: db, xml = cardxml.load(xmlfile) cardlist = [] for id in db: globals()[id] = merge(id) cardlist.append(id)
def setup_module(module): load() load(locale="zhCN")
def annotate_replay(infile, outfile): from hearthstone import cardxml from hearthstone.enums import (BlockType, GameTag, MetaDataType, PlayState, State, TAG_TYPES) db, _ = cardxml.load() entities = {} entity_ref_tags = { GameTag.LAST_AFFECTED_BY, GameTag.LAST_CARD_PLAYED, GameTag.PROPOSED_ATTACKER, GameTag.PROPOSED_DEFENDER, GameTag.WEAPON, } tree = ElementTree.parse(infile) root = tree.getroot() for tag in root.iter("FullEntity"): if "cardID" in tag.attrib: entities[tag.attrib["id"]] = tag.attrib["cardID"] for tag in root.iter("GameEntity"): entities[tag.attrib["id"]] = ResolvedString("GameEntity") for tag in root.iter("Player"): if "name" in tag.attrib: entities[tag.attrib["id"]] = ResolvedString(tag.attrib["name"]) for tag in root.iter("ShowEntity"): if "cardID" in tag.attrib: entities[tag.attrib["entity"]] = tag.attrib["cardID"] tag.set("EntityName", _get_card_name(db, tag.attrib["cardID"])) for tag in root.iter("FullEntity"): if tag.attrib["id"] in entities: tag.set("EntityName", _get_card_name(db, entities[tag.attrib["id"]])) block_counter = 1 for tag in root.iter("Block"): tag.set("block_sequence_num", str(block_counter)) block_counter += 1 if "entity" in tag.attrib and tag.attrib["entity"] in entities: tag.set("EntityCardID", entities[tag.attrib["entity"]]) if tag.attrib["entity"] == "1": tag.set("EntityCardName", "GameEntity") elif tag.attrib["entity"] in ("2", "3"): tag.set("EntityCardName", entities[tag.attrib["entity"]]) else: tag.set("EntityCardName", _get_card_name(db, entities[tag.attrib["entity"]])) if "target" in tag.attrib and tag.attrib["target"] in entities: tag.set("TargetName", _get_card_name(db, entities[tag.attrib["target"]])) if "triggerKeyword" in tag.attrib: try: tag.set("TriggerKeywordName", GameTag(int(tag.attrib["triggerKeyword"])).name) except ValueError: pass for tag in root.iter("Tag"): try: tag_enum = GameTag(int(tag.attrib["tag"])) tag.set("GameTagName", tag_enum.name) enum_or_type = TAG_TYPES.get(tag_enum) if enum_or_type: if enum_or_type.__class__ == enum.EnumMeta: tag.set("%sName" % (enum_or_type.__name__), enum_or_type(int(tag.attrib["value"])).name) except ValueError: pass for tag_change in root.iter("TagChange"): if "entity" in tag_change.attrib and tag_change.attrib[ "entity"] in entities: tag_change.set("EntityCardID", entities[tag_change.attrib["entity"]]) tag_change.set( "EntityCardName", _get_card_name(db, entities[tag_change.attrib["entity"]])) if int(tag_change.attrib["tag"] ) in entity_ref_tags and tag_change.attrib["value"] in entities: tag_change.set("ValueReferenceCardID", entities[tag_change.attrib["value"]]) tag_change.set( "ValueReferenceCardName", _get_card_name(db, entities[tag_change.attrib["value"]])) if tag_change.attrib["tag"] == str(GameTag.STATE.value): tag_change.set("StateName", State(int(tag_change.attrib["value"])).name) if tag_change.attrib["tag"] == str(GameTag.PLAYSTATE.value): tag_change.set("PlayStateName", PlayState(int(tag_change.attrib["value"])).name) try: tag_enum = GameTag(int(tag_change.attrib["tag"])) tag_change.set("GameTagName", tag_enum.name) enum_or_type = TAG_TYPES.get(tag_enum) if enum_or_type: if enum_or_type.__class__ == enum.EnumMeta: tag_change.set( "%sName" % (enum_or_type.__name__), enum_or_type(int(tag_change.attrib["value"])).name) except ValueError: pass for block in root.iter("Block"): try: tag_enum = BlockType(int(block.attrib["type"])) except ValueError: tag_enum = block.attrib["type"] block.set("BlockTypeName", tag_enum.name) for option in root.iter("Option"): if "entity" in option.attrib and option.attrib["entity"] in entities: option.set("EntityCardID", entities[option.attrib["entity"]]) option.set("EntityName", _get_card_name(db, entities[option.attrib["entity"]])) for target in root.iter("Target"): if "entity" in target.attrib and target.attrib["entity"] in entities: target.set("EntityCardID", entities[target.attrib["entity"]]) target.set("EntityName", _get_card_name(db, entities[target.attrib["entity"]])) for choices in root.iter("Choices"): if "entity" in choices.attrib and choices.attrib["entity"] in entities: choices.set("EntityCardID", entities[choices.attrib["entity"]]) choices.set("EntityName", _get_card_name(db, entities[choices.attrib["entity"]])) if "source" in choices.attrib and choices.attrib["source"] in entities: choices.set("SourceCardID", entities[choices.attrib["source"]]) choices.set("SourceName", _get_card_name(db, entities[choices.attrib["source"]])) for choice in root.iter("Choice"): if "entity" in choice.attrib and choice.attrib["entity"] in entities: choice.set("EntityCardID", entities[choice.attrib["entity"]]) choice.set("EntityName", _get_card_name(db, entities[choice.attrib["entity"]])) for meta in root.iter("MetaData"): if "meta" in meta.attrib: meta.set("MetaName", MetaDataType(int(meta.attrib["meta"])).name) for target in root.iter("Info"): if "entity" in target.attrib and target.attrib["entity"] in entities: target.set("EntityName", _get_card_name(db, entities[target.attrib["entity"]])) tree.write(outfile, pretty_print=True)