├── .DS_Store ├── .gitattributes ├── .gitignore ├── Armor.py ├── Enemy.py ├── Game.py ├── Hero.py ├── Item.py ├── LICENSE ├── README.md ├── Shield.py ├── Weapon.py ├── __init__.py ├── csv ├── armor.csv ├── enemies.csv ├── items.csv ├── levelnotes.csv ├── riddles.csv ├── shields.csv └── weapons.csv ├── db └── game.db ├── dbsetup.py ├── quoteslist.txt ├── saves └── TESTSAVE1.hero └── texttools.py /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crawsome/PyRPG_Mini/a53a409bc2ef48ec72ef57bf0ee249d203c5e248/.DS_Store -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | PyRPG_Mini.iml 3 | markdown-navigator.xml 4 | misc.xml 5 | modules.xml 6 | vcs.xml 7 | workspace.xml 8 | markdown-navigator 9 | inspectionProfiles 10 | -------------------------------------------------------------------------------- /Armor.py: -------------------------------------------------------------------------------- 1 | import Game 2 | import random 3 | 4 | 5 | class Armor: 6 | # level,classtype,name,type,basedef,durability 7 | def __init__(self, armorlevel, armorclasstype, armorname, armortype, armorbasedef, armordur): 8 | # level 9 | self.level = armorlevel 10 | 11 | # hero Class 12 | self.classtype = armorclasstype 13 | 14 | # hero Class 15 | self.type = armortype 16 | self.name = armorname 17 | 18 | # Armor Quality (rusty, common, great, magical, legendary) 19 | chance = random.randint(1, 100) 20 | 21 | if chance < 20: 22 | self.quality = 'Rusty' 23 | elif chance >= 21 or chance < 65: 24 | self.quality = 'Common' 25 | elif chance >= 66 or chance < 86: 26 | self.quality = 'Great' 27 | elif chance >= 85 or chance < 96: 28 | self.quality = 'Magical' 29 | elif chance >= 96 or chance < 100: 30 | self.quality = 'Legendary' 31 | 32 | # Defense Values 33 | self.basedefn = armorbasedef 34 | if self.quality == 'Rusty': 35 | self.basedefn = int(self.basedefn * 0.9) 36 | elif self.quality == 'Common': 37 | self.basedefn = int(self.basedefn * 1) 38 | elif self.quality == 'Great': 39 | self.basedefn = int(self.basedefn * 1.25) 40 | elif self.quality == 'Magical': 41 | self.basedefn = int(self.basedefn * 1.6) 42 | elif self.quality == 'Legendary': 43 | self.basedefn = int(self.basedefn * 2) 44 | 45 | self.defn = self.basedefn 46 | 47 | # armor durability value 48 | self.maxdur = armordur 49 | if self.quality == 'Rusty': 50 | self.maxdur = int(self.maxdur * 0.9) 51 | elif self.quality == 'Common': 52 | self.maxdur = int(self.maxdur * 1) 53 | elif self.quality == 'Great': 54 | self.maxdur = int(self.maxdur * 1.25) 55 | elif self.quality == 'Magical': 56 | self.maxdur = int(self.maxdur * 1.6) 57 | elif self.quality == 'Legendary': 58 | self.maxdur = int(self.maxdur * 2) 59 | self.dur = self.maxdur 60 | 61 | # damage durability, and check to see if broken 62 | def damagedur(self, aug, curve): 63 | self.dur -= int(aug * curve * .1) 64 | self.isbroken() 65 | pass 66 | 67 | # restore dur and check to see if fixed 68 | def restoredur(self, aug): 69 | self.dur += aug 70 | if self.dur > self.maxdur: 71 | self.dur = self.maxdur 72 | if not self.isbroken(): 73 | self.defn = self.basedefn 74 | 75 | # repair entirely 76 | def repair(self): 77 | self.defn = self.basedefn 78 | self.dur = self.maxdur 79 | 80 | # 15% durability = stat reduction 81 | def isbroken(self): 82 | if self.dur <= 0: 83 | self.gearbreak() 84 | return True 85 | elif self.dur > 0: 86 | return False 87 | 88 | # this breaks the gear 89 | def gearbreak(self): 90 | self.atk = int(self.basedefn * .3) 91 | 92 | # prints all armor info 93 | def printarmorinfo(self): 94 | Game.marqueeprint('ARMOR') 95 | print(Game.lr_justify('Level:', str(self.level), 60)) 96 | print(Game.lr_justify('Name:', str(self.name), 60)) 97 | print(Game.lr_justify('Type:', str(self.type), 60)) 98 | print(Game.lr_justify('Defense:', str(self.defn) + '/' + str(self.basedefn), 60)) 99 | print(Game.lr_justify('Dur:', str(self.dur) + '/' + str(self.maxdur), 60)) 100 | print(Game.lr_justify('Broken?:', str(self.isbroken()), 60)) 101 | print(Game.lr_justify('Quality:', str(self.quality()), 60)) 102 | 103 | # ['Level', 'Name', 'Type', 'Defense', 'Dur', 'Broken?', 'Power'] 104 | def datadict(self): 105 | return {'Level': str(self.level), 106 | 'Name': str(self.name) + ' ' + str(self.type), 107 | 'Def': str(self.defn), 108 | 'Dur': str(self.dur) + '/' + str(self.maxdur), 109 | 'Broken?': str(self.isbroken()), 110 | 'Repair Cost': str(self.maxdur - self.dur) + ' gold', 111 | 'Quality': str(self.quality) 112 | } 113 | -------------------------------------------------------------------------------- /Enemy.py: -------------------------------------------------------------------------------- 1 | import Game 2 | 3 | 4 | class Enemy: 5 | def __init__(self, enemylevel, enemyname1, enemyname2, enemyname3, enemyatk, enemyxp, enemygold, enemyhp, enemydefn, 6 | enemystatuseffect): 7 | self.level = enemylevel 8 | if enemyname2 == enemyname3: 9 | enemyname3 = '' 10 | self.name = str(enemyname1) + ' ' + str(enemyname2) + ' ' + str(enemyname3) 11 | self.atk = enemyatk 12 | self.xp = enemyxp 13 | self.gold = enemygold 14 | self.maxhp = enemyhp 15 | self.hp = self.maxhp 16 | self.defn = enemydefn 17 | self.effect = enemystatuseffect 18 | 19 | # Heals user up to max health 20 | def heal(self, hpup): 21 | Game.centerprint('Enemy heals for ' + str(int(hpup)) + ' HP') 22 | print('') 23 | self.hp += hpup 24 | if self.hp > self.maxhp: 25 | self.hp = self.maxhp 26 | 27 | # take damage 28 | def damage(self, hpdown, curve): 29 | effatk = hpdown + (hpdown * curve) 30 | self.hp -= int(effatk) 31 | Game.centerprint(str(self.name) + ' takes ' + str(int(effatk)) + ' damage!') 32 | if self.hp < 0: 33 | self.hp = 0 34 | 35 | # resets enemy to max HP (done after a fight) 36 | def reset(self): 37 | self.hp = self.maxhp 38 | 39 | # check if enemy is alive 40 | def isalive(self): 41 | if self.hp > 0: 42 | return True 43 | else: 44 | return False 45 | 46 | # enemy running away awards normal XP/Gold to hero for now 47 | def run(self): 48 | self.hp = 0 49 | 50 | # enemy could get stronger 51 | def anger(self): 52 | Game.centerprint(str(self.name) + ' got Angrier!') 53 | self.atk += self.atk * .14 54 | 55 | # enemy could get weaker 56 | def weaker(self): 57 | Game.centerprint(str(self.name) + ' got Weaker!') 58 | self.atk -= self.atk * .14 59 | 60 | # prints out all enemy detail 61 | def printenemyinfodetail(self): 62 | print(str(self.name)) 63 | print('\tLevel:\t' + str(self.level)) 64 | print('\tAttack:\t' + str(self.atk)) 65 | print('\tXP:\t\t' + str(self.xp)) 66 | print('\tGold:\t' + str(self.gold)) 67 | print('\tMaxHP:\t' + str(self.maxhp)) 68 | print('\tHP:\t\t' + str(self.hp)) 69 | 70 | def datadict(self): 71 | return {'Level': str(self.level), 72 | 'Attack': str(self.atk), 73 | 'XP': str(self.xp), 74 | 'Gold': str(self.gold), 75 | 'MaxHP': str(self.maxhp), 76 | 'HP': str(self.hp) 77 | } 78 | -------------------------------------------------------------------------------- /Game.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | import os 3 | import pickle 4 | import random 5 | import time 6 | from sqlite3 import connect 7 | import Enemy 8 | import Hero 9 | import dbsetup 10 | from texttools import * 11 | 12 | 13 | # game class makes the game work instantiates all other classes at some point. 14 | class Game: 15 | def __init__(self): 16 | # adds a little suspense 17 | # TODO: add suspense option to some printing methods? 18 | self.suspensemode = 0 19 | 20 | # provides inner workings of game, some live-comments 21 | # TODO: add more comments and stats as game goes on 22 | self.debugging = 0 23 | centerprint('Debugging Mode? [1] for yes, [ENTER] for no') 24 | self.debugging = input() 25 | 26 | # riddle mode 0 - optional, 1 - mandatory 27 | centerprint('Riddles Mandatory? [1] for yes, [ENTER] for no') 28 | self.riddlemode = input() 29 | if self.riddlemode == '': 30 | self.riddlemode = 0 31 | 32 | # provides a way to speed through battle (risky!) 33 | self.autoattack = 0 34 | 35 | # make blank hero and enemy objects 36 | self.ourhero = 0 37 | self.ourenemy = 0 38 | 39 | # global text width 40 | self.textwidth = 70 41 | 42 | # width of data, so it's not so spaced-out 43 | self.datawidth = 55 44 | 45 | # Create all game databases (only needs to run once to make databases) 46 | firsttime = False 47 | if 'game.db' not in os.listdir('./db/'): 48 | centerprint('This looks like it\'s your first time playing.') 49 | centerprint('We must load the database first') 50 | centerprint('This will only take a moment...') 51 | firsttime = True 52 | 53 | # re-creates the database, in case you change values1 54 | if firsttime: 55 | print('Loading Database:') 56 | oursetup = dbsetup.dbsetup() 57 | oursetup.setupdb() 58 | if self.debugging: 59 | printtest() 60 | 61 | # our database path 62 | self.dbpath = './db/game.db' 63 | 64 | # import and create our player database 65 | self.gamedb = connect(self.dbpath) 66 | self.conn = self.gamedb.cursor() 67 | 68 | # width of centered data in screencenter 69 | self.datawidth = 55 70 | 71 | # TODO: make self.ourhero.levelup and newhero the same function 72 | # makes a new hero object for when starting new game. 73 | def newhero(self): 74 | self.conn.execute('SELECT * FROM levelnotes WHERE level = 1;') 75 | rows = self.conn.fetchall() 76 | marqueeprint('[CHOOSE CLASS]') 77 | centerprint('[w]arrior [m]age [h]unter') 78 | ourclass = input() 79 | if ourclass == 'w' or ourclass == '': 80 | ourclass = 'warrior' 81 | elif ourclass == 'm': 82 | ourclass = 'mage' 83 | elif ourclass == 'h': 84 | ourclass = 'hunter' 85 | else: 86 | centerprint('Please enter a valid selection') 87 | marqueeprint('[CHOOSE DIFFICULTY]') 88 | centerprint('[1]easy [2]med [3]hard') 89 | diff = input() 90 | 91 | # the harder the difficulty, the less your attack and defense 92 | if diff == '1' or diff == '': 93 | atkcurve = .2 94 | defcurve = .05 95 | elif diff == '2': 96 | atkcurve = .1 97 | defcurve = .1 98 | elif diff == '3': 99 | atkcurve = .05 100 | defcurve = .2 101 | else: 102 | centerprint('Please enter a valid selection') 103 | diff = 1 104 | atkcurve = .4 105 | defcurve = .05 106 | centerprint('Setting Difficulty to ' + str(diff)) 107 | 108 | new_hero_data = rows[0] 109 | ournewhero = Hero.Hero(ourclass, 110 | new_hero_data[0], new_hero_data[1], 111 | new_hero_data[2], new_hero_data[3], 112 | new_hero_data[4], new_hero_data[5]) 113 | ournewhero.defcurve = defcurve 114 | ournewhero.atkcurve = atkcurve 115 | marqueeprint('[ENTER NAME]') 116 | centerprint('Your name, ' + str(ournewhero.ourclass) + '?\n') 117 | ournewhero.name = input() 118 | if ournewhero.name == '': 119 | ournewhero.name = 'Sir Lazy' 120 | return ournewhero 121 | 122 | # brings game back after death. 123 | def gameloop(self): 124 | while True: 125 | marqueeprint('') 126 | centerprint('MiniRPG') 127 | centerprint('Colin Burke 2017') 128 | marqueeprint('') 129 | centerprint('[n]ew game [l]oad') 130 | decision = input() 131 | if decision == 'n' or decision == '': 132 | # Make new global hero and enemy which will change over time 133 | self.ourhero = self.newhero() 134 | self.ourenemy = self.getenemy() 135 | self.ourhero.heroperks() 136 | gridoutput(self.ourhero.datadict()) 137 | if decision == 'l': 138 | print('lOADING GAME') 139 | self.ourhero = self.loadgame() 140 | self.ourenemy = self.getenemy() 141 | while self.ourhero.isalive(): 142 | self.adventure() 143 | 144 | # where the meat of things happen, this decides what happens when you enter [a]dventure 145 | def adventure(self): 146 | centerprint('[a]dventure or [c]amp') 147 | m = input() 148 | ourrand = random.randint(0, 100) 149 | if m == 'a' or m == '': 150 | if ourrand <= 70: 151 | self.ourhero.isbattling = True 152 | # Make new enemy 153 | self.ourenemy = self.getenemy() 154 | marqueeprint('[BATTLE]') 155 | # battle until one is dead 156 | turnnum = 1 157 | while self.ourhero.isalive() and self.ourenemy.isalive() and self.ourhero.isbattling: 158 | marqueeprint('[TURN ' + str(turnnum) + ']') 159 | self.battle() 160 | turnnum += 1 161 | elif 70 < ourrand <= 90: 162 | marqueeprint('[FOUND ITEM]') 163 | itemrand = random.randrange(0, 6) 164 | if itemrand == 0: 165 | self.ourhero.ourarmor = self.ourhero.newarmor() 166 | gridoutput(self.ourhero.ourarmor.datadict()) 167 | elif itemrand == 1: 168 | self.ourhero.ourweapon = self.ourhero.newweapon() 169 | gridoutput(self.ourhero.ourweapon.datadict()) 170 | elif itemrand == 2: 171 | self.ourhero.ourshield = self.ourhero.newshield() 172 | gridoutput(self.ourhero.ourshield.datadict()) 173 | elif 3 <= itemrand <= 6: 174 | self.ourhero.ouritem = self.ourhero.newitem() 175 | gridoutput(self.ourhero.ouritem.datadict()) 176 | self.ourhero.items.append(self.ourhero.ouritem) 177 | self.ourhero.applyequip() 178 | elif 90 < ourrand <= 95: 179 | marqueeprint('A LONE TRAVELER') 180 | centerprint('You find a lone traveler,') 181 | centerprint('He says:') 182 | print('\n') 183 | with open('./quoteslist.txt', 'rb') as f: 184 | quotelist = f.read().splitlines() 185 | quote = random.choice(quotelist) 186 | quote = quote.decode('utf-8') 187 | wrapstring = textwrap.wrap(quote, width=self.datawidth) 188 | for line in wrapstring: 189 | centerprint(line) 190 | print('\n') 191 | threechoicerandom = random.randrange(0, 2) 192 | if threechoicerandom == 0: 193 | xpgain = int(self.ourhero.nextlevel * .10) 194 | self.ourhero.addxp(int(round(xpgain, 1))) 195 | if threechoicerandom == 1: 196 | goldgain = int(self.ourhero.gold * .10) 197 | self.ourhero.addgold(goldgain) 198 | if threechoicerandom == 2: 199 | pass 200 | centerprint('...you venture back to camp') 201 | elif 90 < ourrand <= 95: 202 | # a story event? 203 | centerprint('You find nothing and wander back to camp') 204 | pass 205 | elif 95 < ourrand <= 100: 206 | self.riddle() 207 | elif m == 'c': 208 | self.camp() 209 | if not self.ourhero.isalive(): 210 | return 211 | 212 | # One round of a battle 213 | def battle(self): 214 | self.ourhero.battlecount += 1 215 | self.printadversaries(self.datawidth) 216 | marqueeprint('[CHOOSE ACTION]') 217 | centerprint('[a]tk [d]ef [r]un [i]tem') 218 | centerprint('Coinflip to [h]eal (100g)') 219 | centerprint('Action?') 220 | nextmove = input() 221 | # conditions to end battle 222 | if self.ourhero.isalive(): 223 | turnnotused = True 224 | while turnnotused: 225 | turnnotused = self.playerturn(nextmove) 226 | #wait = input() 227 | if self.ourenemy.isalive(): 228 | self.enemyturn() 229 | #wait = input() 230 | if not self.ourhero.isalive(): 231 | self.ourhero.death() 232 | #wait = input() 233 | return 234 | if not self.ourenemy.isalive(): 235 | self.ourhero.isbattling = False 236 | self.ourenemy.reset() 237 | marqueeprint('[VICTORY]') 238 | self.ourhero.addgold(self.ourenemy.gold + (self.ourenemy.gold * self.ourhero.defcurve)) 239 | self.ourhero.addxp(self.ourenemy.xp + (self.ourenemy.xp * self.ourhero.defcurve)) 240 | # 15% chance to get some health back. 241 | if random.randrange(0, 100) in range(0, 15): 242 | self.ourhero.food() 243 | centerprint('Press [Enter] To continue') 244 | wait = input() 245 | if not self.ourhero.isbattling: 246 | return 247 | 248 | # One round of a player's turn 249 | def playerturn(self, m): 250 | # for health regen potion 251 | if self.ourhero.regentimer > 0: 252 | regen = int(self.ourhero.maxhp * .2) 253 | self.ourhero.heal(regen) 254 | self.ourhero.regentimer -= 1 255 | # for haste potion for 5 turn dodge increases 256 | self.ourhero.dodge = self.ourhero.basedodge 257 | if self.ourhero.hastetimer > 0: 258 | centerprint('Your dodge chance is elevated') 259 | self.ourhero.hastetimer -= 1 260 | else: 261 | self.ourhero.dodge = self.ourhero.basedodge 262 | self.ourhero.applyequip() 263 | marqueeprint('[HERO TURN]') 264 | crit = 0 265 | critrand = random.randrange(0, 100) 266 | if critrand in range(self.ourhero.crit, critrand): 267 | crit = self.ourhero.atk * .4 268 | effatk = int(self.ourhero.atk + crit) 269 | if effatk < 0: 270 | effatk = 0 271 | if m == 'a' or m == '': 272 | if critrand == 0: 273 | centerprint('CRITICAL HIT!') 274 | self.ourenemy.damage(effatk + crit, self.ourhero.atkcurve) 275 | self.ourhero.ourweapon.damagedur(effatk + crit, self.ourhero.defcurve) 276 | if self.ourenemy.hp < 0: 277 | self.ourenemy.hp = 0 278 | self.ourhero.isbattling = False 279 | return False 280 | elif m == 'd': 281 | marqueeprint('[DEFENSE]') 282 | self.ourhero.defn += self.ourhero.defn * self.ourhero.defcurve 283 | return False 284 | elif m == 'r': 285 | marqueeprint('[RUN ATTEMPT]') 286 | rand = random.randrange(0, 4) 287 | if rand == 0: 288 | centerprint('you ran away') 289 | self.ourhero.isbattling = False 290 | else: 291 | centerprint('you can\'t run!') 292 | return False 293 | elif m == 'i': 294 | itemnotchosen = True 295 | while itemnotchosen: 296 | itemnotchosen = self.item_management() 297 | return False 298 | elif m == 'h': 299 | self.ourhero.healflip() 300 | wait = input() 301 | 302 | # One round of an enemy turn 303 | def enemyturn(self): 304 | overunder = random.randrange(0, 20) 305 | if self.ourenemy.isalive: 306 | marqueeprint('[ENEMY ATTACK]') 307 | if overunder == 0: 308 | self.ourenemy.anger() 309 | elif overunder == 1: 310 | self.ourenemy.weaker() 311 | elif overunder == 2: 312 | centerprint(str(self.ourenemy.name) + ' ran away!') 313 | self.ourenemy.hp = 0 314 | self.ourhero.isbattling = False 315 | return 316 | if overunder in range(3, self.ourhero.dodge): 317 | centerprint(str(self.ourenemy.name) + ' swings and misses!') 318 | return 319 | if self.ourhero.isbattling: 320 | effatk = int(self.ourenemy.atk) 321 | if effatk < 0: 322 | effatk = 0 323 | self.ourhero.ourarmor.damagedur(effatk, self.ourhero.defcurve) 324 | self.ourhero.ourshield.damagedur(effatk, self.ourhero.defcurve) 325 | self.ourhero.damage(effatk) 326 | 327 | def riddle(self): 328 | marqueeprint('[RIDDLE]') 329 | centerprint('The area gets quiet. The wind blows.') 330 | centerprint('A torn page lands in your grasp. It reads:') 331 | print('\n') 332 | # query database for a single random riddle 333 | self.conn.execute('SELECT * FROM riddles ORDER BY RANDOM() LIMIT 1' + ';') 334 | row = self.conn.fetchall()[0] 335 | ourriddle = [row[0], row[1]] 336 | wrapstring = textwrap.wrap(ourriddle[0], width=self.datawidth) 337 | answer = str(ourriddle[1]).lower() 338 | for line in wrapstring: 339 | centerprint(line) 340 | centerprint('Speak the answer to the wind...') 341 | useranswer = input() 342 | if useranswer == '' and self.riddlemode == 1: 343 | while useranswer == '': 344 | centerprint('Please answer the riddle.') 345 | useranswer = input() 346 | if self.debugging: 347 | marqueeprint(answer + ', you cheater!') 348 | if similarstring(useranswer, answer) and useranswer != '': 349 | centerprint('You have successfully answered the riddle') 350 | centerprint('The answer was \"' + answer + '\"') 351 | centerprint('I present you with this:') 352 | self.ourhero.addgold(self.ourhero.level * 44) 353 | self.ourhero.addxp(self.ourhero.nextlevel * .17) 354 | else: 355 | centerprint('You Fail! Leave this place!') 356 | 357 | 358 | # fetch a new enemy that is at hero's level (for now...) 359 | def getenemy(self): 360 | self.conn.execute('SELECT * FROM enemies WHERE level = ' + str(self.ourhero.level) + ';') 361 | rows = self.conn.fetchall() 362 | new_enemy = random.choice(rows) 363 | 364 | # create random enemy name 365 | levelname = random.choice((rows[0][1], rows[1][1], 366 | rows[2][1], rows[3][1], 367 | rows[4][1])) 368 | # part of random name 369 | adjective = random.choice((rows[0][2], rows[1][2], 370 | rows[2][2], rows[3][2], 371 | rows[4][2])) 372 | # part of random name 373 | enemyname = random.choice((rows[0][3], rows[1][3], 374 | rows[2][3], rows[3][3], 375 | rows[4][3])) 376 | # part of random name 377 | ournewenemy = Enemy.Enemy(new_enemy[0], levelname, adjective, enemyname, new_enemy[4], 378 | new_enemy[5], (new_enemy[6] + (new_enemy[6] * self.ourhero.defcurve)), 379 | new_enemy[7], new_enemy[8], new_enemy[9]) 380 | return ournewenemy 381 | 382 | # a blacksmith who can repair or sell gear 383 | def blacksmith(self): 384 | centerprint('An old Blacksmith rests at your camp') 385 | centerprint('He shows his wares and services:') 386 | centerprint('[f]ix gear [b]uy gear') 387 | nextdecision = input() 388 | centerprint('Gold: ' + str(self.ourhero.gold)) 389 | if nextdecision == 'f': 390 | 391 | # offer equipment repair for any of the 3 slots, for 1g/durability point 392 | centerprint('The Blacksmith can offer repair ') 393 | centerprint('services for 1g/repair point') 394 | centerprint('Here is your gear durability:') 395 | 396 | # print all your gear out 397 | gridoutput(self.ourhero.ourweapon.datadict()) 398 | gridoutput(self.ourhero.ourshield.datadict()) 399 | gridoutput(self.ourhero.ourarmor.datadict()) 400 | 401 | # user input for what to repair, or all of it, for convenience 402 | decision = input('What do you want to repair? [a] for all') 403 | if decision == '1' or decision == 'a': 404 | repaircost = self.ourhero.ourweapon.maxdur - self.ourhero.ourweapon.dur 405 | centerprint('Repair Your weapon?') 406 | centerprint('Cost: ' + str(repaircost) + ' gold') 407 | centerprint('[y]es [n]o') 408 | decision2 = input() 409 | if decision2 == 'y' and self.ourhero.gold >= repaircost: 410 | self.ourhero.gold -= repaircost 411 | self.ourhero.ourweapon.dur = self.ourhero.ourweapon.maxdur 412 | centerprint('Repair Success.') 413 | if decision == '2' or decision == 'a': 414 | repaircost = self.ourhero.ourshield.maxdur - self.ourhero.ourshield.dur 415 | centerprint('Repair Your shield?') 416 | centerprint('Cost: ' + str(repaircost) + ' gold') 417 | centerprint('[y]es [n]o') 418 | decision2 = input() 419 | if decision2 == 'y' and self.ourhero.gold >= repaircost: 420 | self.ourhero.gold -= repaircost 421 | self.ourhero.ourshield.dur = self.ourhero.ourshield.maxdur 422 | centerprint('Repair Success.') 423 | if decision == '3' or decision == 'a': 424 | repaircost = self.ourhero.ourarmor.maxdur - self.ourhero.ourarmor.dur 425 | centerprint('Repair Your armor?)') 426 | centerprint('Cost: ' + str(repaircost) + ' gold') 427 | centerprint('[y]es [n]o') 428 | decision2 = input() 429 | if decision2 == 'y' and self.ourhero.gold >= repaircost: 430 | self.ourhero.gold -= repaircost 431 | self.ourhero.ourarmor.dur = self.ourhero.ourarmor.maxdur 432 | centerprint('Repair Success') 433 | 434 | # offer random choice of weapon, armor, or shield at 1.5x value price 435 | elif nextdecision == 'b': 436 | weaponforsale = self.ourhero.newweapon() 437 | armorforsale = self.ourhero.newarmor() 438 | shieldforsale = self.ourhero.newshield() 439 | 440 | marqueeprint('[YOUR GEAR]') 441 | gridoutput(self.ourhero.ourweapon.datadict()) 442 | gridoutput(self.ourhero.ourshield.datadict()) 443 | gridoutput(self.ourhero.ourarmor.datadict()) 444 | print('') 445 | 446 | # determine weapon costs 447 | wepcost = weaponforsale.level * 60 * self.ourhero.defcurve 448 | armcost = armorforsale.level * 60 * self.ourhero.defcurve 449 | shcost = shieldforsale.level * 60 * self.ourhero.defcurve 450 | 451 | data1 = [str(weaponforsale.name), str(weaponforsale.type), 452 | str(weaponforsale.baseatk), 453 | str(wepcost)] 454 | data2 = [str(shieldforsale.name), str(shieldforsale.type), 455 | str(shieldforsale.basedefn), 456 | str(shcost)] 457 | data3 = [str(armorforsale.name), str(armorforsale.type), 458 | str(armorforsale.basedefn), 459 | str(armcost)] 460 | 461 | title = ('[GEAR FOR SALE]') 462 | dataheader = ['Name', 'Type', 'Atk/Def', 'Cost'] 463 | alldata = [data1, data2, data3] 464 | fiverowprintoptions(dataheader, alldata, title) 465 | print('\n') 466 | centerprint('Please enter decision [ENTER] to go back') 467 | itemindex = input() 468 | if itemindex not in ['1', '2', '3', '']: 469 | centerprint('Please enter a valid choice') 470 | elif itemindex == '1': 471 | self.ourhero.ourweapon = weaponforsale 472 | if self.ourhero.gold < wepcost: 473 | centerprint('You don\'t have enough money!') 474 | self.ourhero.gold -= wepcost 475 | centerprint('You equip your new gear: ' + str(weaponforsale.name) + ' ' + str(weaponforsale.type)) 476 | elif itemindex == '2': 477 | self.ourhero.ourshield = shieldforsale 478 | if self.ourhero.gold < wepcost: 479 | centerprint('You don\'t have enough money!') 480 | return 481 | self.ourhero.gold -= armcost 482 | centerprint('You equip your new gear: ' + str(shieldforsale.name) + ' ' + str(shieldforsale.type)) 483 | elif itemindex == '3': 484 | self.ourhero.ourarmor = armorforsale 485 | if self.ourhero.gold < shcost: 486 | centerprint('You don\'t have enough money!') 487 | return 488 | self.ourhero.gold -= shcost 489 | centerprint('You equip your new gear: ' + str(armorforsale.name) + ' ' + str(armorforsale.type)) 490 | self.ourhero.applyequip() 491 | return 492 | 493 | # a camp where you regain hp after so many fights. 494 | def camp(self): 495 | camping = True 496 | while camping: 497 | self.ourhero.hp = self.ourhero.maxhp 498 | marqueeprint('[CAMP]') 499 | centerprint('You rest at camp. Hero HP: ' + str(self.ourhero.hp)) 500 | centerprint('[a]dventure [i]tem [h]ero') 501 | centerprint('[p]eddler [b]lacksmith') 502 | centerprint('[l]oad [s]ave [q]uit') 503 | m = input() 504 | if m == 'i': 505 | iteming = True 506 | while iteming: 507 | iteming = self.item_management() 508 | elif m == 'h': 509 | marqueeprint('[HERO DETAIL]') 510 | gridoutput(self.ourhero.datadict()) 511 | wait = input() 512 | gridoutput(self.ourhero.ourweapon.datadict()) 513 | wait = input() 514 | gridoutput(self.ourhero.ourshield.datadict()) 515 | wait = input() 516 | gridoutput(self.ourhero.ourarmor.datadict()) 517 | wait = input() 518 | elif m == 'a' or m == '': 519 | return 520 | # adventure() 521 | elif m == 'l': 522 | marqueeprint('[LOAD GAME]') 523 | self.ourhero = self.loadgame() 524 | elif m == 's': 525 | marqueeprint('[SAVE GAME]') 526 | self.savegame() 527 | elif m == 'b': 528 | marqueeprint('[BLACKSMITH]') 529 | self.blacksmith() 530 | elif m == 'p': 531 | marqueeprint('[PEDDLER\'S WARES]') 532 | self.peddler() 533 | elif m == 'q': 534 | marqueeprint('[QUIT]') 535 | decision = input('Are you sure?') 536 | if decision == 'y': 537 | quit() 538 | else: 539 | centerprint('You walk back to camp') 540 | 541 | # sell the hero items (will be able to buy soon) 542 | def peddler(self): 543 | centerprint('An old Peddler rests at your camp.') 544 | centerprint('He shows his wares:') 545 | centerprint('[b]uy, [r]iddle (100g)') 546 | nextdecision = input() 547 | if nextdecision == 'b': 548 | pass 549 | item1 = self.ourhero.newitem() 550 | item2 = self.ourhero.newitem() 551 | item3 = self.ourhero.newitem() 552 | item4 = self.ourhero.newitem() 553 | item5 = self.ourhero.newitem() 554 | itemarray = [item1, item2, item3, item4, item5] 555 | for i, item in enumerate(itemarray): 556 | print(str(i + 1) + '\t' + item.name + '\t' + str(item.val * 1.5)) 557 | print('Your selection? (ENTER to go back)') 558 | selection = input() 559 | if selection == '1': 560 | self.ourhero.buyitem(item1) 561 | elif selection == '2': 562 | self.ourhero.buyitem(item2) 563 | elif selection == '3': 564 | self.ourhero.buyitem(item3) 565 | elif selection == '4': 566 | self.ourhero.buyitem(item4) 567 | elif selection == '5': 568 | self.ourhero.buyitem(item5) 569 | elif selection == '': 570 | centerprint('\"WHYD YOU COME HERE AND NOT BUY ANYTHING?\"') 571 | return 572 | else: 573 | centerprint('Get out of here you bum!') 574 | # offer random choice of items at 1.5x value price 575 | if nextdecision == 'r': 576 | if self.ourhero.canafford(100): 577 | self.ourhero.gold -= 100 578 | self.riddle() 579 | 580 | # pickle in to hero obj and start gameloop 581 | def loadgame(self): 582 | # load hero object from pickle file 583 | dirlist = os.listdir('./saves/') 584 | for i, item in enumerate(dirlist): 585 | print(str(i) + ' - ' + str(item)) 586 | print(str(datetime.datetime.fromtimestamp(os.path.getmtime('./saves/' + item)))) 587 | print('\n') 588 | index = input("Which Character?\nOr [c]ancel") 589 | if index == '': 590 | index = 0 591 | if index == 'c': 592 | return 593 | index = int(index) 594 | ourpickle = open(('./saves/' + str(dirlist[index])), "rb") 595 | ourdata = pickle.load(ourpickle) 596 | return ourdata 597 | 598 | # pickle our hero to file 599 | def savegame(self): 600 | # pickle hero object to file 601 | # should prompt to overwrite 602 | heroname = input('Name your save file\nOr [c]ancel') 603 | if heroname == 'c': 604 | return 605 | savefolder = "./saves/" 606 | filepath = savefolder + heroname + '.hero' 607 | gamedata = self.ourhero 608 | if not os.path.isfile(filepath): 609 | with open(filepath, 'wb') as f: 610 | pickle.dump(gamedata, f, -1) 611 | else: 612 | answer = input('Overwrite?') 613 | if answer.lower() == 'y': 614 | os.remove(filepath) 615 | print(os.listdir('./saves/')) 616 | with open(filepath, 'wb') as f: 617 | pickle.dump(gamedata, f, -1) 618 | elif answer.lower() == 'n': 619 | newname = input('Enter New Save file name') 620 | with open(filepath + str(newname), 'wb') as f: 621 | pickle.dump(gamedata, f, -1) 622 | 623 | # TODO: Go back from item menu without enemy turn happening 624 | # TODO: Make this into an item selection method, with an argument if [s]elling, [u]sing, or [d]iscarding 625 | # lets hero use items 626 | def item_management(self): 627 | if not self.ourhero.items: 628 | centerprint('Inventory Empty') 629 | return False 630 | # print all the item's info 631 | for i, item in enumerate(self.ourhero.items): 632 | leftprint('ITEM: ' + str(i+1)) 633 | gridoutput(self.ourhero.items[i].datadict()) 634 | centerprint('Please enter decision, [ENTER] to go back') 635 | try: 636 | itemindex = input() 637 | itemindex = int(itemindex) 638 | itemindex -= 1 639 | self.ourhero.ouritem = self.ourhero.items[int(itemindex)] 640 | del (self.ourhero.items[int(itemindex)]) 641 | except ValueError: 642 | centerprint('Please enter a valid choice') 643 | return False 644 | except IndexError: 645 | centerprint('Please enter a valid choice') 646 | return False 647 | self.ourhero.activeitem = self.ourhero.ouritem 648 | centerprint('Using ' + str(self.ourhero.ouritem.name)) 649 | if self.ourhero.ouritem.name == 'Healing Potion': 650 | self.healingpotion() 651 | if self.ourhero.ouritem.name == 'Explosive Mana Vial': 652 | if self.ourhero.isbattling: 653 | self.explosivemanavial() 654 | else: 655 | centerprint('You\'re not in battle!') 656 | return False 657 | if self.ourhero.ouritem.name == 'Health Regen Potion': 658 | self.healthregenpotion() 659 | if self.ourhero.ouritem.name == 'Haste Potion': 660 | self.hastepotion() 661 | if self.ourhero.ouritem.name == 'Weapon Repair Tincture': 662 | self.weaponrepairtincture() 663 | 664 | # hero uses a healing potion 665 | def healingpotion(self): 666 | marqueeprint('[HEALING POTION]') 667 | healed = self.ourhero.activeitem.effect 668 | self.ourhero.heal(healed) 669 | self.ourhero.activeitem = 0 670 | 671 | 672 | # hero uses an item that damages enemy 673 | def explosivemanavial(self): 674 | marqueeprint('[EXPLOSIVE MANA BOMB]') 675 | centerprint('The Mana Vial EXPLODES!') 676 | dmg = self.ourhero.activeitem.effect 677 | self.ourenemy.damage(dmg, self.ourhero.atkcurve) 678 | self.ourhero.activeitem = 0 679 | 680 | 681 | # adds health per turn 682 | def healthregenpotion(self): 683 | marqueeprint('[REGEN POTION]') 684 | self.ourhero.regentimer += 5 685 | centerprint(str(self.ourhero.regentimer) + ' turns health regen') 686 | self.ourhero.activeitem = 0 687 | 688 | # dodge buff 689 | def hastepotion(self): 690 | marqueeprint('[HASTE POTION]') 691 | self.ourhero.hastetimer += 5 692 | centerprint(str(self.ourhero.hastetimer) + ' turns dodge buff') 693 | self.ourhero.activeitem = 0 694 | 695 | # heals 60% of dur points to weapon 696 | def weaponrepairtincture(self): 697 | marqueeprint('[WEAPON REPAIR]') 698 | rep = self.ourhero.ourweapon.maxdur * .6 699 | centerprint('You repaired your weapon for ' + str(rep) + ' durability points') 700 | self.ourhero.ourweapon.dur += rep 701 | if self.ourhero.ourweapon.dur > self.ourhero.ourweapon.maxdur: 702 | self.ourhero.ourweapon.dur = self.ourhero.ourweapon.maxdur 703 | self.ourhero.activeitem = 0 704 | 705 | # adds a little suspense to offset the monotony of text input 706 | def suspense(self): 707 | s = ' ' 708 | if self.suspensemode: 709 | time.sleep(.5) 710 | print(s) 711 | 712 | # Print hero and enemy justified on left and right 713 | def printadversaries(self, datawidth): 714 | self.textwidth = datawidth 715 | centerprint(lr_justify('[HERO]', '[ENEMY]', self.textwidth)) 716 | centerprint(lr_justify(self.ourhero.name, self.ourenemy.name, self.textwidth)) 717 | centerprint(lr_justify(str('lvl: ' + str(self.ourhero.level)), 718 | str('lvl: ' + str(self.ourenemy.level)),self.textwidth)) 719 | centerprint(lr_justify(str('HP: ' + str(self.ourhero.hp) + '/' + str(self.ourhero.maxhp)), 720 | str('HP: ' + str(self.ourenemy.hp) + '/' + str(self.ourenemy.maxhp)), self.textwidth)) 721 | centerprint(lr_justify(str('XP: ' + str(self.ourhero.xp) + '/' + str(self.ourhero.nextlevel)), 722 | str('XP drop: ' + str(self.ourenemy.xp)),self.textwidth)) 723 | 724 | # To be used on status screens 725 | def printmarqueehero(self, sometext): 726 | marqueeprint(sometext) 727 | print(lr_justify('[HERO]', '', self.textwidth)) 728 | print(lr_justify(self.ourhero.name, '', self.textwidth)) 729 | print(lr_justify(str('lvl: ' + str(self.ourhero.level)), '', self.textwidth)) 730 | print(lr_justify(str('HP: ' + str(self.ourhero.hp) + '/' + str(self.ourhero.maxhp)), '', self.textwidth)) 731 | print(lr_justify(str('XP: ' + str(self.ourhero.xp) + '/' + str(self.ourhero.nextlevel)), '', self.textwidth)) 732 | -------------------------------------------------------------------------------- /Hero.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | import Armor 4 | import Game 5 | import Item 6 | import Shield 7 | import Weapon 8 | import dbsetup 9 | from texttools import * 10 | 11 | 12 | class Hero: 13 | def __init__(self, heroclass, herolevel, herohp, heroatk, herodefn, heronextlevel, herododge): 14 | # name 15 | self.name = '' 16 | 17 | # instance vars 18 | self.ourclass = heroclass 19 | self.level = herolevel 20 | self.nextlevel = heronextlevel 21 | 22 | # HP 23 | self.maxhp = herohp 24 | self.hp = self.maxhp 25 | 26 | # Attack 27 | self.baseatk = heroatk 28 | self.atk = self.baseatk 29 | 30 | # Defense 31 | self.basedef = herodefn 32 | self.defn = self.basedef 33 | 34 | # Dodge 35 | self.basedodge = herododge 36 | self.dodge = self.basedodge 37 | 38 | # Luck 39 | self.baseluck = 0 40 | self.luck = self.baseluck 41 | 42 | # Crit 43 | self.basecrit = 5 44 | self.crit = self.basecrit 45 | 46 | # game-created vars 47 | self.gold = 0 48 | self.xp = 0 49 | 50 | # Augmentations for hero classes 51 | self.hpaug = 0 52 | self.dodgeaug = 0 53 | self.defaug = 0 54 | self.atkaug = 0 55 | self.levelupaug = 0 56 | self.critaug = 0 57 | 58 | # Items container and usage 59 | self.items = [] 60 | self.activeitem = 0 61 | 62 | # Gear container 63 | self.gear = [] 64 | 65 | # Keep track of battle count 66 | self.battlecount = 0 67 | 68 | # Used for regen and haste potions 69 | self.regentimer = 0 70 | self.hastetimer = 0 71 | 72 | # A difficulty curve for determining lots of things 73 | self.atkcurve = 0 74 | self.defcurve = 0 75 | 76 | # equip objects 77 | self.ourweapon = Weapon.Weapon(0, 'training', 'wooden', 'stick', 3, 20, 'none') 78 | self.ourarmor = Armor.Armor(0, 'training', 'broken', 'plate', 2, 10) 79 | self.ourshield = Shield.Shield(0, 'training', 'wooden', 'ward', 3, 20) 80 | self.ouritem = Item.Item(0, 0, 0, 0, 0) 81 | self.isbattling = False 82 | 83 | # width of centered data in screencenter 84 | self.datawidth = 40 85 | 86 | # Heals user up to max health 87 | def heal(self, hpup): 88 | centerprint('You heal for ' + str(int(hpup)) + ' HP') 89 | print('') 90 | self.hp += hpup 91 | if self.hp > self.maxhp: 92 | self.hp = self.maxhp 93 | 94 | # flip a coin, pay 100g, 1/2 chance of regaining health 95 | def healflip(self): 96 | marqueeprint('[HEAL FLIP]') 97 | centerprint('Death appears to flip a coin with you.') 98 | if self.gold >= 100: 99 | self.gold -= 100 100 | newrand = random.randrange(0, 1) 101 | if newrand == 0: 102 | self.heal(self.maxhp) 103 | marqueeprint('[HEAL SUCCESS]') 104 | centerprint(str(self.maxhp) + ' healed') 105 | else: 106 | marqueeprint('HEAL FAILED You lost the roll!') 107 | else: 108 | marqueeprint('[HEAL FAILED]') 109 | centerprint('You don\'t have enough money!') 110 | 111 | # sometimes you find food after a fight 112 | def food(self): 113 | hpback = int(self.maxhp * .2) 114 | centerprint('You found some food and healed ' + str(hpback) + ' HP.') 115 | self.heal(hpback) 116 | 117 | # take damage 118 | def damage(self, hpdown): 119 | effatk = hpdown + (hpdown * self.defcurve) 120 | self.hp -= int(effatk) 121 | centerprint(str(self.name) + ' takes ' + str(int(effatk)) + ' damage!') 122 | if self.hp < 0: 123 | self.hp = 0 124 | 125 | # kills the character 126 | def death(self): 127 | self.isbattling = False 128 | self.hp = 0 129 | marqueeprint('') 130 | marqueeprint('[GAME OVER]') 131 | marqueeprint('') 132 | print('') 133 | gridoutput(self.datadict()) 134 | 135 | # adds XP to character, and levels up if it goes over 136 | def addxp(self, gainedxp): 137 | gainedxp = gainedxp + (gainedxp * self.defcurve) 138 | centerprint('You gained ' + str(int(gainedxp)) + ' Exp') 139 | self.xp += int(gainedxp) 140 | if self.xp >= self.nextlevel: 141 | self.levelup() 142 | 143 | # adds gold to character 144 | def addgold(self, gainedgold): 145 | gainedgold = gainedgold + (gainedgold * self.defcurve) 146 | centerprint('You gained ' + str(int(gainedgold + (gainedgold * self.defcurve))) + ' Gold') 147 | self.gold += int(gainedgold + (gainedgold * self.defcurve)) 148 | 149 | # attempt to buy an item 150 | def buyitem(self, item): 151 | if self.canafford(item.val): 152 | self.gold -= item.val 153 | self.items.append(item) 154 | print('You bought ' + item.name) 155 | else: 156 | print('You can\'t afford that!') 157 | 158 | # see if you can afford an item 159 | def canafford(self, val): 160 | if self.gold >= val: 161 | return True 162 | else: 163 | return False 164 | 165 | # alive check 166 | def isalive(self): 167 | if self.hp > 0: 168 | return True 169 | else: 170 | return False 171 | 172 | # applies hero's perks 173 | def heroperks(self): 174 | if self.ourclass == 'warrior': 175 | # more HP 176 | self.hpaug = 15 177 | # slower 178 | self.dodgeaug = 2 179 | # more def 180 | self.defaug = 12 181 | # low atk 182 | self.atkaug = 2 183 | # doofus is a slow leveler 184 | self.levelupaug = 1 185 | # mild crit chance boost 186 | self.critaug = 2 187 | elif self.ourclass == 'mage': 188 | # glass cannon 189 | self.hpaug = 5 190 | # med dodge 191 | self.dodgeaug = 5 192 | # low DEF 193 | self.defaug = 6 194 | # lower atk 195 | self.atkaug = 12 196 | # smarter, levels up quicker 197 | self.levelupaug = .6 198 | # mild crit chance boost 199 | self.critaug = 2 200 | elif self.ourclass == 'hunter': 201 | # med health 202 | self.hpaug = 10 203 | # high dodge 204 | self.dodgeaug = 8 205 | # med DEF 206 | self.defaug = 8 207 | # def ATK 208 | self.atkaug = 6 209 | # he gets by 210 | self.levelupaug = .8 211 | # high crit chance boost 212 | self.critaug = 6 213 | self.maxhp += self.hpaug 214 | self.hp += self.hpaug 215 | self.dodge += self.dodgeaug 216 | self.basedef += self.defaug 217 | self.defn += self.defaug 218 | self.nextlevel = int(self.nextlevel * self.levelupaug) 219 | self.baseatk += self.atkaug 220 | self.atk += self.atkaug 221 | 222 | # prints all hero stat info 223 | def printheroinfodetail(self): 224 | marqueeprint('[HERO DATA]') 225 | centerprint(Game.lr_justify('Class:', str(self.ourclass), self.datawidth)) 226 | centerprint(Game.lr_justify('Name:', str(self.name), self.datawidth)) 227 | centerprint(Game.lr_justify('Level:', str(self.level), self.datawidth)) 228 | centerprint(Game.lr_justify('XP:', str(self.xp) + '/' + str(self.nextlevel), self.datawidth)) 229 | centerprint(Game.lr_justify('HP:', str(self.hp) + '/' + str(self.maxhp), self.datawidth)) 230 | centerprint(Game.lr_justify('Gold:', str(self.gold), self.datawidth)) 231 | centerprint(Game.lr_justify('Atk:', str(self.atk), self.datawidth)) 232 | centerprint(Game.lr_justify('Defense:', str(self.defn), self.datawidth)) 233 | centerprint(Game.lr_justify('Dodge:', str(self.dodge), self.datawidth)) 234 | centerprint(Game.lr_justify('battles fought', str(self.battlecount), self.datawidth)) 235 | print('') 236 | 237 | # returns a dictionary of relevant user data for printing and delivering class information in a package 238 | def datadict(self): 239 | return { 240 | 'Class': str(self.ourclass), 241 | 'Name': str(self.name), 242 | 'Level': str(self.level), 243 | 'XP': str(str(self.xp) + '/' + str(self.nextlevel)), 244 | 'HP': str(str(self.hp) + '/' + str(self.maxhp)), 245 | 'Gold': str(self.gold), 246 | 'Atk': str(self.atk), 247 | 'Def': str(self.defn), 248 | 'Dodge': str(self.dodge), 249 | 'battles': str(self.battlecount) 250 | } 251 | 252 | # levels up hero 253 | def levelup(self): 254 | newdb = dbsetup.dbsetup() 255 | marqueeprint('[LEVEL UP]') 256 | self.xp -= self.nextlevel 257 | self.level += 1 258 | if self.level > 15: 259 | centerprint('MAX LEVEL! YOU WIN!') 260 | centerprint('THANKS FOR PLAYING') 261 | gridoutput(self.datadict()) 262 | quit() 263 | newdb.conn.execute('SELECT * FROM levelnotes WHERE level = ' + str(self.level) + ';') 264 | rows = newdb.conn.fetchall() 265 | newdb.conn.close() 266 | new_hero_data = rows[0] 267 | self.maxhp = int(new_hero_data[1] + self.hpaug) 268 | self.hp = self.maxhp 269 | self.baseatk = int(new_hero_data[2] + self.atkaug) 270 | self.atk = self.baseatk 271 | self.basedef = int(new_hero_data[3] + self.defaug) 272 | self.defn = self.basedef 273 | self.nextlevel += int(new_hero_data[4] * self.levelupaug) 274 | self.dodge = int(new_hero_data[5] + self.dodgeaug) 275 | self.basecrit += self.critaug 276 | gridoutput(self.datadict()) 277 | 278 | # fetches a new weapon for hero 279 | def newweapon(self): 280 | newdb = dbsetup.dbsetup() 281 | newdb.conn.execute('SELECT * FROM weapons WHERE "level" = ? AND "class" = ? ;', 282 | (str(self.level), str(self.ourclass),)) 283 | rows = newdb.conn.fetchall() 284 | newdb.conn.close() 285 | new_weapon_data = rows[0] 286 | ournewweapon = Weapon.Weapon(new_weapon_data[0], new_weapon_data[1], new_weapon_data[2], new_weapon_data[3], 287 | new_weapon_data[4], new_weapon_data[5], new_weapon_data[6]) 288 | return ournewweapon 289 | 290 | # fetches a new armor for hero 291 | def newarmor(self): 292 | newdb = dbsetup.dbsetup() 293 | newdb.conn.execute('SELECT * FROM armor WHERE "level" = ? AND "class" = ? ;', 294 | (str(self.level), str(self.ourclass),)) 295 | rows = newdb.conn.fetchall() 296 | newdb.conn.close() 297 | new_armor_data = rows[0] 298 | ournewarmor = Armor.Armor(new_armor_data[0], new_armor_data[1], new_armor_data[2], new_armor_data[3], 299 | new_armor_data[4], new_armor_data[5]) 300 | return ournewarmor 301 | 302 | # fetches a new shield for hero 303 | def newshield(self): 304 | newdb = dbsetup.dbsetup() 305 | newdb.conn.execute('SELECT * FROM shields WHERE "level" = ? AND "class" = ? ;', 306 | (str(self.level), str(self.ourclass),)) 307 | rows = newdb.conn.fetchall() 308 | newdb.conn.close() 309 | new_shield_data = rows[0] 310 | ournewshield = Shield.Shield(new_shield_data[0], new_shield_data[1], new_shield_data[2], new_shield_data[3], 311 | new_shield_data[4], new_shield_data[5]) 312 | return ournewshield 313 | 314 | # fetches a new item for hero 315 | def newitem(self): 316 | newdb = dbsetup.dbsetup() 317 | newdb.conn.execute('SELECT * FROM items WHERE "level" = ? ;', (self.level,)) 318 | rows = newdb.conn.fetchall() 319 | newdb.conn.close() 320 | new_item_data = random.choice(rows) 321 | ournewitem = Item.Item(new_item_data[0], new_item_data[1], new_item_data[2], new_item_data[3], new_item_data[4]) 322 | return ournewitem 323 | 324 | # re-equips all gear. Usually called when setting something like self.ourarmor = Armor.Armor(*args) 325 | def applyequip(self): 326 | self.atk = int(self.baseatk + self.ourweapon.baseatk) 327 | self.defn = int(self.basedef + self.ourarmor.defn + self.ourshield.defn) 328 | -------------------------------------------------------------------------------- /Item.py: -------------------------------------------------------------------------------- 1 | from texttools import * 2 | 3 | 4 | class Item: 5 | # grade,name,effect,value 6 | def __init__(self, itemlevel, itemgrade, itemname, itemeffect, itemvalue): 7 | self.level = itemlevel 8 | self.grade = itemgrade 9 | self.name = itemname 10 | self.effect = itemeffect 11 | self.val = itemvalue 12 | 13 | # prints all item stats 14 | def printiteminfo(self): 15 | marqueeprint('Item: ') 16 | print(lr_justify('Level:', str(self.level), 60)) 17 | print(lr_justify('Grade:', str(self.grade), 60)) 18 | print(lr_justify('Name:', str(self.name), 60)) 19 | print(lr_justify('Effect Val:', str(self.effect), 60)) 20 | print(lr_justify('Gold Val:', str(self.val), 60)) 21 | 22 | # ['Level', 'Quality', 'Name', 'Effect'] 23 | def datadict(self): 24 | return {'Level': str(self.level), 25 | 'Name': str(self.grade) + ' ' + str(self.name), 26 | 'Effect': str(self.effect), 27 | 'Value': str(self.val) 28 | } 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Colin Burke 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PyRPG_Mini 2 | 3 | A text RPG written in Python 3 with many technical RPG features you'd want. 4 | ## Requirements / Dependencies 5 | * Python3 6 | * sqlite3 7 | * textwrap 8 | * time 9 | * pickle 10 | * os 11 | * datetime 12 | * difflib 13 | * random 14 | * Read/write access to the project folder for database creation, reading, and saved games. 15 | 16 | ## Quick Preview 17 | 18 | ![](https://i.imgur.com/YTx0ZGj.gif) 19 | 20 | ## Game Features 21 | 22 | * OOP Python RPG with simple class names, convenient calls like *ourhero.heal()* and *ourhero.isalive()* 23 | * 15 levels of stats, weapons, items, and monsters 24 | * 3 hero classes, each with unique gear and base stats, which makes them all a unique experience. 25 | * Save / Load system for saving your character's progress 26 | * A customizable set of CSVs for modifying the game , and creating your own turn-based RPG. 27 | * A database population module which implements new changes and makes a new database. (Schema changes coming soon) 28 | * 5 buyable, findable, usable items with added status effects (damage, healing, regen, dodge, weapon repair) 29 | 30 | ## What you will experience 31 | * Randomized battle system ensuring a fun grinding and leveling experience. Later levels require more effort, gear, items. 32 | * 75 enemies with different HP, XP, Gold, Atk, Def 33 | * A miserable old traveler who gives unsolicited life advice 34 | * A Blacksmith who sells and repairs gear 35 | * Riddles which reward gold and EXP 36 | * A Store which sells items 37 | 38 | Check back soon for new features! 39 | 40 | # How to use 41 | 42 | 0. For your convenience, you can skip any prompt and default \[n]ew game, \[w]arrior, \[1] easy, \[a]dventure, \[a]ttack by simply pressing \[enter]. 43 | 44 | 1. Run \_\_init\_\_.py. If the database was deleted, it will reload the database from the CSVs in ./csv/ folder. 45 | 2. Press \[ENTER] to play regular game. Enter \[1] to go into debugging mode. 46 | 3. Select \[n]ew game 47 | 4. Choose your class: \[w]arrior \[m]age \[h]unter 48 | 5. Choose difficulty: \[1]easy \[2]med \[3]hard 49 | 6. Enter your character's name 50 | 7. \[a]dventure or \[c]amp 51 | 8. \[a]dventure will be a random choice of a battle, item, riddle, traveler. 52 | 9. \[c]amp will regerate your health, and offer features like: \[a]dventure, \[i]tem, \[h]ero, \[p]eddler, \[b]lacksmith, \[l]oad, \[s]ave, \[q]uit 53 | 10. Battle will give you several battle commands: \[a]tk, \[d]ef, \[r]un, \[i]tem, \[c]oinflip to \[h]eal (100g) 54 | 11. Upon finishing a battle, you are rewarded with gold and exp. 55 | 12. Have fun! 56 | 57 | # Saving / loading 58 | If loading game run game.py, and select \[l]oad when prompted. 59 | 60 | If saving, go to camp, select \[s]ave, and name the save file. (The script needs permissions to write to the directory!) 61 | 62 | # If you liked it: 63 | 64 | [Contribute](https://colinburke.com/contribute), so I can dedicate more time to projects like this. 65 | 66 | # About the Author 67 | 68 | https://linkedin.com/in/colingburke 69 | -------------------------------------------------------------------------------- /Shield.py: -------------------------------------------------------------------------------- 1 | import Game 2 | import random 3 | 4 | 5 | # TODO: Make shield, armor, weapon all have similar repair methods. 6 | class Shield: 7 | # level,class,name,type,basedef,durability 8 | def __init__(self, shieldlevel, shieldclass, shieldname, shieldtype, shieldbasedefn, shielddur): 9 | # shield level 10 | self.level = shieldlevel 11 | 12 | # shield hero class type 13 | self.ourshieldclass = shieldclass 14 | 15 | # shield name 16 | self.name = shieldname 17 | 18 | # shield type 19 | self.type = shieldtype 20 | 21 | # Shield Quality (rusty, common, great, magical, legendary) 22 | chance = random.randint(1, 100) 23 | 24 | if chance < 20: 25 | self.quality = 'Rusty' 26 | elif chance >= 21 or chance < 65: 27 | self.quality = 'Common' 28 | elif chance >= 66 or chance < 86: 29 | self.quality = 'Great' 30 | elif chance >= 85 or chance < 96: 31 | self.quality = 'Magical' 32 | elif chance >= 96 or chance < 100: 33 | self.quality = 'Legendary' 34 | 35 | # Defense Values 36 | self.basedefn = shieldbasedefn 37 | if self.quality == 'Rusty': 38 | self.basedefn = int(self.basedefn * 0.9) 39 | elif self.quality == 'Common': 40 | self.basedefn = int(self.basedefn * 1) 41 | elif self.quality == 'Great': 42 | self.basedefn = int(self.basedefn * 1.25) 43 | elif self.quality == 'Magical': 44 | self.basedefn = int(self.basedefn * 1.6) 45 | elif self.quality == 'Legendary': 46 | self.basedefn = int(self.basedefn * 2) 47 | 48 | self.defn = self.basedefn 49 | 50 | # shield durability value 51 | self.maxdur = shielddur 52 | if self.quality == 'Rusty': 53 | self.maxdur = int(self.maxdur * 0.9) 54 | elif self.quality == 'Common': 55 | self.maxdur = int(self.maxdur * 1) 56 | elif self.quality == 'Great': 57 | self.maxdur = int(self.maxdur * 1.25) 58 | elif self.quality == 'Magical': 59 | self.maxdur = int(self.maxdur * 1.6) 60 | elif self.quality == 'Legendary': 61 | self.maxdur = int(self.maxdur * 2) 62 | self.dur = self.maxdur 63 | 64 | # damage durability, and check to see if broken 65 | def damagedur(self, aug, curve): 66 | self.dur -= int(aug * curve) 67 | self.isbroken() 68 | pass 69 | 70 | # restore dur and check to see if fixed 71 | def restoredur(self, aug): 72 | self.dur += aug 73 | if self.dur > self.maxdur: 74 | self.dur = self.maxdur 75 | if not self.isbroken(): 76 | self.defn = self.basedefn 77 | 78 | # repair entirely 79 | def repair(self): 80 | self.defn = self.basedefn 81 | self.dur = self.maxdur 82 | 83 | # 15% durability = stat reduction 84 | def isbroken(self): 85 | if self.dur <= 0: 86 | self.gearbreak() 87 | return True 88 | elif self.dur > 0: 89 | return False 90 | 91 | # this breaks the gear 92 | def gearbreak(self): 93 | self.atk = int(self.basedefn * .3) 94 | 95 | # prints all info about the shield 96 | def printshieldinfo(self): 97 | Game.marqueeprint('SHIELD') 98 | print(Game.lr_justify('Level:', str(self.level), 60)) 99 | print(Game.lr_justify('Name:', str(self.name), 60)) 100 | print(Game.lr_justify('Type:', str(self.type), 60)) 101 | print(Game.lr_justify('Defense:', str(self.defn) + '/' + str(self.basedefn), 60)) 102 | print(Game.lr_justify('Dur:', str(self.dur) + '/' + str(self.maxdur), 60)) 103 | print(Game.lr_justify('Broken?:', str(self.isbroken()), 60)) 104 | print(Game.lr_justify('Quality:', str(self.quality), 60)) 105 | 106 | # ['Level', 'Name', 'Defense', 'Dur', 'Broken?', 'Power'] 107 | def datadict(self): 108 | return {'Level': str(self.level), 109 | 'Name': str(self.name) + ' ' + str(self.type), 110 | 'Def': str(self.defn), 111 | 'Dur': str(self.dur) + '/' + str(self.maxdur), 112 | 'Broken?': str(self.isbroken()), 113 | 'Repair Cost': str(self.maxdur - self.dur) + ' gold', 114 | 'Quality': str(self.quality) 115 | } 116 | -------------------------------------------------------------------------------- /Weapon.py: -------------------------------------------------------------------------------- 1 | from texttools import * 2 | import random 3 | 4 | 5 | class Weapon: 6 | # level,class,name,type,baseattack,durability,power 7 | def __init__(self, weaponlevel, weaponclass, weaponname, weapontype, weaponbaseatk, weapondur, weaponpower): 8 | # Weapon level 9 | self.level = weaponlevel 10 | 11 | # Weapon hero class type 12 | self.ourclass = weaponclass 13 | 14 | # Weapon type 15 | self.type = weapontype 16 | 17 | # Weapon Name 18 | self.name = weaponname 19 | 20 | # Weapon Quality (rusty, common, great, magical, legendary) 21 | chance = random.randint(1, 100) 22 | 23 | if chance < 20: 24 | self.quality = 'Rusty' 25 | elif chance >= 21 or chance < 65: 26 | self.quality = 'Common' 27 | elif chance >= 66 or chance < 86: 28 | self.quality = 'Great' 29 | elif chance >= 85 or chance < 96: 30 | self.quality = 'Magical' 31 | elif chance >= 96 or chance < 100: 32 | self.quality = 'Legendary' 33 | 34 | # Weapon atk 35 | self.baseatk = weaponbaseatk 36 | if self.quality == 'Rusty': 37 | self.baseatk = int(self.baseatk * 0.9) 38 | elif self.quality == 'Common': 39 | self.baseatk = int(self.baseatk * 1) 40 | elif self.quality == 'Great': 41 | self.baseatk = int(self.baseatk * 1.25) 42 | elif self.quality == 'Magical': 43 | self.baseatk = int(self.baseatk * 1.6) 44 | elif self.quality == 'Legendary': 45 | self.baseatk = int(self.baseatk * 2) 46 | 47 | self.atk = self.baseatk 48 | 49 | # Weapon durability 50 | self.maxdur = weapondur 51 | self.dur = self.maxdur 52 | 53 | # Weapon Power (Not implemented yet) 54 | self.power = weaponpower 55 | 56 | # damage durability, and check to see if broken 57 | def damagedur(self, aug, curve): 58 | self.dur -= int(aug * curve * .1) 59 | self.isbroken() 60 | pass 61 | 62 | # restore dur by integer and check to see if fixed 63 | def restoredur(self, aug): 64 | self.dur += aug 65 | if not self.isbroken(): 66 | self.dur = self.maxdur 67 | self.atk = self.baseatk 68 | 69 | # restore dur entirely 70 | def repair(self): 71 | self.atk = self.baseatk 72 | self.dur = self.maxdur 73 | 74 | # this breaks the gear 75 | def gearbreak(self): 76 | self.atk = int(self.baseatk * .3) 77 | 78 | # 15% durability = stat reduction 79 | def isbroken(self): 80 | if self.dur <= 0: 81 | self.gearbreak() 82 | return True 83 | elif self.dur >= self.maxdur * .15: 84 | return False 85 | 86 | # prints all weapon stats 87 | def printweaponinfo(self): 88 | marqueeprint('WEAPON') 89 | print(lr_justify('Level:', str(self.level), 70)) 90 | print(lr_justify('Class:', str(self.ourclass), 70)) 91 | print(lr_justify('Name:', str(self.name), 70)) 92 | print(lr_justify('Type:', str(self.type), 70)) 93 | print(lr_justify('Atk:', str(self.atk) + '/' + str(self.baseatk), 70)) 94 | print(lr_justify('Dur:', str(self.dur) + '/' + str(self.maxdur), 70)) 95 | print(lr_justify('Broken?:', str(self.isbroken()), 70)) 96 | print(lr_justify('Power:', str(self.power), 70)) 97 | print(lr_justify('Quality:', str(self.quality), 70)) 98 | 99 | # ['Level', 'Name', 'Type', 'Atk', 'Dur', 'Broken?', 'Power'] 100 | def datadict(self): 101 | return {'Level': str(self.level), 102 | 'Name': (str(self.name) + ' ' + str(self.type)), 103 | 'Atk': str(self.atk), 104 | 'Dur': (str(self.dur) + '/' + str(self.maxdur)), 105 | 'Broken?': str(self.isbroken()), 106 | 'Repair Cost': str(self.maxdur - self.dur) + ' gold', 107 | 'Power': str(self.power), 108 | 'Quality': str(self.quality) 109 | } 110 | -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- 1 | import Game 2 | 3 | if __name__ == '__main__': 4 | ourgame = Game.Game() 5 | ourgame.gameloop() 6 | -------------------------------------------------------------------------------- /csv/armor.csv: -------------------------------------------------------------------------------- 1 | level,classtype,name,type,basedef,durability 2 | 1,warrior,weak,plate,4,30 3 | 1,mage,weak,robe,2,15 4 | 1,hunter,weak,outfit,3,20 5 | 2,warrior,Novice,plate,7,36 6 | 2,mage,Novice,robe,6,18 7 | 2,hunter,Novice,outfit,6,24 8 | 3,warrior,Old,plate,10,43 9 | 3,mage,Old,robe,8,22 10 | 3,hunter,Old,outfit,9,29 11 | 4,warrior,Leather,plate,14,52 12 | 4,mage,Leather,robe,11,26 13 | 4,hunter,Leather,outfit,12,35 14 | 5,warrior,melancholy,plate,17,62 15 | 5,mage,melancholy,robe,14,31 16 | 5,hunter,melancholy,outfit,15,41 17 | 6,warrior,banded,plate,21,75 18 | 6,mage,banded,robe,17,37 19 | 6,hunter,banded,outfit,18,50 20 | 7,warrior,large,plate,24,90 21 | 7,mage,large,robe,20,45 22 | 7,hunter,large,outfit,21,60 23 | 8,warrior,Gilded,plate,28,107 24 | 8,mage,Gilded,robe,22,54 25 | 8,hunter,Gilded,outfit,24,72 26 | 9,warrior,enchanted,plate,31,129 27 | 9,mage,enchanted,robe,25,64 28 | 9,hunter,enchanted,outfit,27,86 29 | 10,warrior,reinforced,plate,34,155 30 | 10,mage,reinforced,robe,28,77 31 | 10,hunter,reinforced,outfit,30,103 32 | 11,warrior,moaning,plate,38,186 33 | 11,mage,moaning,robe,31,93 34 | 11,hunter,moaning,outfit,33,124 35 | 12,warrior,blessed,plate,41,223 36 | 12,mage,blessed,robe,34,111 37 | 12,hunter,blessed,outfit,36,149 38 | 13,warrior,talking,plate,45,267 39 | 13,mage,talking,robe,37,134 40 | 13,hunter,talking,outfit,39,178 41 | 14,warrior,glowing,plate,48,321 42 | 14,mage,glowing,robe,39,160 43 | 14,hunter,glowing,outfit,42,214 44 | 15,warrior,epic,plate,52,385 45 | 15,mage,epic,robe,42,193 46 | 15,hunter,epic,outfit,46,257 47 | -------------------------------------------------------------------------------- /csv/enemies.csv: -------------------------------------------------------------------------------- 1 | level,firstname,middlename,lastname,attack,xp,gold,hp,def,status 2 | 1,Timid,Corny,Duck,8,2,1,11,3,run 3 | 1,Timid,Clammy,Robot,10,3,1,11,5,run 4 | 1,Timid,Salty,Mystic,11,4,2,13,6,run 5 | 1,Timid,Coffee,Codger,12,6,3,13,7,run 6 | 1,Timid,Naked,Swindler,14,7,3,17,8,run 7 | 2,Docile,YUUUGE,Politician,15,4,4,19,10,poison 8 | 2,Docile,Cocksure,Talking Head,17,6,5,27,11,bleeding 9 | 2,Docile,Crying,Simpleton,14,7,5,29,12,none 10 | 2,Docile,Oily,Sports Fan,17,8,6,32,13,none 11 | 2,Docile,Roided,Rockman,17,9,7,34,15,none 12 | 3,Bothered,Milky,Broseidon,21,10,7,37,16,poison 13 | 3,Bothered,Corny,Duck,24,12,8,40,17,bleeding 14 | 3,Bothered,Clammy,Robot,27,13,8,42,18,none 15 | 3,Bothered,Salty,Mystic,31,14,9,45,20,none 16 | 3,Bothered,Coffee,Codger,28,15,10,47,21,none 17 | 4,Dastardly,Naked,Swindler,29,16,10,50,22,poison 18 | 4,Dastardly,YUUUGE,Politician,30,18,11,53,23,bleeding 19 | 4,Dastardly,Cocksure,Talking Head,32,19,12,55,24,none 20 | 4,Dastardly,Crying,Simpleton,33,20,12,58,26,none 21 | 4,Dastardly,Oily,Sports Fan,35,21,13,61,27,none 22 | 5,Larger-than-average,Roided,Rockman,36,23,14,63,28,poison 23 | 5,Larger-than-average,Milky,Broseidon,37,24,14,66,29,bleeding 24 | 5,Larger-than-average,Corny,Duck,39,25,15,68,31,none 25 | 5,Larger-than-average,Clammy,Robot,40,26,15,71,32,none 26 | 5,Larger-than-average,Salty,Mystic,41,27,16,74,33,none 27 | 6,Aggressive,Coffee,Codger,43,29,17,76,34,poison 28 | 6,Aggressive,Naked,Swindler,44,30,17,79,36,bleeding 29 | 6,Aggressive,YUUUGE,Politician,45,31,18,81,37,none 30 | 6,Aggressive,Cocksure,Talking Head,47,32,19,84,38,none 31 | 6,Aggressive,Crying,Simpleton,48,33,19,87,39,none 32 | 7,Cunning,Oily,Sports Fan,50,35,20,89,41,poison 33 | 7,Cunning,Roided,Rockman,51,36,21,92,42,bleeding 34 | 7,Cunning,Milky,Broseidon,52,37,21,94,43,none 35 | 7,Cunning,Corny,Duck,54,50,22,97,44,none 36 | 7,Cunning,Clammy,Robot,55,52,22,100,45,none 37 | 8,Fearsome,Salty,Mystic,56,53,23,102,47,poison 38 | 8,Fearsome,Coffee,Codger,58,54,24,105,48,bleeding 39 | 8,Fearsome,Naked,Swindler,59,43,24,108,49,none 40 | 8,Fearsome,YUUUGE,Politician,61,44,25,110,50,none 41 | 8,Fearsome,Cocksure,Talking Head,62,46,26,113,52,none 42 | 9,Intimidating,Crying,Simpleton,63,47,26,115,53,poison 43 | 9,Intimidating,Oily,Sports Fan,65,48,27,118,54,bleeding 44 | 9,Intimidating,Roided,Rockman,66,49,28,121,55,none 45 | 9,Intimidating,Milky,Broseidon,67,50,28,123,57,none 46 | 9,Intimidating,Corny,Duck,69,52,29,126,58,none 47 | 10,Godlike,Clammy,Robot,70,53,29,128,59,poison 48 | 10,Godlike,Salty,Mystic,71,61,30,131,60,bleeding 49 | 10,Godlike,Coffee,Codger,73,63,31,134,62,none 50 | 10,Godlike,Naked,Swindler,74,64,31,136,63,none 51 | 10,Godlike,YUUUGE,Politician,76,65,32,139,64,none 52 | 11,Ascended,Cocksure,Talking Head,77,59,33,141,65,poison 53 | 11,Ascended,Crying,Simpleton,78,60,33,144,67,bleeding 54 | 11,Ascended,Oily,Sports Fan,80,61,34,147,68,none 55 | 11,Ascended,Roided,Rockman,81,63,35,149,69,none 56 | 11,Ascended,Milky,Broseidon,82,64,35,152,70,none 57 | 12,Ethereal,Corny,Duck,84,65,36,155,71,poison 58 | 12,Ethereal,Clammy,Robot,85,66,36,157,73,bleeding 59 | 12,Ethereal,Salty,Mystic,86,67,37,160,74,none 60 | 12,Ethereal,Coffee,Codger,88,69,38,162,75,none 61 | 12,Ethereal,Naked,Swindler,89,70,38,165,76,none 62 | 13,Vile-Hardened,YUUUGE,Politician,109,71,39,168,78,poison 63 | 13,Vile-Hardened,Cocksure,Talking Head,110,72,40,170,79,bleeding 64 | 13,Vile-Hardened,Crying,Simpleton,112,73,40,173,80,none 65 | 13,Vile-Hardened,Oily,Sports Fan,114,82,41,175,81,none 66 | 13,Vile-Hardened,Roided,Rockman,115,83,41,178,83,none 67 | 14,Vile-Aggressive,Milky,Broseidon,117,84,42,181,84,poison 68 | 14,Vile-Aggressive,Corny,Duck,118,86,43,183,85,bleeding 69 | 14,Vile-Aggressive,Clammy,Robot,120,80,43,186,86,none 70 | 14,Vile-Aggressive,Salty,Mystic,122,81,44,189,88,none 71 | 14,Vile-Aggressive,Coffee,Codger,123,82,45,191,89,none 72 | 15,Vile-Superior,Naked,Swindler,125,83,45,194,90,poison 73 | 15,Vile-Superior,YUUUGE,Politician,127,84,46,196,91,bleeding 74 | 15,Vile-Superior,Cocksure,Talking Head,128,86,47,387,92,none 75 | 15,Vile-Superior,Crying,Simpleton,130,87,47,397,94,none 76 | 15,Vile-Superior,Oily,TRUMP,132,88,48,428,95,none 77 | -------------------------------------------------------------------------------- /csv/items.csv: -------------------------------------------------------------------------------- 1 | level,grade,name,effect,value 2 | 1,minor,Healing Potion,40,8 3 | 1,minor,Explosive Mana Vial,39,7 4 | 2,minor,Health Regen Potion,10,30 5 | 2,minor,Haste Potion,20,36 6 | 3,minor,Weapon Repair Tincture,10,50 7 | 3,weak,Healing Potion,80,16 8 | 3,weak,Explosive Mana Vial,93,18 9 | 4,weak,Health Regen Potion,17,51 10 | 4,weak,Haste Potion,30,54 11 | 5,weak,Weapon Repair Tincture,15,75 12 | 5,Standard,Healing Potion,200,40 13 | 6,Standard,Explosive Mana Vial,138,27 14 | 6,Standard,Health Regen Potion,30,90 15 | 6,Standard,Haste Potion,40,72 16 | 7,Standard,Weapon Repair Tincture,20,100 17 | 7,Above-average,Healing Potion,400,80 18 | 8,Above-average,Explosive Mana Vial,205,41 19 | 8,Above-average,Health Regen Potion,53,159 20 | 8,Above-average,Haste Potion,50,90 21 | 9,Above-average,Weapon Repair Tincture,25,125 22 | 9,Satisfying,Healing Potion,700,140 23 | 10,Satisfying,Explosive Mana Vial,510,102 24 | 10,Satisfying,Health Regen Potion,94,282 25 | 11,Satisfying,Haste Potion,60,108 26 | 11,Satisfying,Weapon Repair Tincture,30,150 27 | 11,Excessive,Healing Potion,1200,240 28 | 12,Excessive,Explosive Mana Vial,1269,253 29 | 12,Excessive,Health Regen Potion,168,504 30 | 13,Excessive,Haste Potion,70,126 31 | 14,Excessive,Weapon Repair Tincture,40,200 32 | 15,100% Pure,Healing Potion,3000,600 33 | 15,100% Pure,Explosive Mana Vial,4428,885 34 | 15,100% Pure,Health Regen Potion,300,900 35 | 15,100% Pure,Haste Potion,80,144 36 | 15,100% Pure,Weapon Repair Tincture,50,250 37 | -------------------------------------------------------------------------------- /csv/levelnotes.csv: -------------------------------------------------------------------------------- 1 | Level,HP,ATK,DEF,xptonextlevel,dodge 2 | 1,20,7,3,11,0 3 | 2,32,13,6,30,1 4 | 3,54,20,9,98,1 5 | 4,71,27,13,212,2 6 | 5,92,33,16,429,2 7 | 6,120,40,19,674,2 8 | 7,155,47,22,967,3 9 | 8,202,53,25,1345,3 10 | 9,263,60,28,1666,4 11 | 10,341,67,31,2002,4 12 | 11,444,73,34,2337,4 13 | 12,577,80,38,2673,5 14 | 13,750,87,41,3008,5 15 | 14,975,93,44,3344,6 16 | 15,1267,100,50,3679,6 17 | -------------------------------------------------------------------------------- /csv/riddles.csv: -------------------------------------------------------------------------------- 1 | QUESTIONS,ANSWERS 2 | "With thieves I consort, With the Vilest, in short, I'm quite at ease in depravity, Yet all divines use me, And savants can't lose me, For I am the century of gravity.",V 3 | "I move without wings, Between silken string, I leave as you find, My substance behind.",Spider 4 | "What flies forever, Rests never?",Wind 5 | "I appear in the morning. But am always there. You can never see me. Though I am everywhere. By night I am gone, though I sometimes never was. Nothing can defeat me. But I am easily gone.",Sunlight 6 | "I crawl on the earth. And rise on a pillar.",Shadow 7 | "They are many and one, they wave and they drum, Used to cover a state, they go with you everywhere.",Hands 8 | "What must be in the oven yet can not be baked? Grows in the heat yet shuns the light of day? What sinks in water but rises with air? Looks like skin but is fine as hair?",Yeast 9 | "I have holes on the top and bottom. I have holes on my left and on my right. And I have holes in the middle, Yet I still hold water.",Sponge 10 | "What can be swallowed, But can also swallow you?",Pride 11 | "You get many of me, but never enough. After the last one, your life soon will snuff. You may have one of me but one day a year, When the last one is gone, your life disappears.",Birthday 12 | "I run around the city, but I never move.",Wall 13 | "As a whole, I am both safe and secure. Behead me, I become a place of meeting. Behead me again, I am the partner of ready. Restore me, I become the domain of beasts.",Stable 14 | "Two horses, swiftest traveling, harnessed in a pair, and grazing ever in places. Distant from them.",Eyes 15 | "At the sound of me, men may dream. Or stamp their feet. At the sound of me, women may laugh. Or sometimes weep.",Music 16 | "To unravel me you need a simple key, no key that was made by locksmith's hand. But a key that only I will understand.",Riddle 17 | "Long and think, red within, with a nail at the end.",Finger 18 | "I'm sometimes white and always wrong. I can break a heart and hurt the strong. I can build love or tear it down. I can make a smile or bring a frown.",Lie 19 | "You can tumble in it, roll in it, burn it, animal eat it. Used to cover floors, still used beyond stall doors. Freshens whatever it is placed on. Absorbs whatever is poured into it.",Hay 20 | "I come in winter. I cannot see, hear, or feel. I can't eat, But you can eat parts of me.",Snowman 21 | "Sometimes I am loud. And viewed with distaste. Poke out my 'eye', then I'm on the front of your face.",Noise 22 | "What is it that has four legs, one head, and a foot?",Bed 23 | "What makes a loud noise when changing its jacket. Becomes larger but weighs less?",Popcorn 24 | "I am always hungry, I must always be fed. The finger I lick will soon turn red.",Fire 25 | "Something wholly unreal, yet seems real to I. Think my friend, tell me where does it lie?",Mind 26 | "No matter how little or how much you use me, you change me every month.",Calendar 27 | "What can burn the eyes, sting the mouth, yet be consumed?",Salt 28 | "What an fill a room but takes up no space?",Light 29 | "It occurs once in every minute. Twice in every moment and yet never in one hundred thousand years.",M 30 | "With pointed fangs it sits in wait. With piercing force it doles out fate, over bloodless victims proclaiming its might. Eternally joining in a single bite.",Stapler 31 | "It holds most knowledge that has ever been said. But is not the brain, is not the head. To feathers and their masters, it's both bane and boon…One empty, and one full.",Paper 32 | "Upon me you can tread, though softly under cover. And I will take you places, that you have yet to discover. I'm high, and I'm low, though flat in the middle. And though a joy to the children, adults think of me little.",Stairs 33 | "A mile from end to end, yet as close to as a friend. A precious commodity, freely given. Seen on the dead and on the living. Found on the rich, poor, short and tall. But shared among children most of all.",Smile 34 | "I have a hundred legs, but cannot stand. I have a long neck, but no head. I cannot see. I'm neat and tidy as can be.",Broom 35 | "Flat as a leaf, round as a ring. Has two eyes, can't see a thing.",Button 36 | "I don't think or eat or slumber. Or move around or fear thunder. Just like you I look the same but I can't harm you or be your bane.",Doll 37 | "In marble halls as white as milk, lined with a skin as soft as silk. Within a fountain crystal-clear. A golden apple doth appear. No doors there are to this stronghold, yet thieves break in and steal the gold.",Egg 38 | "What is it that you must give before you can keep it.",Word 39 | "I dig out tiny caves and store gold and silver in them. I also build bridges of silver and make crowns of gold. They are the smallest you could imagine. Sooner or later everybody needs my help. Yet many people are afraid to let me help them.",Dentist 40 | "What is long and slim, works in light. Has but one eye, and an awful bite?",Needle 41 | "What lies in a tunnel of darkness. That can only attack when pulled back?",Bullet 42 | "What has six faces and twenty-one eyes?",Die 43 | "Until I am measured. I am not known, yet how you miss me when I have flown.",Time 44 | "Three lives have I. Gentle enough to soothe the skin. Light enough to caress the sky. Hard enough to crack rocks.",Water 45 | "I wear a red robe, with staff in hand, and a stone in my throat.",Cherry 46 | "A warrior amongst the flowers, he bears a thrusting sword. He uses it whenever he must, to defend his golden hoard.",Bee 47 | "I hide but my head is outside.",Nail 48 | "A house full, a yard full, a chimney full, no one can get a spoonful.",Smoke 49 | "You can spin, wheel and twist. But this thing can turn without moving.",Milk 50 | "Halo of water, tongue of wood. Skin of stone, long I've stood. My fingers short reach to the sky. Inside my heart men live and die.",Castle 51 | "When they are caught, they are thrown away. When they escape, you itch all day.",Fleas 52 | "What does man love more than life, fear more than death or mortal strife. What the poor have, the rich require, and what contented men desire. What the miser spends, and the spendthrift saves. And all men carry to their graves.",Nothing 53 | "In we go, out we go. All around and in a row. Always, always steady flow. When we'll stop, you'll never known. In we go, out we go.",Tides 54 | "A cloud was my mother, the wind is my father. My son is the cool stream, and my daughter is the fruit of the land. A rainbow is my bed, the earth my final resting place. And I'm the torment of man.",Rain 55 | "Born of earth, but with none of its strength. Molded by flame, but with none of its power. Shaped",Glass 56 | "Remove the outside. Cook the inside. Eat the outside. Throw away the inside.",Corn 57 | "This is in a realm of true and in a realm false, but you experience me as you turn and toss.",Dream 58 | "There is an ancient invention. Still used in some parts of the world today. That allows people to see through walls.",Window 59 | "Some live in me, some live on. And some shave me to stride upon. I rarely leave my native land. Until my death I always stand. High and low I may be found. Both above and below ground.",Tree 60 | "Metal or bone I may be, many teeth I have and always bared. Yet my bite harms no one. And ladies delight in my touch.",Comb 61 | "I am a fire's best friend. When fat, my body fills with wind. When pushed to thin, through my nose I blow. Then you can watch the embers glow.",Bellows 62 | "Every dawn begins with me. At dusk I'll be the first you see, and daybreak couldn't come without. What midday centers all about. Daises grow from me, I'm told. And when I come, I end all code, but in the sun I won't be found. Yet still, each day I'll be around.",D 63 | "You heart it speak, for it has a hard tongue. But it cannot breathe, for it has not a lung.",Bell 64 | "I cut through evil like a double edged sword, and chaos flees at my approach. Balance I single-handedly upraise, through battles fought with heart and mind, instead of with my gaze.",Justice 65 | "The eight of us move forth and back. To protect our king from the foes attack.",Pawns 66 | "He has one and a person has two. A citizen has three. And a human being has four. A personality has five. And an inhabitant of earth has six.",Syllable 67 | "If you break me, I do not stop working. If you touch me, I may be snared. If you lose me, nothing will matter.",Heart 68 | "What's in the middle of nowhere?",H 69 | "What force and strength cannot get through. I, with a gentle touch, can do. Many in the street would stand. Were I not a friend at hand.",Key 70 | "Often held but never touched. Always wet but never rusts. Often bits but seldom bit. To use it well you must have wit.",Tongue 71 | "As round as an apple. As deep as a cup. All the king's horses can't pull it up.",Well 72 | "He stands beside the road. In a purple cap at tattered green cloak. Those who touch him, curse him.",Thistle 73 | "Power enough to smash ships and crush roofs. Yet it still must fear the sun.",Ice 74 | "What surrounds the world, yet dwells within a thimble?",Space 75 | "I cannot be other than what I am, until the man who made me dies. Power and glory will fall to me finally. Only when he last closes his eyes.",Prince 76 | "What is it that makes tears without sorrow. And takes its journey to heaven?",Smoke 77 | "Inside a great blue castle lives a shy young maid. She blushes in the morning and comes not out at night.",Sun 78 | "This thing runs but cannot walk, sometimes sings but never talks. Lacks arms, has hands; lacks a head but has a face.",Clock 79 | "A word I know, six letters it contains. Subtract just one and twelve remains.",Dozens 80 | "I go in hard and dry. I come out soft and sticky. You can blow me.",Gum 81 | "I am the yellow hem of the sea's blue skirt.",Beach 82 | "A skin have I, more eyes than one. I can be very nice when I am done.",Potato 83 | "I have four legs but no tail. Usually I am heard only at night.",Frog 84 | "A tiny bead, like fragile glass, strung along a cord of grass.",Dew 85 | "Break it and it is better, immediately set and harder to break again.",Record 86 | "Each morning I appear to lie at your feet, all day I follow no matter how fast you run. Yet I nearly perish in the midday sun.",Shadow 87 | "What do you throw out to use and take in when you're done?",Anchor 88 | "What is it which builds things up? Lays mountains low? Dries up lakes, and makes things grow? Cares not a whim about your passing? And is like few other things, because it is everlasting?",Time 89 | "I am the fountain from which no one can drink. For many I am considered a necessary link. Like gold to all I am sought for, but my continued death brings wealth for all to want more.",Oil 90 | "Sleeping during the day, I hide away. Watchful through the night, I open at dawn's light. But only for the briefest time, do I shine. And then I hide away. And sleep through the day.",Sunrise 91 | "A seed am I, three letters make my name. Take away two and I still sound the same.",Pea 92 | "In the middle of night, I surround the gong. In the middle of sight, I end the song.",G 93 | "Look into my face and I'm everybody. Scratch my back and I'm nobody.",Mirror 94 | "Two brothers we are, great burdens we bear. All day we are bitterly pressed. Yet this I will say, we are full all the day, and empty when go to rest.",Boots 95 | "They can be harbored, but few hold water. You can nurse them, but only by holding them against someone else. You can carry them, but not with your arms. You can bury them, but not in the earth.",Grudge 96 | "What is it that was given to you, belongs only to you. And yet your friends use it more than you do?",Name 97 | "By Moon or by Sun, I shall be found. Yet I am undone, if there's no light around.",Shadow 98 | "What do you use to hoe a row, slay a foe, and wring with woe?",Hands 99 | "We travel much, yet prisoners are, and close confined to boot. Yet with any horse, we will keep the pace, and will always go on foot.",Spurs 100 | "Without a bridle, or a saddle, across a thing I ride a-straddle. And those I ride, by help of me, though almost blind, are made to see.",Glasses 101 | "I fly through the air on small feathered wings, seeking out life and destroying all things.",Arrow 102 | "I am the red tongue of the earth, that buries cities.",Lava 103 | "I look at you, you look at me, I raise my right, you raise your left.",Mirror 104 | "What is the thing which, once poured out, cannot be gathered again?",Rain 105 | "It is a part of us, and then replaced. It escapes out bodies, to a better place. The world becomes its sizeable home. Its passions unrestraint, the planet it roams.",Water 106 | "What word starts with 'E', ends with 'E', but only has one letter? It is not the letter 'E'.",Envelope 107 | "A hole in a pole, though I fill a hole in white. I'm used more by the day, and less by the night.",Eye 108 | "I fly, yet I have no wings. I cry, yet I have no eyes. Darkness follows me. Lower light I never see.",Cloud 109 | "I'm full of holes, yet I'm full of water.",Sponge 110 | "Long and slinky like a trout, never sings till it's guts come out.",Gun 111 | "What animal keeps the best time?",Watchdog 112 | "What kind of room has no windows or doors?",Mushroom 113 | "I have legs but walk not, a strong back but work not. Two good arms but reach not. A seat but sit and tarry not.",Chair 114 | "It's in your hand though you can not feel it. Only you and time can reveal it.",Fate 115 | "Not born, but from a Mother's body drawn. I hang until half of me is gone. I sleep in a cave until I grow old. Then valued for my hardened gold.",Cheese 116 | "I am the outstretched fingers that seize and hold the wind. Wisdom flows from me in other hands. Upon me are sweet dreams dreamt, my merest touch brings laughter.",Feather 117 | "Hands she has but does not hold. Teeth she has but does not bite. Feet she has but they are cold. Eyes she has but without sight.",Doll 118 | "Only two backbones and thousands of ribs.",Railroad 119 | "Hard iron on horse. Cow's hide on man.",Shoe 120 | "What word is the same written forward, backward and upside down?",Noon 121 | "I cannot be felt, seen or touched. Yet I can be found in everybody. My existence is always in debate. Yet I have my own style of music.",Soul 122 | "I am seen in the water. If seen in the sky, I am in the rainbow, a jay's feather, and lapis lazuli.",Blue 123 | "You use it between your head and your toes, the more it works the thinner it grows.",Soap 124 | "Fatherless and motherless. Born without sin, roared when it came into the world. And never spoke again.",Thunder 125 | "Where can you find roads without cars, forests without trees and cities without houses?",Map 126 | "A leathery snake, with a stinging bite. I'll stay coiled up, unless I must fight.",Whip 127 | "Take one out and scratch my head, I am now black but once was red.",Match 128 | "Mountains will crumble and temples will fall. And no man can survive its endless call.",Time 129 | "What has wings, but can not fly. Is enclosed, but can outside also lie. Can open itself up, or close itself away. Is the place of kings and queens and doggerel of every means. What is it upon which I stand? Which can lead us to different lands.",Stage 130 | "I'm the source of all emotion, but I'm caged in a white prison.",Heart 131 | "I am the tool, for inspiring many. Buy me in the store, for not much more than a penny. Don't overuse me, or my usefulness will go.",Pen 132 | "What goes through a door but never goes in. And never comes out?",Keyhole 133 | "What goes up when the rain comes down?",Umbrella 134 | "I occur twice in eternity. And I'm always within sight.",T 135 | "Twigs and spheres and poles and plates. Join and bind to reason make.",Skeleton 136 | "The sun bakes them, the hand breaks them, the foot treads on them, and the mouth tastes them.",Grapes 137 | "I have many feathers to help me fly. I have a body and head, but I'm not alive. It is your strength which determines how far I go. You can hold me in your hand, but I'm never thrown.",Arrow 138 | "What's black when you get it, red when you use it, and white when you're all through with it?",Charcoal 139 | "What has four legs in the morning, two legs in the afternoon, and three legs in the evening?",Man 140 | "Take off my skin, I won't cry, but you will.",Onion 141 | "Hold the tail, while I fish for you.",Net 142 | "I am so simple that I can only point. Yet I guide men all over the world.",Compass 143 | "Iron roof, glass walls, burns and burns and never falls.",Lantern 144 | "Late afternoons I often bathe. I'll soak in water piping hot. My essence goes through. My see through clothes. Used up am I - I've gone to pot.",Teabag 145 | "What can't you see, hear or feel, until its too late. What shadows love, and shopkeepers hate?",Thief 146 | "What can bring back the dead. Make us cry, make us laugh, make us young. Born in an instant yet lasts a life time?",Memory 147 | "I have a neck but no head. I have a body but no arm. I have a bottom but no leg.",Bottle 148 | "A thousand colored folds stretch toward the sky. Atop a tender strand, rising from the land, until killed by maiden's hand. Perhaps a token of love, perhaps to say goodbye.",Flower 149 | "Gold in a leather bag, swinging on a tree, money after honey in its time. Ills of a scurvy crew cured by the sea, reason in its season but no rhyme.",Orange 150 | "A slow, solemn square-dance of warriors feinting. One by one they fall, warriors fainting, thirty-two on sixty-four.",Chess 151 | "He has married many women but has never married.",Priest 152 | "In your fire you hear me scream, creaking and whining, yet I am dead before you lay me in your hearth.",Log 153 | "I weaken all men for hours each day. I show you strange visions while you are away. I take you by night, by day take you back. None suffer to have me, but do from my lack.",Sleep 154 | "I saw a strange creature. Long, hard, and straight, thrusting into a round, dark opening. Preparing to discharge its load of lives. Puffing and squealing noises accompanied it, then a final screech as it slowed and stopped.",Train 155 | "Large as a mountain, small as a pea, endlessly swimming in a waterless sea.",Asteroid 156 | "I do not breathe, but I run and jump. I do not eat, but I swim and stretch. I do not drink, but I sleep and stand. I do not think, but I grow and play. I do not see, but you see me everyday.",Leg 157 | "When liquid splashes me, none seeps through. When I am moved a lot, liquid I spew. When I am hit, color I change. And color, I come in quite a range. What I cover is very complex, and I am very easy to flex.",Skin 158 | "Give it food and it will live, give it water and it will die.",Fire 159 | "A nut cracker up in a tree.",Squirrel 160 | "What happens every second, minute, month, and century. But not every hour, week, year, or decade?",N 161 | "It has no top or bottom, but it can hold flesh, bones, and blood all at the same time.",Ring 162 | "I am free for the taking. Through all of your life, though given but once at birth. I am less than nothing in weight, but will fell the strongest of you if held.",Breath 163 | "My first is in blood and also in battle. My second is in acorn, oak, and apple. My third and fourth are both the same. In the center of sorrow and twice in refrain. My fifth starts eternity ending here. My last is the first of last, Oh Dear.",Barrel 164 | "When I'm metal or wood, I help you get home. When I'm flesh and I'm blood. In the darkness I roam.",Bat 165 | "I march before armies, a thousand salute me. My fall can bring victory, but no one would shoot me. The wind is my lover, one-legged am I. Name me and see me at home in the sky.",Flag 166 | "Tool of thief, toy of queen. Always used to be unseen. Sign of joy, sign of sorrow. Giving all likeness borrowed.",Mask 167 | "What five-letter word becomes shorter when you add two more letters?",Short 168 | "What is pronounced like one letter, written with three letters. And belongs to all animals?",Eye 169 | "What is it that given one, you'll have either two or none?",Choice 170 | "It is greater than God and more evil than the devil. The poor have it, the rich need it, and if you eat it you'll die.",Nothing 171 | "What gets bigger the more you take away from it?",Hole 172 | "The more of it there is, the less you see.",Darkness 173 | "To cross the water I'm the way, for water I'm above. I touch it not and, truth to say, I neither swim nor move.",Bridge 174 | "As beautiful as the setting sun, as delicate as the morning dew. An angel's dusting from the stars. That can turn the Earth into a frosted moon.",Snow 175 | "When set loose I fly away. Never so cursed as when I go astray.",Fart 176 | "How far will a blind dog walk into a forest?",Halfway 177 | "My first is in wield, sever bones and marrow. My second is in blade, forged in cold steel. My third is an arbalest, and also in arrows. My fourth is in power, plunged through a shield. My fifth is in honor, and also in vows. My last will put an end to it all.",Weapon 178 | "Face with a tree, skin like the sea. A great beast I am. Yet vermin frightens me.",Elephant 179 | "I sleep by day, I fly by night. I have no feathers to aid my flight.",Bat 180 | "I am mother and father, but never birth or nurse. I'm rarely still, but I never wander.",Tree 181 | "What goes in the water red, and comes out black?",Iron 182 | "Grows from the ground, bushes and grass, leaves of yellow, red and brow, unruly plants, get the axe, trim the hedge back down.",Hair 183 | "What can touch someone once and last them a life time?",Love 184 | "A dragons tooth in a mortals hand, I kill, I maim, I divide the land.",Sword 185 | "You will find me with four legs, but no hair. People ride me for hours, but I don't go anywhere without needing to be tugged. Jerked or turned on, I always manage to be ready for work.",Desk 186 | "No sooner spoken than broken.",Silence 187 | "Though desert men once called me God, today men call me mad. For I wag my tail when I am angry. And growl when I am glad.",Cat 188 | "An open ended barrel, it is shaped like a hive. It is filled with the flesh, and the flesh is alive.",Thimble 189 | "What kind of pet always stays on the floor?",Carpet 190 | "What flies without wings? What passes all things? What mends all sorrow? What brings the morrow?",Time 191 | "What has a neck and no head, two arms but no hands?",Shirt 192 | "Two in a corner, one in a room, none in a house, but one in a shelter.",R 193 | "What does no man want, yet no man want to lose?",Work 194 | "I am the heart that does not beat. If cut, I bleed without blood. I can fly, but have no wings. I can float, but have no fins. I can sing, but have no mouth.",Wood 195 | "Weight in my belly, trees on my back, nails in my ribs, feet I do lack.",Boat 196 | "What is that over the head and under the hat?",Hair 197 | "I bind it and it walks. I loose it and it stops.",Sandal 198 | "My voice is tender, my waist is slender and I'm often invited to play. Yet wherever I go, I must take my bow or else I have nothing to say.",Violin 199 | "Lovely and round, I shine with pale light, grown in the darkness, a lady's delight.",Pearl 200 | "The strangest creature you'll ever find has two eyes in front and a hundred behind.",Peacock 201 | "A little pool with two layers of wall around it. One white and soft and the other dark and hard. Amidst a light brown grassy lawn with an outline of a green grass.",Coconut 202 | "I open wide and tight I shut, Sharp am I and paper-cut fingers too, so do take care, I'm good and bad, so best beware.",Scissors 203 | "Only one color, but not one size. Stuck at the bottom, yet easily flies. Present in sun, but not in rain. Doing no harm, and feeling no pain.",Shadow 204 | "A house of wood in a hidden place. Built without nails or glue. High above the earthen ground. It holds pale gems of blue.",Nest 205 | "Who spends the day at the window, goes to the table for meals. And hides at night?",Fly 206 | "The beginning of eternity, the end of time and space, the beginning of every end, the end of every place.",E 207 | "Always old, sometimes new. Never sad, sometimes blue. Never empty, sometimes full. Never pushes, always pulls.",Moon 208 | "I bubble and laugh and spit water in your face. I am no lady, and I don't wear lace.",Fountain 209 | "My teeth are sharp, my back is straight, to cut things up it is my fate.",Saw 210 | "I love to dance and twist and prance. I shake my tail, as away I sail. Wingless I fly into the sky.",Kite 211 | "I usually wear a yellow coat. I usually have a dark head. I make marks wherever I go.",Pencil 212 | "My life is often a volume of grief, your help is needed to turn a new leaf. Stiff is my spine and my body is pale. But I'm always ready to tell a tale.",Book 213 | "I cost no money to use, or conscious effort to take part of. And as far as you can see, there is nothing to me. But without me, you are dead.",Air 214 | "Soldiers line up spaced with pride. Two long rows lined side by side. One sole unit can decide, if the rows will unit or divide.",Zipper 215 | "What measures out time. Until in time all is smashed to it?",Sand 216 | "I turn around once. What is out will not get in. I turn around again. What is in will not get out.",Key 217 | "Who is he that runs without a leg. And his house on his back?",Snail 218 | "When the day after tomorrow is yesterday. Today will be as far from Wednesday. As today was from Wednesday. When the day before yesterday was tomorrow. What is the day after this day?",Thursday 219 | "What has roots as nobody sees, is taller than trees. Up, up it goes, and yet never grows?",Mountain 220 | "Come up and let us go. Go down and here we stay.",Anchor 221 | "They have not flesh, nor feathers, nor scales, nor bone. Yet they have fingers and thumbs of their own.",Gloves 222 | "Long slim and slender. Dark as homemade thunder. Keen eyes and peaked nose. Scares the Devil wherever it goes.",Snake 223 | "What is put on a table, cut, but never eaten?",Deck 224 | "The sharp slim blade, that cuts the wind.",Grass 225 | "Although my cow is dead, I still beat her… What a racket she makes.",Drum 226 | "It sat upon a willow tree, and sang softly unto me. Easing my pain and sorrow with its song. I wished to fly, but tarried long. And in my suffering, the willow was like a cool clear spring. What was it that helped me so? To spend my time in my woe.",Bird 227 | "I have four wings but cannot fly. I never laugh and never cry. On the same spot always found, toiling away with little sound.",Windmill 228 | "I am never quite what I appear to be. Straight-forward I seem, but it's only skin deep. For mystery most often lies beneath my simple speech. Sharpen your wits, open your eyes, look beyond my exteriors, read me backwards, forwards, upside down. Think and answer the question...What am I?",Riddle 229 | "All about the house, with his lady he dances, yet he always works, and never romances.",Broom 230 | "I walked and walked and at last I got it. I didn't want it. So I stopped and looked for it. When I found it, I threw it away.",Thorn 231 | "Two in a whole and four in a pair. And six in a trio you see. And eight's a quartet but what you must get. Is the name that fits just one of me?",Half 232 | "I drive men mad for love of me. Easily beaten, never free.",Gold 233 | "I go around in circles, but always straight ahead. Never complain, no matter where I am led.",Wheel 234 | "You use a knife to slice my head. And weep beside me when I am dead.",Onion 235 | "Turns us on our backs, and open up our stomachs. You will be the wisest of men though at start a lummox.",Books 236 | "Thousands lay up gold within this house. But no man made it. Spears past counting guard this house, but no man wards it.",Beehive 237 | "What goes around the world and stays in a corner?",Stamp 238 | "What has to be broken before it can be used?",Egg 239 | "Creatures of power, creatures of grade, creatures of beauty, creatures of strength. As for their lives, they set everything's pace. For all things must come to live. Under their emerald embrace…Either in their life or in their death.",Trees 240 | "Double my number, I'm less than a score. Half of my number is less than four. Add one to my double when bakers are near. Days of the week are still greater, I fear.",Six 241 | "In buckles or lace, they help set the pace. The farther you go, the thinner they grow.",Shoes 242 | "When young, I am sweet in the sun. When middle-aged, I make you gay. When old, I am valued more than ever.",Wine 243 | "Forward I'm heavy, but backwards I'm not.",Ton 244 | "Hard to catch, easy to hold. Can't be seen, unless it's cold.",Breath 245 | "I am two-faced but bear only one. I have no legs but travel widely. Men spill much blood over me. Kings leave their imprint on me. I have greatest power when given away, yet lust for me keeps me locked away.",Coin 246 | "Two little holes in the side of a hill. Just as you come to the cherry-red mill.",Nose 247 | "When you stop and look, you can always see me. If you try to touch, you cannot feel me. I cannot move, but as you near me, I will move away from you.",Horizon 248 | "A dagger thrust at my own heart, dictates the way I'm swayed. Left I stand, and right I yield, to the twisting of the blade.",Lock 249 | "What instrument can make any sound and be heart, but not touched or seen?",Voice 250 | "What goes further the slower it goes?",Money 251 | "I can run but not walk. Wherever I go, thought follows close behind.",Nose 252 | "Used left or right, I get to travel over cobblestone or gravel. Used up, I vie for sweet success, used down, I cause men great duress.",Thumb 253 | "What goes through the door without pinching itself? What sits on the stove without burning itself? What sits on the table and is not ashamed?",Sun 254 | "The moon is my father. The sea is my mother. I have a million brothers. I die when I reach land.",Wave 255 | "What always goes to bed with his shoes on?",Horse 256 | "My thunder comes before the lightning. My lightning comes before the clouds. My rain dries all the land it touches.",Volcano 257 | "My love, when I gaze on thy beautiful face. Careering along, yet always in place, the thought has often come into my mind. If I ever shall see thy glorious behind.",Moon 258 | "What starts with a 'T', ends with a 'T', and has T in it?",Teapot 259 | "Today he is there to trip you up. And he will torture you tomorrow. Yet he is also there to ease the pain, when you are lost in grief and sorrow.",Alcohol 260 | "I can be moved. I can be rolled. But nothing will I hold. I'm red and I'm blue, and I can be other colors too. Having no head, though similar in shape. I have no eyes - yet move all over the place.",Ball 261 | "Inside a burning house, this thing is best to make. And best to make it quickly, before the fire's too much to take.",Haste 262 | "What is round as a dishpan, deep as a tub, and still the oceans couldn't fill it up?",Sieve 263 | "My first is in some but not in all. My second is into but not in tall. My third in little but no in big. My fourth in port but not in pig. My whole is made in nature's way. For clothing, rugs used every day.",Silk 264 | "Gets rid of bad ones, short and tall. Tightens when used, one size fits all.",Noose 265 | "What gets wetter the more it dries.",Towel 266 | "A little house full of meat, no door to go in and eat.",Nut 267 | "A beggar's brother went out to sea and drowned. But the man who drowned had no brother. Who was the beggar to the man who drowned?",Sister 268 | "I can be written, I can be spoken, I can be exposed, I can be broken.",News 269 | "A horrid monster hides from the day, with many legs and many eyes. With silver chains it catches prey. And eats it all before it dies. Yet in every cottage does it stay. And every castle beneath the sky.",Spider 270 | "Five hundred begins it, five hundred ends it. Five in the middle is seen. First of all figures, the first of all letters. Take up their stations between. Join all together, and then you will bring before you the name of an eminent king.",David 271 | "Tall in the morning, short at noon, gone at night. But I'll be back soon.",Shadow 272 | "In the night a mountain, in the morning a meadow.",Bed 273 | "What can be heard and caught but never seen?",Remark 274 | "I can sizzle like bacon, I am made with an egg. I have plenty of backbone, but lack a good leg. I peel layers like onions, but still remain whole. I can be long, like a flagpole, yet fit in a hole.",Snake 275 | "If a man carried my burden, he would break his back. I am not rich, but leave silver in my track.",Snail 276 | "High born, my touch is gentle. Purest white is my lace. Silence is my kingdom. Green is the color of my death.",Snow 277 | "You heard me before, yet you hear me again, then I die. Until you call me again.",Echo 278 | "What wears a coat in the winter and pants in the summer?",Dog 279 | "I'm not really more than holes tied to more holes. I'm strong as good steel, though not as stiff as a pole.",Chain 280 | "I am the third from a sparkle bright, I thrive throughout the day and night. Deep in the path of a cows white drink. I've had thousands of millions of years to think. But one of my creatures is killing me. And so the question I ask to thee, is who am I?",Earth 281 | "Up on high I wave away but not a word can I say.",Flag 282 | "I am whole but incomplete. I have no eyes, yet I see. You can see, and see right through me. My largest part is one fourth of what I once was.",Skeleton 283 | "They're up near the sky, on something very tall. Sometimes they die, only then do they fall.",Leaves 284 | "Toss me out of the window. You'll find a grieving wife. Pull me back but through the door, and watch someone give life.",N 285 | "A time when they're green. A time when they're brown. But both of these times, cause me to frown. But just in between, for a very short while. They're perfect and yellow. And cause me to smile.",Bananas 286 | "I build up castles. I tear down mountains. I make some men blind. I help others to see.",Sand 287 | "Round as a button, deep as a well. If you want me to talk, you must first pull my tail.",Bell 288 | "A house with two occupants, sometimes one, rarely three. Break the walls, eat the boarders, then throw away me.",Peanut 289 | "My first master has four legs, my second master has two. My first I serve in life, my second I serve in death. Tough I am, yet soft beside. Against ladies cheeks I often reside.",Fur 290 | "I have one eye. See near and far. I hold the moments you treasure and the things that make you weep.",Camera 291 | "There are two meanings to me. With one I may need to be broken, with the other I hold on. My favorite characteristic is my charming dimple.",Tie 292 | "With sharp edged wit and pointed poise. It can settle disputes without making a noise.",Sword 293 | "Lighter than what I am made of, more of me is hidden than is seen. I am the bane of the mariner. A tooth within the sea.",Iceberg 294 | "I have one, you have one. If you remove the first letter, a bit remains. If you remove the second, bit still remains. If you remove the third, it still remains.",Habit 295 | "Kings and queens may cling to power. And the jester's got his call. But, as you may all discover. The common one outranks them all.",Ace 296 | "Glittering points that downward thrust. Sparkling spears that never rust.",Icicles 297 | "My first is in fish but no in snail. My second is in rabbit but no in tail. My third is in up but not in down. My fourth is in tiara but not in crown. My fifth is in tree you plainly see. My whole a food for you and me.",Fruit 298 | "What I am filled, I can point the way. When I am empty. Nothing moves me. I have two skins. One without and one within.",Gloves 299 | "My first is in window but not in pane. My second's in road but not in lane. My third is in oval but not in round. My fourth is in hearing but not in sound. My whole is known as a sign of peace. And from noah's ark won quick release.",Dove 300 | "If you drop me I'm sure to crack. But give me a smile and I'll always smile back.",Mirror 301 | "I make you weak at the worst of all times. I keep you safe, I keep you fine. I make your hands sweat. And your heart grow cold. I visit the weak, but seldom the bold.",Fear 302 | "I run through hills. I veer around mountains. I leap over rivers. And crawl through the forests. Step out your door to find me.",Road 303 | "You can see nothing else when you look in my face. I will look you in the eye and I will never lie.",Mirror 304 | "I have split the one into five. I am the circle that few will spy. I am the path that breaks and gives. I am the bow no man may bend.",Rainbow 305 | "A harvest sown and reaped on the same day in an unplowed field. Which increases without growing, remains whole though it is eaten within and without. Is useless and yet the staple of nations.",War 306 | "Snake coiled round and round. Snake deep below the ground. Snake that's never had a head. Snake that binds but not with dread.",Rope 307 | "My first is in ocean but never in sea. My second's in wasp but never in bee. My third is in glider and also in flight. My whole is a creature that comes out at night.",Owl 308 | "Dies half its life. Lives the rest. Dances without music. Breathes without breath.",Tree 309 | "What runs around all day. Then lies under the bed. With its tongue hanging out?",Shoe 310 | "It's true I bring serenity. And hang around the stars. But yet I live in misery, you'll find me behind bars. With thieves and villains I consort. In prison I'll be found. But I would never go to court. Unless there's more than one.",S 311 | "You must keep this thing. Its loss will affect your brothers. For once yours is lost, it will soon be lost by others.",Temper 312 | "What can you catch but not throw?",Cold 313 | "Black we are and much admired. Men seek us if they are tired. We tire the horse, comfort man. Guess this riddle if you can.",Coal 314 | "I have a face, yet no senses. But I don't really care, because time is of the essence.",Clock 315 | "If you have it, you want to share it. If you share it, you don't have it.",Secret 316 | "There is one in every corner and two in every room.",O 317 | "It comes only before, it comes only after. Rises only in darkness, but rises only in light. It is always the same, but is yet always different.",Moon 318 | "As soft as silk, as white as milk, as bitter as gall, a thick green wall, and a green coat covers me all.",Walnut 319 | "We are little airy creatures, all of different voice and features, one of us in glass is set. One of us you'll find in jet. Another you may see in tin. And the fourth a box within. If the fifth you should pursue, it can never fly from you.",Vowels 320 | "Three little letters. A paradox to some. The worse that it is, the better it becomes.",Pun 321 | "Almost everyone needs it, asks for it, gives it. But almost nobody takes it.",Advice 322 | "Different lights do make me strange, thus into different sizes I will change.",Pupil 323 | "Ten men's strength, ten men's length. Ten men can't break it, yet a young boy walks off with it.",Rope 324 | "Some try to hide, some try to cheat. But time will show, we always will meet. Try as you might, to guess my name. I promise you'll know, when you I do claim.",Death 325 | "I'm a god. I'm a planet. I measure heat.",Mercury 326 | "I'm white, I'm round, but not always around. Sometimes you see me, sometimes you don't.",Moon 327 | "People are hired to get rid of me. I'm often hiding under your bed. In time I'll always return you see. Bite me and you're surely dead.",Dust 328 | "Die without me, never thank me. Walk right through me, never feel me. Always watching, never speaking. Always lurking, never seen.",Air 329 | "White bird, featherless, flying out of paradise. Flying over sea and land. Dying in my hand.",Snow 330 | "My life can be measured in hours. I serve by being devoured. Thin, I am quick. Fat, I am slow. Wind is my foe.",Candle 331 | "What goes up but never comes down?",Age 332 | "We are all around, yet to us you are half blind. Sunlight makes us invisible, and difficult to find.",Stars 333 | "What's large on Saturday and Sunday. Small on Tuesday, Wednesday, and Thursday, and disappears on Monday and Friday?",S 334 | "What do you fill with empty hands?",Gloves 335 | "Goes over all the hills and hollows. Bites hard, but never swallows.",Frost 336 | "Stealthy as a shadow in the dead of night, cunning but affectionate if given a bite. Never owned but often loved. At my sport considered cruel, but that's because you never know me at all.",Cat 337 | "A red drum which sounds without being touched, and grows silent, when it is touched.",Heart 338 | "My second is performed by my first, and it is thought a thief by the marks of my whole might be caught.",Footstep 339 | "The man who made it didn't need it. The man who bought it didn't use it. The man who used it didn't want it.",Coffin 340 | "A hill full, a hole full, yet you cannot catch a bowl full.",Mist 341 | "I am a box that holds black and white keys without locks. Yet they can unlock your soul.",Piano 342 | "What is often returned, but never borrowed/",Thanks 343 | "A muttered rumble was heard from the pen, and I, in my walking stopped to look in. What was this I saw? A massive beast, hoofed, and jawed. With spikes upon its mighty brow, I watched as he struck the turf and prowled. And yet for all of his magnificence, he couldn't get out of that wooden fence.",Bull 344 | "What word has kst in the middle, in the beginning, and at the end?",Inkstand 345 | "So cold, damp and dark this place. To stay you would refrain, yet those who occupy this place do never complain.",Grave 346 | "What kind of nut is empty at the center and has no shell.",Doughnut 347 | "I have a title and many pages. I am a genteel of genteel descent. I am a killer veteran of war. I am a slave to my lord pledged to his service.",Knight 348 | "Of these things - I have two. One for me - and one for you. And when you ask about the price, I simply smile and nod twice.",Sharing 349 | "At night I come without being fetched. By day I am lost without being stolen.",Stars 350 | "Ripped from my mother's womb. Beaten and burned, I become a blood thirsty killer.",Iron 351 | "I'm very tempting, so its said, I have a shiny coat of red, and my flesh is white beneath. I smell so sweet, taste good to eat, and help to guard your teeth.",Apple 352 | "They made me a mouth, but didn't give me breath. Water gives me life, but the sun brings me death.",Snowman 353 | "I am as simple as a circle. Worthless as a leader, but when I follow a group. Their strength increases tenfold. By myself I am practically nothing. Neither negative or positive.",0 354 | "I saw a man in white, he looked quite a sight. He was not old, but he stood in the cold. And when he felt the sun, he started to run. Who could he be? Please answer me.",Snowman 355 | "We are five little objects of an everyday sort. You will find us all in a tennis court.",Vowels 356 | "What always runs but never walks, often murmurs, never talks. Has a bed but never sleeps, has a mouth but never eats?",River 357 | "I can be cracked, I can be made. I can be told, I can be played.",Joke 358 | "My children are near and far. No matter that I know where they are. The gift I give them make their day. But if I were gone they would wander away.",Sun 359 | "Screaming, soaring seeking sky. Flowers of fire flying high. Eastern art from ancient time. Name me now and solve this rhyme.",Firework 360 | "Who is it that rows quickly with four oars, but never comes out from under his own roof?",Turtle 361 | "Who works when he plays and plays when he works?",Musician 362 | "My first is twice in apple but not once in tart. My second is in liver but not in heart. My third is in giant and also in ghost. Whole I'm best when I am toast.",Pig 363 | "Reaching stiffly for the sky, I bare my fingers when its cold. In warmth I wear an emerald glove and in between I dress in gold.",Tree 364 | "A precious stone, as clear as diamond. Seek it out while the sun's near the horizon. Though you can walk on water with its power, try to keep it, and it'll vanish in an hour.",Ice 365 | "Half-way up the hill, I see you at last, lying beneath me with your sounds and sights. A city in the twilight, dim and vast, with smoking roofs, soft bells, and gleaming lights.",Past 366 | "I heard of a wonder, of words moth-eaten. That is a strange thing, I thought, weird. That a man's song be swallowed by a worm. His blinded sentences, his bedside stand-by rustled in the night - and the robber-guest. Not one wit the wiser. For the words he had mumbled.",Bookworm 367 | "What has a single eye but cannot see?",A needle 368 | "I'm light as a feather, yet the strongest man can't hold me for more than 5 minutes. What am I?",Breath. 369 | "What goes in the water black and comes out red?",A lobster. 370 | "What two things can you never eat for breakfast?",Lunch and dinner. 371 | "What is brown and sticky?",A stick. 372 | "What asks but never answers?",An owl 373 | "What loses its head in the morning and gets it back at night?",A pillow 374 | "What building has the most stories?",A library. 375 | "I occur once in a minute...",The letter 'm' 376 | "I pass before the sun, but make no shadow. What am I?",wind 377 | "Lighter than a feather, but a man cannot hold me for long...",breath 378 | "I have a hundred legs and cannot stand, a long neck but no head, and I eat the maid's life.",broom 379 | -------------------------------------------------------------------------------- /csv/shields.csv: -------------------------------------------------------------------------------- 1 | level,class,name,type,basedef,durability 2 | 1,warrior,weak,shield,3,30 3 | 1,mage,weak,ward,1,32 4 | 1,hunter,weak,buckler,2,35 5 | 2,warrior,Novice,shield,6,38 6 | 2,mage,Novice,ward,4,41 7 | 2,hunter,Novice,buckler,5,43 8 | 3,warrior,Old,shield,8,46 9 | 3,mage,Old,ward,7,49 10 | 3,hunter,Old,buckler,7,51 11 | 4,warrior,Leather,shield,11,54 12 | 4,mage,Leather,ward,9,57 13 | 4,hunter,Leather,buckler,10,59 14 | 5,warrior,melancholy,shield,14,62 15 | 5,mage,melancholy,ward,11,65 16 | 5,hunter,melancholy,buckler,12,68 17 | 6,warrior,banded,shield,17,70 18 | 6,mage,banded,ward,13,73 19 | 6,hunter,banded,buckler,15,76 20 | 7,warrior,large,shield,19,78 21 | 7,mage,large,ward,16,81 22 | 7,hunter,large,buckler,17,84 23 | 8,warrior,Gilded,shield,22,86 24 | 8,mage,Gilded,ward,18,89 25 | 8,hunter,Gilded,buckler,19,92 26 | 9,warrior,enchanted,shield,25,95 27 | 9,mage,enchanted,ward,20,97 28 | 9,hunter,enchanted,buckler,22,100 29 | 10,warrior,reinforced,shield,28,103 30 | 10,mage,reinforced,ward,22,105 31 | 10,hunter,reinforced,buckler,24,108 32 | 11,warrior,moaning,shield,30,111 33 | 11,mage,moaning,ward,25,113 34 | 11,hunter,moaning,buckler,27,116 35 | 12,warrior,blessed,shield,33,119 36 | 12,mage,blessed,ward,27,122 37 | 12,hunter,blessed,buckler,29,124 38 | 13,warrior,talking,shield,36,127 39 | 13,mage,talking,ward,29,130 40 | 13,hunter,talking,buckler,32,132 41 | 14,warrior,glowing,shield,39,135 42 | 14,mage,glowing,ward,31,138 43 | 14,hunter,glowing,buckler,34,140 44 | 15,warrior,epic,shield,41,143 45 | 15,mage,epic,ward,34,146 46 | 15,hunter,epic,buckler,36,149 47 | -------------------------------------------------------------------------------- /csv/weapons.csv: -------------------------------------------------------------------------------- 1 | level,class,name,type,baseattack,durability,power 2 | 1,warrior,novice,sword,8,40,none 3 | 1,mage,novice,staff,5,32,none 4 | 1,hunter,novice,bow,6,36,none 5 | 2,warrior,gatekeeper,sword,12,44,none 6 | 2,mage,gatekeeper,staff,8,35,none 7 | 2,hunter,gatekeeper,bow,9,40,none 8 | 3,warrior,wanderer,sword,19,49,none 9 | 3,mage,wanderer,staff,12,39,none 10 | 3,hunter,wanderer,bow,15,44,none 11 | 4,warrior,old,sword,24,54,none 12 | 4,mage,old,staff,16,43,none 13 | 4,hunter,old,bow,19,49,none 14 | 5,warrior,historic,sword,31,60,none 15 | 5,mage,historic,staff,26,48,none 16 | 5,hunter,historic,bow,27,54,none 17 | 6,warrior,ancient,sword,29,67,none 18 | 6,mage,ancient,staff,31,53,none 19 | 6,hunter,ancient,bow,32,60,none 20 | 7,warrior,glowing,sword,34,75,none 21 | 7,mage,glowing,staff,36,59,none 22 | 7,hunter,glowing,bow,37,67,none 23 | 8,warrior,talking,sword,39,84,none 24 | 8,mage,talking,staff,41,66,none 25 | 8,hunter,talking,bow,42,75,none 26 | 9,warrior,reckless,sword,44,94,none 27 | 9,mage,reckless,staff,46,73,none 28 | 9,hunter,reckless,bow,47,84,none 29 | 10,warrior,mysterious,sword,49,105,none 30 | 10,mage,mysterious,staff,51,81,none 31 | 10,hunter,mysterious,bow,52,94,none 32 | 11,warrior,gilded,sword,54,117,none 33 | 11,mage,gilded,staff,55,90,none 34 | 11,hunter,gilded,bow,57,105,none 35 | 9,warrior,poison,sword,59,94,poison 36 | 9,mage,poison,staff,60,73,poison 37 | 9,hunter,poison,bow,62,84,poison 38 | 10,warrior,fire,sword,64,105,fire 39 | 10,mage,fire,staff,65,81,fire 40 | 10,hunter,fire,bow,67,94,fire 41 | 11,warrior,haste,sword,69,117,haste 42 | 11,mage,haste,staff,70,90,haste 43 | 11,hunter,haste,bow,72,105,haste 44 | 12,warrior,defense,sword,74,131,none 45 | 12,mage,defense,staff,75,100,none 46 | 12,hunter,defense,bow,77,117,none 47 | 13,warrior,fancy,sword,79,146,none 48 | 13,mage,fancy,staff,80,112,none 49 | 13,hunter,fancy,bow,82,131,none 50 | 14,warrior,reinforced,sword,84,163,none 51 | 14,mage,reinforced,staff,85,125,none 52 | 14,hunter,reinforced,bow,87,146,none 53 | 15,warrior,epic,sword,89,182,none 54 | 15,mage,epic,staff,90,140,none 55 | 15,hunter,epic,bow,92,163,none 56 | -------------------------------------------------------------------------------- /db/game.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crawsome/PyRPG_Mini/a53a409bc2ef48ec72ef57bf0ee249d203c5e248/db/game.db -------------------------------------------------------------------------------- /dbsetup.py: -------------------------------------------------------------------------------- 1 | import csv 2 | import os 3 | from sqlite3 import connect 4 | 5 | import Game 6 | 7 | 8 | class dbsetup(): 9 | def __init__(self): 10 | self.dbpath = './db/game.db' 11 | # import and create our player database 12 | self.gamedb = connect(self.dbpath) 13 | self.conn = self.gamedb.cursor() 14 | 15 | # used to delete the current database 16 | def deletedbifexists(self): 17 | if os.path.exists('./db/game.db'): 18 | os.remove('./db/game.db') 19 | 20 | def setupdb(self): 21 | # If you set this to 1, it will print out all data as it populates the datbase. 22 | debugging = 0 23 | 24 | # make a database connection to the game database 25 | if debugging: 26 | print('connecting to database') 27 | conn = connect('./db/game.db') 28 | 29 | # create our cursor 30 | if debugging: 31 | print('creating cursor') 32 | cur = conn.cursor() 33 | 34 | # create our armor table in the database 35 | if debugging: 36 | print('creating table for armor') 37 | cur.execute( 38 | '''CREATE TABLE IF NOT EXISTS armor (level INTEGER, class TEXT, name TEXT, type TEXT, basedef INTEGER, durability INTEGER)''') 39 | 40 | # insert our armor table in the database 41 | if debugging: 42 | print('inserting armor into database') 43 | with open('./csv/armor.csv', 'r') as fin: 44 | dr = csv.reader(fin) 45 | for i in dr: 46 | if debugging: 47 | print('inserting ' + str(i)) 48 | cur.execute('INSERT INTO armor VALUES (?,?,?,?,?,?);', i) 49 | if debugging: 50 | cur.execute('SELECT * FROM armor') 51 | rows = cur.fetchall() 52 | for row in rows: 53 | print('QUERY ALL: ' + str(row)) 54 | 55 | # create our enemy table in the database 56 | if debugging: 57 | print('creating table for enemies') 58 | cur.execute( 59 | '''CREATE TABLE IF NOT EXISTS enemies(level INT, firstname TEXT, middlename TEXT, lastname TEXT, attack INTEGER, xp INTEGER, gold INTEGER, hp INTEGER, def INTEGER, status TEXT)''') 60 | 61 | # insert our enemy table in the database 62 | if debugging: 63 | print('inserting enemies into database') 64 | with open('./csv/enemies.csv', 'r') as fin: 65 | dr = csv.reader(fin) 66 | for i in dr: 67 | if debugging: 68 | print('inserting ' + str(i)) 69 | cur.execute('INSERT INTO enemies VALUES (?,?,?,?,?,?,?,?,?,?);', i) 70 | if debugging: 71 | cur.execute('SELECT * FROM enemies') 72 | rows = cur.fetchall() 73 | for row in rows: 74 | print('QUERY ALL: ' + str(row)) 75 | 76 | # create our items table in the database 77 | if debugging: 78 | print('creating table for items') 79 | cur.execute( 80 | '''CREATE TABLE IF NOT EXISTS items(level INT, grade INT,name TEXT,effect INT,value INT)''') 81 | 82 | # insert our items table in the database 83 | if debugging: 84 | print('inserting items into database') 85 | with open('./csv/items.csv', 'r') as fin: 86 | dr = csv.reader(fin) 87 | for i in dr: 88 | if debugging: 89 | print('inserting ' + str(i)) 90 | cur.execute('INSERT INTO items VALUES (?,?,?,?,?);', i) 91 | if debugging: 92 | cur.execute('SELECT * FROM items') 93 | rows = cur.fetchall() 94 | for row in rows: 95 | print('QUERY ALL: ' + str(row)) 96 | 97 | # create our levelnotes table in the database 98 | if debugging: 99 | print('creating table for levelnotes') 100 | cur.execute( 101 | '''CREATE TABLE IF NOT EXISTS levelnotes(Level INT,HP INT,ATK INT,DEF INT,xptonextlevel INT, dodge INT )''') 102 | 103 | # insert our levelnotes table in the database 104 | if debugging: 105 | print('inserting levelnotes into database') 106 | with open('./csv/levelnotes.csv', 'r') as fin: 107 | dr = csv.reader(fin) 108 | for i in dr: 109 | if debugging: 110 | print('inserting ' + str(i)) 111 | cur.execute('INSERT INTO levelnotes VALUES (?,?,?,?,?,?);', i) 112 | if debugging: 113 | cur.execute('SELECT * FROM levelnotes') 114 | rows = cur.fetchall() 115 | for row in rows: 116 | print('QUERY ALL: ' + str(row)) 117 | 118 | # create our shields table in the database 119 | if debugging: 120 | print('creating table for shields') 121 | cur.execute( 122 | '''CREATE TABLE IF NOT EXISTS shields (level INT,class TEXT,name TEXT,type TEXT,basedef INT,durability INT)''') 123 | 124 | # insert our shields table in the database 125 | if debugging: 126 | print('inserting shields into database') 127 | with open('./csv/shields.csv', 'r') as fin: 128 | dr = csv.reader(fin) 129 | for i in dr: 130 | if debugging: 131 | print('inserting ' + str(i)) 132 | cur.execute('INSERT INTO shields VALUES (?,?,?,?,?,?);', i) 133 | if debugging: 134 | cur.execute('SELECT * FROM shields') 135 | rows = cur.fetchall() 136 | for row in rows: 137 | print('QUERY ALL: ' + str(row)) 138 | 139 | # create our weapons table in the database 140 | if debugging: 141 | print('creating table for weapons') 142 | cur.execute( 143 | '''CREATE TABLE IF NOT EXISTS weapons ( level INTEGER ,class TEXT ,name TEXT ,type TEXT,baseattack INTEGER ,durability INTEGER ,power TEXT)''') 144 | 145 | # insert our weapons table in the database 146 | if debugging: 147 | print('inserting weapons into database') 148 | with open('./csv/weapons.csv', 'r') as fin: 149 | dr = csv.reader(fin) 150 | for i in dr: 151 | if debugging: 152 | print('inserting ' + str(i)) 153 | cur.execute('INSERT INTO weapons VALUES (?,?,?,?,?,?,?);', i) 154 | if debugging: 155 | cur.execute('SELECT * FROM weapons') 156 | rows = cur.fetchall() 157 | for row in rows: 158 | print('QUERY ALL: ' + str(row)) 159 | 160 | # create our riddles table in the database 161 | if debugging: 162 | print('creating table for riddles') 163 | cur.execute( 164 | '''CREATE TABLE IF NOT EXISTS riddles (question TEXT ,answer TEXT)''') 165 | 166 | # insert our riddles table in the database 167 | if debugging: 168 | print('inserting riddles into database') 169 | with open('./csv/riddles.csv', 'r') as fin: 170 | dr = csv.reader(fin) 171 | for i in dr: 172 | if debugging: 173 | print('inserting ' + str(i)) 174 | cur.execute('INSERT INTO riddles VALUES (?,?);', i) 175 | if debugging: 176 | cur.execute('SELECT * FROM riddles') 177 | rows = cur.fetchall() 178 | for row in rows: 179 | print('QUERY ALL: ' + str(row)) 180 | # commit the changes 181 | conn.commit() 182 | # close the database connection to let other operations use it 183 | conn.close() 184 | Game.centerprint('...Have fun') 185 | -------------------------------------------------------------------------------- /quoteslist.txt: -------------------------------------------------------------------------------- 1 | "Two roads diverged in a wood, and I took the one less traveled by, and that has made all the difference." 2 | "These woods are lovely, dark and deep, But I have promises to keep, And miles to go before I sleep, And miles to go before I sleep." 3 | "In three words I can sum up everything I've learned about life: it goes on." 4 | "The best way out is always through." 5 | "We dance round in a ring and suppose, But the Secret sits in the middle and knows." 6 | "Love is an irresistible desire to be irresistibly desired." 7 | "And were an epitaph to be my story I'd have a short one ready for my own. I would have written of me on my stone: I had a lover's quarrel with the world." 8 | "My apple trees will never get across And eat the cones under his pines, I tell him. He only says, “Good fences make good neighbors.”" 9 | "I am not a teacher, but an awakener." 10 | "Whose woods these are I think I know. His house is in the village though; He will not see me stopping here To watch his woods fill up with snow." 11 | "Life, loathe it or ignore it, you can’t like it." 12 | "I think you ought to know I'm feeling very depressed." 13 | "The bird that would soar above the plain of tradition and prejudice must have strong wings." 14 | "Perhaps I'm old and tired, but I always think that the chances of finding out what really is going on are so absurdly remote that the only thing to do is to say hang the sense of it and just keep yourself occupied." 15 | "Ow! My brains!" 16 | "I don't want to die now!" "I've still got a headache! I don't want to go to heaven with a headache, I'd be all cross and wouldn't enjoy it!" 17 | "Pardon me for breathing, which I never do anyway so I don't know why I bother to say it, oh God I'm so depressed." 18 | "I hate to advocate drugs, alcohol, violence, or insanity to anyone, but they've always worked for me." 19 | "A man who procrastinates in his choosing will inevitably have his choice made for him by circumstance." 20 | "Life has become immeasurably better since I have been forced to stop taking it seriously." 21 | "When the going gets weird, the weird turn professional." 22 | "It's never too late to have a happy childhood." 23 | "Humanity has advanced, when it has advanced, not because it has been sober, responsible, and cautious, but because it has been playful, rebellious, and immature." 24 | "Disbelief in magic can force a poor soul into believing in government and business." 25 | "We're our own dragons as well as our own heroes, and we have to rescue ourselves from ourselves." 26 | "The highest function of love is that it makes the loved one a unique and irreplacable being." 27 | "To achieve the impossible, it is precisely the unthinkable that must be thought." 28 | "There are many things worth living for, a few things worth dying for, and nothing worth killing for." 29 | "Equality is not in regarding different things similarly, equality is in regarding different things differently." 30 | "When they tell you to grow up, they mean stop growing." 31 | "There are two kinds of people in this world: Those who believe there are two kinds of people in this world and those who are smart enough to know better. :" 32 | "Not everybody goes to movies to get their life changed." 33 | "I have had it with these goddamn Trolls in this goddamn forest!" 34 | "I don't mind dying, I just don't wanna go out like some punk." 35 | "The year I started golf I had a caddie and one day I did get angry with myself and threw a club. My caddie told me, 'You're not good enough to get mad'." 36 | "What kills me is that everybody thinks I like jazz." 37 | "A Python script is just a script to me. They open, they close." 38 | "Want to know what the 'A.' in A. Lone Traveler means? None of your fucking business." 39 | “If you have an opportunity to use your voice you should use it.” 40 | “I think the biggest challenges for franchises are keeping them fresh and exciting, and most times, you need a good bad guy to make that thing continually work, and sometimes they don't.” 41 | "You think water moves fast? You should see ice. It moves like it has a mind." 42 | "Everybody knows, when you make an assumption, you make an ass out of you and umption" 43 | "Ain't that always the way? Elevator music, a man with a kilt, and a chick with a nickel-plated nine?" 44 | "AK-47, the very best there is. When you absolutely, positively got to kill every motherfucker in the room, accept no substitutes." 45 | "You know me. It's my duty to please that booty." 46 | "The path of the righteous man is beset on all sides by the inequities of the selfish and the tyranny of evil men." 47 | "Don't mistake my patience for cowardice." 48 | "Die, monster! You don't belong in this world!" 49 | "It's all right! If my death can save others, I gladly surrender my life." 50 | "Death in the dream world will send your soul wandering for all eternity, Demon." 51 | "You have been doomed ever since you lost the ability to love." 52 | "For what profit is it to a man if he gains the world, and loses his own soul?" 53 | "The blood that flows through my veins is cursed. T'would be best if I were to disappear forever." 54 | "Man, I don't want to know how many calories that whole pack of crackers was." 55 | "Sizzling circuits!" 56 | "RUMOR HAS IT, THE FERRY-MAN AT DEAD RIVER LOVES GARLIC." 57 | "STEP INTO THE SHADOWS OF THE HELL HOUSE." 58 | "A RIB CAN SHIELD YOU FROM EVIL." 59 | "I'VE BEEN WAITING FOR A GOOD LOOKING GUY LIKE YOU." 60 | "No, this isn't happening. There's no reason for me to go on. WHAT AM I FIGHTING FOOOOOOOOOOOOOOOOR?!" 61 | "Genes exist to pass down our hopes and dreams for the future through our children. Living is a link to the future." 62 | "Save often" 63 | "Save often" 64 | "Save often" 65 | "Save often" 66 | "Save often" 67 | "The highest function of love is that it makes the loved one a unique and irreplaceable being." 68 | "The unhappy person resents it when you try to cheer him up, because that means he has to stop dwelling on himself and start paying attention to the universe." 69 | “A sense of humor...is superior to any religion so far devised.” 70 | “Never underestimate how much assistance, how much satisfaction, how much comfort, how much soul and transcendence there might be in a well-made taco and a cold bottle of beer.” 71 | “The beet is the most intense of vegetables. The radish, admittedly, is more feverish, but the fire of the radish is a cold fire, the fire of discontent not of passion. Tomatoes are lusty enough, yet there runs through tomatoes an undercurrent of frivolity. Beets are deadly serious." 72 | “To achieve the impossible, it is precisely the unthinkable that must be thought.” 73 | “Christianity is merely a system for turning priestesses into handmaidens, queens into concubines, and goddesses into muses.” 74 | “Breathe properly. Stay curious. And eat your beets.” 75 | “It is better to be small, colorful, sexy, careless, and peaceful, like the flowers, than large, conservative, repressed, fearful, and aggressive, like the thunder lizards; a lesson, by the way, that the Earth has yet to learn.” 76 | “Should you fail to pilot your own ship, don't be surprised at what inappropriate port you find yourself docked.” 77 | “Does koala bear poop smell like cough drops?” 78 | "Have you ever eaten ramen noodles raw with the seasoning? Break it up, open it up, pour it in, and they're like ponoodle chips" 79 | "You are now thinking of HER" 80 | "You are now thinking of HIM" 81 | “The minute you land in New Orleans, something wet and dark leaps on you and starts humping you like a swamp dog in heat, and the only way to get that aspect of New Orleans off you is to eat it off." 82 | "I was a North American Fall Webworm in my past life. Those were the good old days... What were you in your former life?" 83 | "That reminds me, I saw Gubayama the other day in Shibomnigee. He said to give you his best." 84 | "You enjoy all the killing!" 85 | "Stop eating so many sandwiches" 86 | "I've seen you around here before" 87 | "Didn't you just come by this way?" 88 | "An anemone or clematis plants juice can cause a rash. When pruning them, its a good idea to wear gloves." 89 | "I hear it's amazing when the famous purple stuffed worm in flap-jaw space with the tuning fork does a raw blink on Hara-Kiri Rock. I need scissors! 61!" 90 | "Actually, I am in really bad shape financially. I pay money to my ex-wife as part of our divorce settlement, among other bills... I just had no choice but to make you pay for lunch the other day. I'm really sorry." 91 | "Just remember, there's a thin line between being a hero and being a memory." 92 | "Sometimes even the wisest of man or machine can make an error." 93 | "I'll gladly repay you Tuesday for a hamburger today." 94 | You come across a man standing over a body. He mutters "Uh... yeah. Killed himself." 95 | "You know, sweetheart, if there's one thing I've learned, it's this: nobody knows what's gonna happen at the end of the line, so you might as well enjoy the trip." 96 | "I have to confess... I never killed anybody." 97 | If the battle number is prime, there's "a secret" to type..." 98 | "The living still give me the creeps." 99 | "They Bought the Farm, Now Sell Them the Cows" 100 | "Your destiny... cannot be purchased." 101 | "So, what IS that stuff they pack canned hams in, anyway?" 102 | “Never underestimate the power of stupid people in large groups.” 103 | “The reason I talk to myself is because I’m the only one whose answers I accept.” 104 | “The planet is fine. The people are fucked.” 105 | "Think of how stupid the average person is, and realize half of them are stupider than that." 106 | "Don't sweat the petty things and don't pet the sweaty things." 107 | "Have you ever noticed that anybody driving slower than you is an idiot, and anyone going faster than you is a maniac?" 108 | "Weather forecast for tonight: dark. Continued dark overnight, with widely scattered light by morning." 109 | "Life is not measured by the number of breaths we take, but by the moments that take our breath away." 110 | "Inside every cynical person, there is a disappointed idealist." 111 | "Can you imagine a fulfilled society? Whoa, what would everyone do? Everyone, LVL15." 112 | "I started to see human beings as little lonesome, water based, pink meat, life forms pushing air through themselves and making noises that the other little pieces of meat seemed to understand. I was thinking to myself, 'There's five billion people here but we've never been more isolated.' The only result of the aggressive individualism we pursue is that you lose sight of your compassion and we go to bed at night thinking, 'Is this all there is?' because we don't feel fulfilled. " 113 | -------------------------------------------------------------------------------- /saves/TESTSAVE1.hero: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crawsome/PyRPG_Mini/a53a409bc2ef48ec72ef57bf0ee249d203c5e248/saves/TESTSAVE1.hero -------------------------------------------------------------------------------- /texttools.py: -------------------------------------------------------------------------------- 1 | import textwrap 2 | from difflib import SequenceMatcher 3 | 4 | 5 | def marqueeprint(text): 6 | print('{:=^70}'.format(text.upper())) 7 | 8 | 9 | # Left-justify print 10 | def leftprint(text): 11 | print('{:<70}'.format(text)) 12 | 13 | 14 | # right-justify print 15 | def rightprint(text): 16 | print('{:>70}'.format(text)) 17 | 18 | 19 | # centered print 20 | def centerprint(text): 21 | wrapstring = textwrap.wrap(text, width=70) 22 | for line in wrapstring: 23 | # print(line) 24 | print('{:^70}'.format(line)) 25 | 26 | 27 | # From https://stackoverflow.com/questions/9660109/allign-left-and-right-in-python 28 | def lr_justify(left, right, width): 29 | return '{}{}{}'.format(left, ' ' * (width - len(left + right)), right) 30 | 31 | 32 | # Prints 4 rows of something with numeric options on left 33 | def fiverowprintoptions(dataheader, table_data, title): 34 | marqueeprint(title) 35 | dataheader.insert(0, '#') 36 | print("{: <2} {: <10} {: <15} {: <22} {: <6}".format(*dataheader)) 37 | for i, row in enumerate(table_data): 38 | row.insert(0, i + 1) 39 | print("{: <2} {: <10} {: <15} {: <22} {: <6}".format(*row)) 40 | 41 | 42 | # dynamic sized row-at-a-time output. Will appropriately size the margins 43 | # of any dict passed to it and tries to print it out all pretty-like. 44 | def gridoutput(table_data): 45 | basestring = '{: ' 46 | centerchar = ['^'] 47 | cap = '} ' 48 | rowformat = '' 49 | columwidth, thedata, dataheader = [], [], [] 50 | for key, value in table_data.items(): 51 | dataheader.append(key) 52 | thedata.append(value) 53 | columwidth.append(len(max([str(key), str(value)], key=len))) 54 | for i, widthsize in enumerate(columwidth): 55 | rowformat += basestring 56 | rowformat += centerchar[i % len(centerchar)] 57 | rowformat += str(widthsize) 58 | rowformat += cap 59 | marqueeprint(('[' + table_data['Name'] + ']').upper()) 60 | 61 | # a hacky way to center the text after the formatting is done 62 | spacesqty = (70 - len(rowformat.format(*dataheader)))/2 63 | spaces = ' ' * int(spacesqty) 64 | print(spaces + rowformat.format(*dataheader)) 65 | print(spaces + rowformat.format(*thedata)) 66 | 67 | 68 | # not developed yet 69 | def gridoutputmultiple(title, table_data): 70 | pass 71 | 72 | 73 | # for debugging and margin adjustments for user to zoom in 74 | def printtest(): 75 | marqueeprint("[[PRINT TEST]]") 76 | leftprint('Justified Left') 77 | rightprint('Justified Right') 78 | centerprint('Center Print') 79 | marqueeprint("[[/PRINT TEST]]") 80 | 81 | 82 | # if string is at least 80% similar, will return true 83 | def similarstring(a, b): 84 | ourratio = SequenceMatcher(None, a, b).ratio() 85 | if ourratio >= .8: 86 | return True 87 | else: 88 | return False 89 | --------------------------------------------------------------------------------