def generate_encounter(self, current_player, enctype="creature"): if enctype == 'creature': self.gm_print('Give me a second to get this entry...') creature = Monster( self.data.table_fetch(f'Floor{self.dungeon_data["floor"]}')) self.gm_print(f'You encounter a {creature.name}!') # TODO: Add more options (charm, barter, negotiate, intimidate) self.run_combat(current_player, creature) elif enctype == 'trap': self.gm_print('You encounter a trap!') choice = rpgtools.generate_menu( ['Go around it', 'Disarm it', 'Just trip it']) if choice == 0: if current_player.check('DEX'): self.gm_print('You go around the trap...') else: self.gm_print('You go around the trap...') self.gm_print('But it gets you at the last moment!') current_player.hp -= rpgtools.roll('1d6') elif choice == 1: if current_player.check('INT'): self.gm_print('You try to disarm the trap...') else: self.gm_print('You try to disarm the trap...') self.gm_print('But it gets you at the last moment!') current_player.hp -= rpgtools.roll('1d6') elif choice == 2: self.gm_print('You boldly march straight into the trap!') current_player.hp -= rpgtools.roll('1d6')
def make_wordgen(raw_lang_data, rules): word_gen = {'word': [], 'V': [], 'C': []} for _ in range(6): word_gen['word'].append(make_word_struct(rules).replace('v', '[@V]').replace('c', '[@C]')) word_gen['V'] += raw_lang_data.table_fetch('V', rpgtools.roll('2d3'), repeat=False, concat=False) word_gen['C'] += raw_lang_data.table_fetch('C', rpgtools.roll('6d6'), concat=False) word_gen = table_process.Table(init_data=word_gen) return word_gen
def generate_layer(self, curr_layer, display): layer = self.map[curr_layer] layer[10][10] = '<' curr_dir = self.directory[curr_layer] room_num = 0 curr_dir.append(Room('EXIT', None, '<', [10, 10])) foundexit = False while room_num < coretools.roll(self.limit): candidates = [] targetroom = None # Scan for rooms that you can expand from for x in range(self.width): for y in range(self.height): if layer[y][x] in ['<', '#']: candidates.append([x, y]) # Pick random room to expand expand = random.choice(candidates) for room in curr_dir: if [room.x, room.y] == expand: targetroom = room directions = {'n': [0, -1], 's': [0, 1], 'e': [1, 0], 'w': [-1, 0]} directions_available = ['n', 's', 'e', 'w'] for direction in directions: tx = expand[0] + directions[direction][0] ty = expand[1] + directions[direction][1] if tx < 0 or tx > self.width - 1: directions_available.remove(direction) continue if ty < 0 or ty > self.height - 1: directions_available.remove(direction) continue ty = expand[1] + directions[direction][1] if layer[ty][tx] != '.': directions_available.remove(direction) if directions_available != []: chosen = random.choice(directions_available) tx = expand[0] + directions[chosen][0] ty = expand[1] + directions[chosen][1] if coretools.roll('1d20') == 1 and not foundexit: char = '>' foundexit = True else: char = '#' layer[ty][tx] = char newroom = Room(targetroom, chosen, char, [tx, ty]) curr_dir.append(newroom) targetroom.exits[chosen] = newroom room_num += 1 if display: self.display_progress(layer) time.sleep(0.1) if not foundexit: curr_dir[-1].kind = '>' layer[curr_dir[-1].y][curr_dir[-1].x] = '>' if display: self.display_progress(layer) time.sleep(0.1)
def use(self, user, target): if self.use_case == 'stat': target.data[self.data[0]] += rpgtools.roll(self.data[1]) print( f'({user.name}) I modify {target.name}\'s {self.data[0]} by {self.data[1]}' ) elif self.use_case == 'attack': target.data[self.data[0]] += rpgtools.roll(self.data[1]) print( f'({user.name}) I deal {self.data[1]} damage to {target.name}') if self.consumable: self.consumable -= 1 if self.consumable <= 0: user.inventory.remove(self)
def make_word_struct(ruleset, init_state='v'): curr_state = init_state for _ in range(max(rpgtools.roll(f'2d2-1'), 1)): for rule in ruleset: if rule in curr_state: curr_state = curr_state.replace(rule, random.choice(ruleset[rule]), 1) return curr_state
def check(self, stat): self.player_print(f'Gonna make a {stat} check...') res = rpgtools.roll('1d20') < self.data[stat] if res: self.player_print('Pass.') return True else: self.player_print('Miss.') return False
def run_combat(self, player, enemy): order = [enemy, player] self.gm_print('Roll initiative...') if player.check('DEX'): order = [player, enemy] to_escape = False while True: for actor in order: if actor == player: self.gm_print('Your turn.') choice = rpgtools.generate_menu(['Use Item', 'Flee']) if choice == 0: player.use_inventory_item([enemy]) elif choice == 1: self.gm_print('Give me an escape check.') if player.check('DEX'): self.gm_print('You successfully disengage!') break else: self.gm_print( 'You will flee at the end of the combat turn!') to_escape = True else: self.gm_print(f'It\'s the {actor.name}\'s turn.') for attacks in range(actor.data['#AT']): if rpgtools.roll('1d20') > player.data['AC']: damage = rpgtools.roll(actor.data['Dmg']) player.data['HP'] -= damage self.gm_print( f'The {actor.name} hits you for {damage} damage!' ) else: self.gm_print(f'The {actor.name} misses!') if to_escape: self.gm_print('You flee!') break if player.data['HP'] <= 0: self.gm_print(f'You fall in battle!') player.is_alive = False break elif enemy.data['HP'] <= 0: self.gm_print(f'The {enemy.name} died!') player.xp += 10 break
def __init__(self, statline): statline = statline.split(':') self.name = statline[0].strip() statline = [ _.strip().split() for _ in statline[1].split(';') if _.strip() != '' ] self.data = {} for line in statline: if line[0] == 'AC': self.data['AC'] = int(line[1]) elif line[0] == 'HD': self.data['HP'] = rpgtools.roll(f'{int(line[1])}d6') elif line[0] == '#AT': self.data['#AT'] = int(line[1]) self.data['AttackName'] = line[2] elif line[0] == 'Dmg': self.data['Dmg'] = line[1] self.data['DamageName'] = line[2]
def use_inventory_item(self, extra_targets=None): target = self if self.inventory: choice = self.inventory[rpgtools.generate_menu(self.inventory, use_attr='name')] self.player_print(f"I'm gonna use {choice.name}.") if extra_targets: possible_targets = [self] + extra_targets self.player_print("Gotta pick a target.") target = possible_targets[rpgtools.generate_menu( possible_targets, use_attr='name')] if choice.use_case == 'attack': self.player_print("Making an attack roll...") res = rpgtools.roll('1d20') + self.data['STR'] if res > target.data['AC']: self.player_print('Hit.') choice.use(self, target) else: self.player_print('Miss.') else: choice.use(self, target)
def __init__(self, name): self.name = name self.is_alive = True self.inventory = [ Item('Rusty Sword', 'attack', ['HP', '-1d6']), Item('Ration', 'stat', ['hunger', 3], consumable=3), Item('Torch', 'stat', ['light', 3], consumable=3) ] self.xp = 0 self.data = { 'STR': rpgtools.roll('3d6'), 'DEX': rpgtools.roll('3d6'), 'CON': rpgtools.roll('3d6'), 'INT': rpgtools.roll('3d6'), 'WIS': rpgtools.roll('3d6'), 'CHA': rpgtools.roll('3d6'), 'AC': 10, 'HP': 10, 'HPMax': 10, 'light': 3, 'hunger': 3 }