def collect_class_option_data(class_name, class_lvl, subclass_id=-1): """ Extracts the class options data from the class database. :param class_name: the name of the class selected :type class_name: str :param class_lvl: the level to build the class at :type class_lvl: int :param subclass_id: the id of the subclass, if appropriate :type subclass_id: int, optional :return: three arrays holding the traits, proficiencies and languages """ if subclass_id == -1: subclassStr = " IS NULL" else: subclassStr = "=" + str(subclass_id) traits, proficiencies, languages = [], [], [] Db.cursor.execute("SELECT classOptionsId FROM ClassOptions WHERE classId=" + str( Db.get_id(class_name, "Class")) + " AND subclassId" + subclassStr) ids = Db.cursor.fetchall() for nextId in ids: metadata, options = DataExtractor.class_options_connections(nextId[0], subclass_id) if metadata[0] <= class_lvl: if metadata[2] == "traits": traits += make_choice(metadata[1], options, class_name) traits = choose_trait_option(traits, class_name) elif metadata[2] == "proficiencies": proficiencies += make_choice(metadata[1], options, class_name) else: languages += make_choice(metadata[1], options, class_name) return traits, proficiencies, languages
def pull_generic_tag(tag_name, data, weight, archetype_tags, archetype_weight_dict): """ Adjusts the inputted weighting dictionary based on the occurrences of archetype tags in the inputted data set. :param tag_name: the singular name of the type of item being pulled, such as Spell :type tag_name: str :param data: the names of all data pieces to pull tags from, with their relevant data values, in a 2D array :type data: list :param weight: the weighting to be applied to recorded occurrences of the tags :type weight: int :param archetype_tags: the tags that apply to the archetype(s) selected in creating the chromosome :type archetype_tags: set :param archetype_weight_dict: a dictionary, linking an archetype tag to the (weighted) occurences of it so far :type archetype_weight_dict: dict :return: the updated archetype weight dictionary """ for dataPiece, dataValue in data: tags = DataExtractor.get_names_from_connector(tag_name, "GenericTag", input_name=dataPiece) tagAmnt = Counter(tags) for match in set(tags).intersection(archetype_tags): # calculates the weighted value of the match, based on it's amount of occurrences, and adds this # to the archetype weighting dictionaries current value weightedWorth = (tagAmnt[match] * (weight + dataValue)) archetype_weight_dict.update( {match: (archetype_weight_dict[match] + weightedWorth)}) return archetype_weight_dict
def create_equipment(class_name): """ Creates and selects all equipment options for one class. :param class_name: the name of the class to get the equipment for :type class_name: str :return: a list of equipment objects """ optionsData = DataExtractor.equipment_connections(Db.get_id(class_name, "Class")) equipment = [] for option in optionsData: equipment += create_equipment_option(option, class_name)[1] return equipment
def create_all_equipment(): """ Creates an object for each equipment item in the database. """ equipmentData = DataExtractor.equipment_items() for equip in equipmentData: for x in range(0, len(equip)): if equip[x] == "": equip[x] = 0 if type(equip[-1]) is list: Equipment.Equipment(*equip[:-1], item_range=equip[-1]) else: Equipment.Equipment(*equip)
def dev_btn(): """ Calls the systems reaction to the Dev Menu button being pressed. """ CoreDatabase.connection = sql.connect(CoreDatabase.dir_path + "/Resources/ChrDatabase.db") CoreDatabase.cursor = CoreDatabase.connection.cursor() print("Enter which service you'd like to use:\n" "1. Database Setup\n" "2. View Tables\n" "3. General testing\n" "4. Exit") menu = CoreDatabase.int_input("> ") if menu == 1: DatabaseSetup.begin() elif menu == 2: CoreDatabase.view_tables() elif menu == 3: # replace me with whatever needs testing! DataExtractor.begin() else: SystemExit(0) CoreDatabase.complete_setup()
def create_background(background_name): """ Creates and returns a background object, given the name of the background to use. :param background_name: the name of the background selected :type background_name: str :return: a python object representing the background """ tools, skills, languages = DataExtractor.background_connections(background_name) finalProfs, finalLanguages = [], [] finalProfs += make_choice(tools[0], tools[1], background_name) finalProfs += make_choice(skills[0], skills[1], background_name) finalLanguages = make_choice(languages[0], languages[1], background_name) return Background.Background(background_name, finalProfs, finalLanguages)
def get_spell(spell_name, chr_level=1): """ Gets a specified spell from the array of built spells, or adds it if it currently isn't in there. This is done to save building a substantial amount of objects for each spell. :param spell_name: the name of the spell to return :type spell_name: str :param chr_level: the level of the current character, relevant for cantrips :type chr_level: int :return: the spell object, pointed to from the array """ # determines if the spell is built spellIndex = -1 spellArray = Spell.builtSpells for x in range(0, len(spellArray)): if spellArray[x].name == spell_name: spellIndex = x if spellIndex == -1: Spell.builtSpells.append( Spell(*DataExtractor.spell_info(spell_name, chr_level))) spellIndex = len(Spell.builtSpells) - 1 return Spell.builtSpells[spellIndex]
def create_class_magic(class_name, class_lvl, subclass_name=""): """ Creates the magic related to a class at a specified level. :param class_name: the class to create magic for :type class_name: str :param class_lvl: the level the class is at when gaining the magic object :type class_lvl: int :param subclass_name: the subclass to create magic for, if appropriate :type subclass_name: str, optional :return: an object representing all the magic in a class """ # retrieves and sets up variables [cantripsKnown, amntKnown, spellsPrepared, knownCalc], spells, spellslots \ = DataExtractor.create_class_magic(class_name, class_lvl, subclass_name) spellsPrepared = spellsPrepared == 1 spellObjects, cantripObjects, selectedSpells = [], [], [] if amntKnown is None: amntKnown = -1 # creates spells for spell in spells: nextSpell = Spell.get_spell(spell, class_lvl) if nextSpell.level == 0: cantripObjects.append(nextSpell) else: spellObjects.append(nextSpell) # chooses spells if subclass_name != "": class_name = subclass_name selectedSpells = make_choice(cantripsKnown, cantripObjects, class_name) if spellsPrepared is False: selectedSpells += make_choice(amntKnown, spellObjects, class_name) params = [spellslots, False, amntKnown, selectedSpells] else: params = [spellslots, True, amntKnown, selectedSpells, knownCalc, spellObjects] return CharacterElements.Magic.Magic(*params)
def collect_race_option_data(race_name, chr_lvl, subrace_id=-1): """ Extracts the race options data from the race database. :param race_name: the name of the race selected :type race_name: str :param chr_lvl: the level of the character being built :type chr_lvl: int :param subrace_id: the id of the subrace, if appropriate :type subrace_id: int, optional :return: three arrays holding the traits, proficiencies and languages """ if subrace_id == -1: subraceStr = " IS NULL" else: subraceStr = "=" + str(subrace_id) spells, proficiencies, languages = [], [], [] modUsed = "" Db.cursor.execute("SELECT raceOptionsId FROM RaceOptions WHERE raceId=" + str(Db.get_id(race_name, "Race")) + " AND subraceId" + subraceStr) ids = Db.cursor.fetchall() Db.cursor.execute("SELECT raceOptionsId FROM RaceOptions WHERE raceId=" + str(Db.get_id(race_name, "Race"))) for nextId in ids: metadata, options = DataExtractor.race_options_connections(nextId[0], subrace_id) if len(options) > 0: if metadata[1] == "proficiencies": proficiencies += make_choice(metadata[0], options, race_name) elif metadata[1] == "spells": spellNames = [] for spell in options: spellNames.append(spell[0]) spells = make_choice(metadata[0], spellNames, race_name) spells = build_race_spells(options, spells, chr_lvl) modUsed = options[0][3] else: languages += make_choice(metadata[0], options, race_name) return spells, modUsed, proficiencies, languages
def create_race(race_name, chr_lvl, subrace_id=-1, is_subrace=False): """ Creates and returns a race object, given the name and level of the race to use. :param race_name: the name of the race to create :type race_name: str :param chr_lvl: the level of the character being created :type chr_lvl: int :param subrace_id: the id of the subrace being built :type subrace_id: int, optional :param is_subrace: whether the current pass is creating the subrace :type is_subrace: bool, optional :return: a race object of the inputted race """ # recursively builds a subrace from the data if subrace_id > -1 and is_subrace is False: subrace = create_race(race_name, chr_lvl, subrace_id, True) subrace_id = -1 else: subrace = None # get basic variable data if subrace_id == -1: subraceStr = " IS NULL" else: subraceStr = "=" + str(subrace_id) raceId = Db.get_id(race_name, "Race") # get basic racial data Db.cursor.execute("SELECT size FROM Race WHERE raceId=" + str(raceId)) size = Db.cursor.fetchone()[0] if subrace_id == -1: Db.cursor.execute("SELECT speed, darkvision, resistance FROM Race WHERE raceId=" + str(raceId)) else: Db.cursor.execute("SELECT speed, darkvision, resistance FROM Subrace WHERE raceId=" + str(raceId) + " AND subraceId" + subraceStr) speed, darkvision, resistance = Db.cursor.fetchone() # gets the trait data traits = [] traitNames = DataExtractor.get_names_from_connector("Race", "Trait", raceId) for trait in traitNames: Db.cursor.execute("SELECT subraceId FROM RaceTrait WHERE traitId=" + str(Db.get_id(trait, "Trait"))) subId = Db.cursor.fetchone()[0] if (subId is None and subrace_id == -1) or (subId == subrace_id): Db.cursor.execute("SELECT traitDescription FROM Trait WHERE traitName='" + trait.replace("'", "''") + "'") traits.append((trait, Db.cursor.fetchone()[0])) traits = choose_trait_option(traits, race_name) # extracts data from options spells, modUsed, proficiencies, languages = collect_race_option_data(race_name, chr_lvl, subrace_id) # gets the ability score data Db.cursor.execute("SELECT abilityScore, scoreIncrease FROM RaceAbilityScore WHERE raceId=" + str(raceId) + " AND subraceId" + subraceStr) abilityScores = dict() for scoreName, scoreIncrease in Db.cursor.fetchall(): abilityScores.update({scoreName: scoreIncrease}) # converts data into the required formats darkvision = darkvision == 1 if len(spells) == 0: spells = None modUsed = None if is_subrace: Db.cursor.execute("SELECT subraceName FROM Subrace WHERE subraceId=" + str(subrace_id)) race_name = Db.cursor.fetchone()[0] return Race.Race(race_name, languages, proficiencies, abilityScores, traits, speed, size, darkvision, spells, modUsed, resistance, subrace)
def pull_generic_tags(self): """ Pulls all information linked to the GenericTag table from each archetype tag, and monitors how often it is used in the selected spells, equipment and traits. :return: the list information of all generic tags """ # stores a set of the tags relevant to the selected archetype(s) archetypeTags = set() # stores a dictionary of (tag, value) pairs, where the pair is the weighted occurrences of the tag archetypeWeightDict = dict() # stores the weights of the generic tags, in [equipment, spell, trait] order weights = [1, 1, 1] # fills out the set and dictionary of the tags for tag in self.tags: archetypeTags.update( set( DataExtractor.get_names_from_connector("Tag", "GenericTag", input_name=tag[0]))) for tag in archetypeTags: archetypeWeightDict.update({tag: 0}) # prepares lists of the names of each data group, with their related data values # they have easily adjustable data value weightings, with the base values typically being # their maximum dice values, plus 1 for every dice above 1, to represent the benefit of more dice equipment, spells, traits = [], [], [] for eq in set(self.character.chrClass.equipment): if eq.armorClass != 0: equipVal = (eq.armorClass - 10) / 4.0 elif eq.dice is not None: diceValues = eq.dice.split("d") equipVal = (int(diceValues[0]) * int(diceValues[1])) + (int(diceValues[0]) - 1) equipVal /= 6.0 else: equipVal = 0 equipment.append([eq.name, equipVal]) for spell in (self.character.magic.knownSpells + self.character.magic.preparedSpellOptions): if spell.damage is None: spellDmg = 0 else: spellDmgVals = spell.damage.split("d") spellDmg = (int(spellDmgVals[0]) * int(spellDmgVals[1])) + (int(spellDmgVals[0]) - 1) spellDmg /= 6.0 spells.append([spell.name, spellDmg]) for trait in self.character.traits: traits.append([trait[0], 0]) archetypeWeightDict = pull_generic_tag("Equipment", equipment, weights[0], archetypeTags, archetypeWeightDict) archetypeWeightDict = pull_generic_tag("Spell", spells, weights[1], archetypeTags, archetypeWeightDict) archetypeWeightDict = pull_generic_tag("Trait", traits, weights[2], archetypeTags, archetypeWeightDict) return archetypeWeightDict