def AssignRace(): #Assigning specific race values and traits global race global races global subRaces global stats global movementSpeed global resistances global size global sizeFlavor global langs global age raceDict = races[universal_functions.GetValidOption( 1, 9, "That is not a valid race-number from the list\nPlease try again: ", "What race do you want to play?\n1.\tDragonborn\n2.\tDwarf\n3.\tElf\n4.\tGnome\n5.\tHalf-Elf\n6.\tHalf-Orc\n7.\tHalfling\n8.\tHuman\n9.\tTiefling\nChoose 1/2/3/4/5/6/7/8/9: " ) - 1] race = raceDict['Name'] if 'subRaceIndex' in raceDict: for subRaceDict in subRaces: if subRaceDict['Index'] == raceDict['subRaceIndex']: AssignSubRace(subRaceDict) #AssignSubRace(subRaces[raceDict['subRace']]) for i in raceDict['statBoost']: if type(i[0]) != int: stats[i[0]( 1, 6, "That is not a valid ability score. Please try again: ", "Choose which ability score you want to improve by 1\n1.\tStrength\n2.\tDexteriay\n3.\tConstitution\n4.\tIntelligence\n5.\tWisdom\n6.\tCharisma\nChoose an option: " ) - 1] += i[1] else: stats[i[0]] += i[1] movementSpeed = raceDict['speed'] size = raceDict['size'] sizeFlavor = universal_functions.GetValidOption( (raceDict['sizeFlavor'][0]) - 1, (raceDict['sizeFlavor'][1]) + 1, "That is not a valid size in feet. Please try again: ", "A typical " + race.lower() + " is between " + str(raceDict['sizeFlavor'][0]) + " and " + str(raceDict['sizeFlavor'][1]) + " feet tall. \nI have given you a foot leway on each side to choose from. \nHow tall do you want your character to be? " ) for lang in raceDict['langs']: langs.append(lang) age = universal_functions.GetValidOption( math.floor((raceDict['age'][0] * 2) / 3), math.floor((raceDict['age'][1] * 2) / 3), "That is either too young or too old for a " + race.lower() + "to be usefull for a party.\nPlease choos an age between " + str(math.floor((raceDict['age'][0] * 2) / 3)) + " and " + str(math.floor((raceDict['age'][1] * 2) / 3)) + " years: ", "Most " + race.lower() + "s becomes mature at age " + str(raceDict['age'][0]) + " and die around the age of " + str(raceDict['age'][1]) + ". \nYou can choose an age for this character in the range: " + str(math.floor((raceDict['age'][0] * 2) / 3)) + " to " + str(math.floor((raceDict['age'][1] * 2) / 3)) + " years: ") if 'resist' in raceDict: resistances[raceDict['resist']] = 1 if 'traits' in raceDict: AddTrait(raceDict['traits'])
def CreateSpell(): global abilities global abilityIDs spellList = [x.split(".")[0].lower() for x in os.listdir("Resources/Spells") if x.endswith(".py")] spellNameChosen = False spellName = input("What should this new Spell be called (Choose a name that does not already exist in the spells folder)? ").replace(" ","") while(not spellNameChosen): if spellName.lower() not in spellList: spellNameChosen = True else: spellName = input("That spell already exsists, please choose another name ") for i in abilities: abilityIDs.append(i[0]) abilityIDFound = False currIdTest = 1 while(not abilityIDFound): if currIdTest in abilityIDs: currIdTest += 1 else: abilityID = currIdTest abilityIDFound = True diceSizes = [4,6,8,10,12,20] damageDice = diceSizes[universal_functions.GetValidOption(1,len(diceSizes),"That is not a index in the range.\nPlease try again: ","the dice sizes are: " + str(diceSizes) + "\nChoose which index you want as damage-dice for this spell: ")-1] diceRolls = universal_functions.GetValidOption(1,1000000,"You cannot have 0, negative numbers, very high numbers or decimal numbers as nuber of dice to roll.\nPlease try again: ","Choose how many damage-dice that should be rolled for this spell: ") modifyer = universal_functions.GetValidOption(1,6,"That is not in the index.\nPlease try again: ", "[str, dex, con, int, wis, cha]\nChoose 1-6 which stat you want as modifyer for this spell ")-1 file = open("Resources/Spells/" + spellName + ".py","w") file.write("import math\n") file.write("import random\n") file.write("from Scripts import universal_functions\n") file.write("from Scripts import universal_data\n") file.write("abilityID = " + str(abilityID) + "\n") file.write("def " + spellName + "(user, target, charList):\n") file.write("\tmodifyer = math.floor((charList[user]['Stats'][" + str(modifyer) + "]-10)/2)\n") file.write("\tattackRoll = universal_functions.rollDice(1,20,1,1,False) + modifyer\n") file.write("\tprint(charList[user]['Name'] + ' used " + spellName + "')\n") file.write("\tprint(charList[user]['Name'] + ' rolled a ' + str(attackRoll) + ' to hit')\n") file.write("\tif attackRoll - modifyer == 20:\n") file.write("\t\tdamage = 2*(universal_functions.rollDice(1," + str(damageDice) + "," + str(diceRolls) + "," + str(diceRolls) + ", False))+modifyer\n") file.write("\t\tprint(charList[user]['Name'] + ' rolled a critical and dealt: ' + str(damage) + ' damage')\n") file.write("\telif attackRoll >= charList[target]['AC']:\n") file.write("\t\tdamage = universal_functions.rollDice(1," + str(damageDice) + "," + str(diceRolls) + "," + str(diceRolls) + ", False)+modifyer\n") file.write("\t\tprint(charList[user]['Name'] + ' hit and dealt: ' + str(damage) + ' damage')\n") file.write("\telse:\n") file.write("\t\tdamage = 0\n") file.write("\t\tprint(charList[user]['Name'] + ' missed')\n") file.write("\treturn([target,-damage])\n") file.write("universal_data.abilities.append([abilityID," + spellName + "])\n") file.close() exec("from Spells import " + spellName) solo_encounter.ImportNewSpell(spellName)
def RunProgram( ): #I make the program structure a function in order to guarrantee that i have defined all required function and variables already #importing global variables global name global level global charType global resistances global stats global movementSpeed global race global subRace global size global sizeFlavor global langs global age global alignment global abilities global proficiencies global traits global charClass global health global AC global equipment global profBonus name = input("What do you want to call this character? " ) #every character needs a name charType = input( "is this character ment to be an monster or a player? m/p ").lower() while (charType != "m" and charType != "p"): #loop to ensure the player chooses a valid option print("you did not choose 'm' or 'p'") charType = input( "is this character ment to be an monster or a player? m/p ").lower( ) level = universal_functions.GetValidOption( 1, 20, "That is not a valid level for a DnD player\nPlease try again ", "what level should this character start out as? ") statChoiseMethods = [RollStats, PointBuyStats, PredefinedStats] statChoiseMethods[universal_functions.GetValidOption( 1, 3, "you did not choose 1/2/3. Please try again: ", "How do you want to choose your stats?\n1.\tRoll stats\n2.\tPoint buy\n3.\tPredefined stats\nChoose 1/2/3: " ) - 1]() AssignRace() AssignClass() AssignHp() AssignAlignment() GetArmorType() profBonus = 1 + math.ceil(level / 4) saveCharacter(name, stats, movementSpeed, level, charType, race, resistances, size, sizeFlavor, langs, age, alignment, subRace, abilities, proficiencies, traits, charClass, health, AC, equipment, profBonus) os.system('cls')
def AssignHp(): global level global health global classDict conMod = (math.floor((stats[2] - 10) / 2)) if conMod < 0: conMod = 0 hitDie = classDict['HitDie'] preDefHpPrLv = int((hitDie / 2) + 1) health = hitDie + conMod hpChoise = universal_functions.GetValidOption( 1, 2, "That is not a valid choise. Please try again: ", "Do you want to get hp by:\n1.\tRolling it randomly on a d" + str(hitDie) + "\n2.\tChoose the predefined which for your class is: " + str(int(preDefHpPrLv)) + "\nWhat is your choise? ") if hpChoise == 1: for i in range(level - 1): health += random.randint(1, hitDie) + conMod else: for i in range(level - 1): health += preDefHpPrLv + conMod print("Your character will start with: " + str(health) + " HP")
def RunProgram(): input("This option is not done yet, currently only creates a test file") choises = [CreateWeapon, CreateSpell, CreateArmor] choiseString = "There are " + str(len(choises)) + " different things to do in this part of the program:\n" for i in range(len(choises)): choiseString += str(i+1) + ".\t" + choises[i].__name__ + "\n" choiseString += "What do you want to do: " choises[universal_functions.GetValidOption(1,len(choises),"That is not a number in the list. Please try again: ",choiseString)-1]() input() os.system('cls')
def AssignClass(): global charClass global classes global classDict classMessage = ("There are " + str(len(classes)) + " classes which are:\n") for i in range(1, len(classes) + 1): classMessage += (str(i) + ".\t" + classes[i - 1]['Name'] + "\n") classMessage += "Which class do you want to play? " classDict = classes[universal_functions.GetValidOption( 1, len(classes), "That is not a class in the range", classMessage) - 1] charClass = classDict['Name']
def playerTurn(): global abilities print("player turn:") chooseAttackString = ("you have " + str(len(abilities)) + " different actions:\n") for i in range(len(abilities)): chooseAttackString += str(i + 1) + ".\t" + abilities[i][1].__name__ + "\n" chooseAttackString += "Which one do you want to use? " action = universal_functions.GetValidOption( 1, len(abilities), "That is not a valid choise of an attack. Please try again: ", chooseAttackString) - 1 damageList = abilities[action][1](0, 1, charList) health[damageList[0]] += damageList[1]
def AssignAlignment(): global alignment alignments = [ "Lawful good", "Neutral good", "Chaotic good", "Lawful neutral", "True neutral", "Chaotic neutral", "Lawful evil", "Neutral evil", "Chaotic evil" ] alignment = alignments[universal_functions.GetValidOption( 1, 9, "That value is not in the list alignment list. Please try again: ", "Choose which alignment you're character will have\n" + "1.\t" + str(alignments[0]) + "\n" + "2.\t" + str(alignments[1]) + "\n" + "3.\t" + str(alignments[2]) + "\n" + "4.\t" + str(alignments[3]) + "\n" + "5.\t" + str(alignments[4]) + "\n" + "6.\t" + str(alignments[5]) + "\n" + "7.\t" + str(alignments[6]) + "\n" + "8.\t" + str(alignments[7]) + "\n" + "9.\t" + str(alignments[8]) + "\n" + "What alignment do you want? ") - 1]
def GetArmorType(): global equipment global AC global stats dexMod = math.floor((stats[1] - 10) / 2) if math.floor( (stats[1] - 10) / 2) >= 0 else 0 armorChoise = universal_functions.GetValidOption( 1, 3, "That is not a valid choise of Armor", "There are three armortypes you can choose:\n1.\tLight armor\n2.\tMedium armor\n3.\tHeavy armor\nWhat armortype do you want? " ) - 1 armorList = [["Padded", 11 + dexMod], ["Hide", 12 + [dexMod if dexMod <= 2 else 2][0]], ["Ring Mail", 14]] equipment.append(armorList[armorChoise][0]) AC = armorList[armorChoise][1]
def AssignSubRace(subRaceDict): global subRace global race global races global stats global movementSpeed global resistances global size global sizeFlavor global langs global age subRaces = [] for key in subRaceDict: subRaces.append(key) numSubRaces = len(subRaces) choiseString = ("The race: " + race + " has " + str(numSubRaces - 1) + " sub-races which are as follows:\n") for i in range(1, numSubRaces): choiseString += (str(i) + ".\t" + subRaces[i] + "\n") choiseString += "Which sub-race do you want this character to be? " subRace = subRaces[universal_functions.GetValidOption( 1, numSubRaces - 1, "That is not a subrace-number on the list", choiseString)] subRaceBonuses = [ "resistances", "abilities", "stats", "proficiencies", "movement", "traits", "spell" ] subRaceBonusFunctions = [ AddRes, AddAbility, ASI, AddProficiencie, SetSpeed, AddTrait, AddSpell ] for subRaceAbility in subRaceDict[subRace]: try: subRaceBonusFunctions[subRaceBonuses.index(subRaceAbility[0])]( subRaceAbility[1]) except ValueError: pass subRace = ", " + subRace
def AssignMonster(): global monster monsters = [ x for x in os.listdir("Resources/Monsters") if x.endswith(".txt") ] if len(monsters) == 0: print( "You don have any monsters to play against, make one and then come back" ) return (False) chooseMonsMessage = "Your current monsters are:\n" for i in range(len(monsters)): chooseMonsMessage += (str(i + 1) + ".\t" + str(monsters[i].split(".")[0]) + "\n") chooseMonsMessage += "What monster do you want to play against? " failString = "That is not a valid monster choise, please try again: " monsterCharNum = universal_functions.GetValidOption( 1, len(monsters), failString, chooseMonsMessage) monsterFile = open("Resources/Monsters/" + monsters[monsterCharNum - 1], "r") for line in monsterFile: monster[line.split(":")[0]] = ast.literal_eval(line.split("\"")[1]) monsterFile.close()
def RollStats( ): #one of the three ways the stats can be filled out, this one uses the ranom method global stats statValues = [] print( "You have chossen to roll your stats.\nThe format for rolling stats is 4d6k3" ) for numberOfStats in range(6): tempStat = [] statSum = 0 for rollsPerStat in range(4): tempStat.append(random.randint(1, 6)) tempStat.sort() tempStat[0] = 0 for num in tempStat: statSum += num statValues.append(statSum) statValues.sort() print("Your stat rolls are: " + str(statValues)) count = 0 for stat in [ "Strength", "Dexterity", "Constitution", "Intelligence", "Wisdom", "Charisma" ]: choise = universal_functions.GetValidOption( 1, 6 - count, "That is not a valid choise, please try again: ", "Choose which index of the stat rolls you want as " + stat + ". Choose in range 1-" + str(6 - count) + ": ") choise -= 1 stats.append(statValues[choise]) print("You have choosen " + str(statValues[choise]) + " for " + str(stat)) del statValues[choise] if (len(statValues) != 0): print("Your remaining rolls are: " + str(statValues)) count += 1
def PredefinedStats( ): #one of the three ways the stats can be filled out, this one you pick each stat from a list of values global stats statValues = [15, 14, 13, 12, 10, 8] print("You have chosen to pick stats form the predefined stat list") print("The predefined stat list is: " + str(statValues)) count = 0 for stat in [ "Strength", "Dexterity", "Constitution", "Intelligence", "Wisdom", "Charisma" ]: choise = universal_functions.GetValidOption( 1, (6 - count), "You did not choose a value in that range.\nChoose a value in the range 1-" + str(6 - count) + ": ", ("Choose which index of the stat rolls you want as " + stat + ". Choose in range 1-" + str(6 - count) + ": ")) - 1 stats.append(statValues[choise]) print("You have choosen " + str(statValues[choise]) + " for " + stat) del statValues[choise] if (len(statValues) != 0): print("Your remaining rolls are: " + str(statValues)) count += 1
def RunProgram(): input( "This option is not done yet.\nCurrently only imports a character file into memory and prints it to the output" ) end = False chosenCharType = False while (not chosenCharType): chosenChar = False levelChoise = input( "Do you want to level up a player character, monster or not level up at all 'p'/'m'/'e': " ).lower() while (not chosenChar): if levelChoise == "p": chars = [ x for x in os.listdir("Resources/Characters") if x.endswith(".txt") ] if len(chars) == 0: print( "There are currently no existing characters to level") break chooseCharMessage = "Your current characters are:\n" for i in range(len(chars)): chooseCharMessage += (str(i + 1) + ".\t" + str(chars[i].split(".")[0]) + "\n") chooseCharMessage += "What character do you want to level up? " failString = "That is not a valid character choise, please try again: " levelCharNum = universal_functions.GetValidOption( 1, len(chars), failString, chooseCharMessage) levelChar = open( "Resources/Characters/" + chars[levelCharNum - 1], "r") chosenChar = True chosenCharType = True elif levelChoise == "m": chars = [ x for x in os.listdir("Resources/Monsters") if x.endswith(".txt") ] if len(chars) == 0: print( "There are no currently existing characters to level") break chooseCharMessage = "Your current monsters are:\n" for i in range(len(chars)): chooseCharMessage += (str(i + 1) + ".\t" + str(chars[i].split(".")[0]) + "\n") chooseCharMessage += "What monster do you want to level up? " failString = "That is not a valid monster choise, please try again: " levelCharNum = universal_functions.GetValidOption( 1, len(chars), failString, chooseCharMessage) levelChar = open( "Resources/Monsters/" + chars[levelCharNum - 1], "r") chosenChar = True chosenCharType = True elif levelChoise == "e": end = True chosenChar = True chosenCharType = True else: levelChoise = input( "That is not a valid choise, Please try again: ") if (not end): print(levelChar.read()) input("The character has been leveled up") os.system('cls')
from Scripts import universal_functions import os def AssignDicts(): level_up.AssignDicts() create_character.AssignDicts() AssignDicts() programs = [ create_character, create_misc, level_up, solo_encounter, diceroller ] numOfScripts = len(programs) playing = True print( "Welcome to DnDlike, the best battle sim and character creater for DnD there is, maybe." ) while (playing): option = universal_functions.GetValidOption( 1, numOfScripts + 1, "That is not a valid option. Please try again: ", "Do you want to:\n1.\tCreate a character\n2.\tCreate equipment, spells or alike\n3.\tLevel up a character\n4.\tPlay an encounter with a character\n5.\tUse the diceroller\n6.\tStop the program\nPlease choose: " ) if option > numOfScripts: playing = False else: os.system('cls') programs[option - 1].RunProgram() input( "The program is now closing, thank you for playing\nIf you enjoyed you may consider donating at 'https://www.paypal.me/SirEraisuithon'" )