def used(bot, trigger): """Fetches a used trigger from the Weaver Dice trigger spreadsheet.""" #Use the provided trigger if there is one if trigger.group(2): #Make sure the trigger number a valid integer if not is_integer(trigger.group(2)): return say(bot,"Please provide a valid trigger number.") #Make sure the trigger number is in range trigger_index = int(trigger.group(2)) if trigger_index>len(shared_var['used_list'])+1 or trigger_index < 2: return say(bot,"Used trigger '"+str(trigger_index)+"' is out of range.") t = shared_var['used_list'][trigger_index-2] return mute_say(bot, trigger, trigger.nick + ' ' + t['prefix'] + t['text'], 6) else: if trigger.is_privmsg is False: delay=get_delay_timer('trigger') if delay>0: return say(bot,"ZzZz...["+str(delay)+"s]") set_delay_timer('trigger',30) t = random.choice([x for x in shared_var['used_list'] if x['blank'] == False]) return mute_say(bot, trigger, trigger.nick + ' ' + t['prefix'] + t['text'], 6)
def luck_specific(bot, trigger): """Returns a power/life perk or flaw.""" options = [ 'life perk', 'life flaw', 'life advantage', 'life disadvantage', 'power perk', 'power flaw', 'power advantage', 'power disadvantage', 'perk life', 'perk power', 'advantage life', 'advantage power', 'flaw life', 'flaw power', 'disadvantage life', 'disadvantage power', 'life', 'power', 'perk', 'flaw', 'advantage', 'disadvantage' ] string = trigger.group(1).lower() if trigger.group(2): string = string + ' ' + trigger.group(2).lower() for i in range(0, len(options)): if string.startswith(options[i]): option = options[i] break string = string[len(option):].strip() option = option.replace('disadvantage', 'flaw') option = option.replace('advantage', 'perk') option = option.title() if option.startswith("Perk") or option.startswith("Flaw"): option = ' '.join(reversed(option.split())) if string: if is_integer(string): if option in [ 'Life Perk', 'Life Flaw', 'Power Perk', 'Power Flaw' ]: data = int(string) if data > 1 and data < 80: return say( bot, trigger.nick + ' ' + shared_var['luck_list'][option][data - 2]['text'], 8) else: return say(bot, 'Please provide a number 2 - 79.', 3) else: return say(bot, 'Please be more specific.', 3) else: return luck_keyword(bot, trigger, string, option) else: if option == 'Perk': option = random.choice(['Life Perk', 'Power Perk']) elif option == 'Flaw': option = random.choice(['Life Flaw', 'Power Flaw']) elif option == 'Life': option = random.choice(['Life Perk', 'Life Flaw']) elif option == 'Power': option = random.choice(['Power Perk', 'Power Flaw']) selection = random.choice([ x for x in shared_var['luck_list'][option] if x['blank'] == False ])['text'] return mute_say(bot, trigger, trigger.nick + ' ' + selection, 8)
def refresh(bot, trigger): """Forces the cache to update.""" if not trigger.group(2) or trigger.group(2).lower() == 'capes': cache_capes() say(bot, "Cape cache updated.") if not trigger.group(2) or trigger.group(2).lower() == 'dibs': cache_dibs() say(bot, "Dibs cache updated.")
def card_commands(bot, trigger): if trigger[0] != '$': return data = shared_var['re_delimiters'].split(trigger.strip().lower()) command = data[0][1:] if command in shared_var['card_commands']: if len(data) == 1: return cards(bot, [{ 'key': 'commands', 'pre': '', 'card': command, 'primary': False }], -1) else: list = [] subcommand = command for key in data[1:]: #Check if command has its own sheet, or if it exists as a subcommand if command in shared_var[ 'cards_by_group'] or command + ' ' + key in shared_var[ 'card_sub_commands']: card = {'key': command + ' ' + key, 'pre': ''} list.append(card) #Check if card is a name elif subcommand in shared_var[ 'card_sub_commands'] and subcommand + ' ' + key in shared_var[ 'cards_by_name']: card = {'key': subcommand, 'card': key, 'pre': ''} list = [card] else: return say( bot, "Card '" + command + ' ' + key + "' (or '" + subcommand + "' with name '" + key + "') missing.", 3) subcommand = subcommand + ' ' + key return cards(bot, list)
def luck(bot, trigger): """Rolls 2dx (default 1d4, 1d4) and fetches the relevant perks and/or flaws from the detail sheet.""" die = [4, 4] if trigger.group(2): if is_integer(trigger.group(2)): sides = int(trigger.group(2)) die = [4, sides] else: return luck_keyword(bot, trigger) if (sides < 4): return say(bot, "The dice must have at least 4 sides.") delay = get_delay_timer('luck') if delay > 0: return say(bot, "ZzZz...[" + str(delay) + "s]") set_delay_timer('luck', 15) result = [] roll = [] for x in range(0, 2): selection = ['None'] * die[x] selection[0] = 'Life Flaw' selection[1] = 'Power Flaw' selection[die[x] - 2] = 'Life Perk' selection[die[x] - 1] = 'Power Perk' r = random.randint(1, die[x]) roll.append(str(r) + "/" + str(die[x])) if selection[r - 1] is not 'None': selection = random.choice([ x for x in shared_var['luck_list'][selection[r - 1]] if x['blank'] == False ])['text'] result.append(selection) roll_string = '[' + ', '.join(roll) + ']' if result: result[0] = trigger.nick + ' ' + roll_string + ' ' + result[0] mute_say(bot, trigger, result, 20) else: return say(bot, trigger.nick + ' ' + roll_string + ' [None]')
def luck_keyword(bot, trigger, keyword=None, filter=None): if not keyword: keyword = trigger.group(2).lower() keys = shared_var['re_delimiters'].split(keyword) #Search For Exact Keyword response = None if not response and filter in [None, 'Life', 'Perk', 'Life Perk']: response = next((x for x in shared_var['luck_list']['Life Perk'] if x['keyword'] == keyword), None) if not response and filter in [None, 'Power', 'Perk', 'Power Perk']: response = next((x for x in shared_var['luck_list']['Power Perk'] if x['keyword'] == keyword), None) if not response and filter in [None, 'Life', 'Flaw', 'Life Flaw']: response = next((x for x in shared_var['luck_list']['Life Flaw'] if x['keyword'] == keyword), None) if not response and filter in [None, 'Power', 'Flaw', 'Power Flaw']: response = next((x for x in shared_var['luck_list']['Power Flaw'] if x['keyword'] == keyword), None) #Search For Partial Keyword if not response and filter in [None, 'Life', 'Perk', 'Life Perk']: response = next((x for x in shared_var['luck_list']['Life Perk'] if any(key in x['keyword'] for key in keys)), None) if not response and filter in [None, 'Power', 'Perk', 'Power Perk']: response = next((x for x in shared_var['luck_list']['Power Perk'] if any(key in x['keyword'] for key in keys)), None) if not response and filter in [None, 'Life', 'Flaw', 'Life Flaw']: response = next((x for x in shared_var['luck_list']['Life Flaw'] if any(key in x['keyword'] for key in keys)), None) if not response and filter in [None, 'Power', 'Flaw', 'Power Flaw']: response = next((x for x in shared_var['luck_list']['Power Flaw'] if any(key in x['keyword'] for key in keys)), None) if not response: if not filter: return say(bot, "Invalid luck keyword.") else: return say(bot, "Invalid " + filter + " keyword.") else: return mute_say(bot, trigger, trigger.nick + ' ' + response['text'], 8)
def undibs(bot, trigger): """Reverse a claim on a cape name.""" if trigger.group(2): name = trigger.group(2) say(bot, 'Removing dibs. This might take a moment...') # Update the dibs cache cache_dibs() # Check for a cape with the correct details for id, cape in enumerate(shared_var['dibs']): if cape['name'].upper() == name.upper() and cape['owner'].upper( ) == trigger.nick.upper(): # Remove cape spreadsheet = google_sheet_get(shared_var['sheet']) worksheet = spreadsheet.worksheet('Dibs') worksheet.update_cell(id + 2, 1, '') worksheet.update_cell(id + 2, 2, '') return say(bot, 'Dibs removed.') return say(bot, "You don't have dibs on that name.") else: return say(bot, 'Please specify a cape.')
def markov(bot, trigger): """Returns a markov chain composed of words from current and used triggers.""" chain = 3 size = 42 if trigger.group(2): data = trigger.group(2).split() try: chain = int(data[0]) except ValueError: return say(bot,"Invalid markov chain length .") except AttributeError: return say(bot,"Invalid input.") if (chain==0): return say(bot,"...") if (chain>10 or chain<2): return say(bot,"Please specify a chain length from 2 to 10.") if len(data)>1: try: size = int(data[1]) except ValueError: return say(bot,"Invalid markov size.") except AttributeError: return say(bot,"Invalid input.") if (size<1 or size>200): return say(bot,"Please specify a markov size from 1 to 200.") words = [] for input in shared_var['used_list']: if not input['blank']: words.append(input['text']) for input in shared_var['trigger_list']: if not input['blank']: words.append(input['text']) markov = markovgen.Markov(words,chain) text = markov.generate_markov_text(size) text = text[:1].upper() + text[1:] if text[-1] not in ['.','!','?']: if text[-1] in [',',':',';']: text = text[:-1]+'.' else: text = text + '.' if (size == 4): text = '"'+text[:-1]+'," Scion whispered.' return say(bot,text,3)
def simurgh(bot, trigger): if trigger.nick.lower() not in ['wildbow','wildbow|gm','wild|gm','teller','teller|gm']: return 1 tag = '' if trigger.group(2): #adjustment data = trigger.group(2).split(' ',1) try: offset = min(int(data[0]),90) except ValueError: return say(bot,"Invalid adjustment.") except AttributeError: return say(bot,"Invalid adjustment.") #tag if len(data)>1: tag = data[1] else: offset = random.randrange(0,90) percentage = offset+random.randrange(0,101-offset) if not tag: return say(bot,"Adjusted: ("+str(percentage)+"%)") else: return say(bot,"Adjusted '"+tag+"': ("+str(percentage)+"%)")
def classification(bot, trigger): """Increments the specified classification by the provided number.""" if trigger.sender.lower() != '#weaverdice': return say(bot,'Please perform increments in #Weaverdice.') if trigger.group(2): if trigger.group(1).lower()=="thinker" and trigger.group(2).lower()=="run": return say(bot,'"Thinker. Don\'t worry about the number. Just run."') try: increment = float(trigger.group(2)) except ValueError: return say(bot,"Invalid increment.") except AttributeError: return say(bot,"Invalid input.") if (increment==0): return say(bot,"Nope, not wasting my time incrementing by 0.") else: return say(bot,"Specify a number to increment "+trigger.group(1).lower()+" by. If you're trying to generate an npc, the command is '$npc "+trigger.group(1).lower()+"'") type = trigger.group(1).lower() delay=get_delay_timer(type) if delay>0 and increment*-1!=shared_var['increment::'+type]: return say(bot,"ZzZz...["+str(delay)+"s]") set_delay_timer(type,15) shared_var['increment::'+type]=increment #classes spreadsheet = google_sheet_get(shared_var['trigger_sheet']) worksheet = spreadsheet.worksheet('Count & Frontpage') values = worksheet.col_values(2) shared_var['classes'] = values[6:18] cell = ['mover','shaker','brute','breaker','master','tinker','blaster','thinker','striker','changer','trump','stranger'].index(type) try: shared_var['classes'][cell] = ('%f' % (float(shared_var['classes'][cell])+increment)).rstrip('0').rstrip('.') except: return say(bot,"Invalid count for '"+type.title()+"'.") worksheet.update_cell(7+cell, 2, shared_var['classes'][cell]) return say(bot,type.title()+" count modified by "+str(increment)+". Current value: "+shared_var['classes'][cell])
def card(bot, trigger): """Documentation can be found here: https://goo.gl/6icZb5""" if trigger.group(2): data = trigger.group(2).split(' ') if is_integer(data[-1]): cards(bot, [{ 'key': ' '.join(data[:-1]), 'pre': '', 'card': int(data[-1]) }]) elif data[-1][0] == '"' and data[-1][-1] == '"': cards(bot, [{ 'key': ' '.join(data[:-1]), 'pre': '', 'card': data[-1][1:-1].lower() }]) else: cards(bot, [{'key': trigger.group(2), 'pre': ''}]) else: return say(bot, "Please specify a card.")
def cape(bot, trigger): """Searches the cape database for a name or ID.""" ids = [] if trigger.group(2): if is_integer(trigger.group(2)): ids = [(int(trigger.group(2)), 0)] elif trigger.group(2)[0] == '#' and is_integer(trigger.group(2)[1:]): ids = [(int(trigger.group(2)[1:]), 0)] else: key = trigger.group(2).lower() ids = [] for id, cape in enumerate(shared_var['capes']): # PERFECT MATCH if any(key == alias for alias in cape['s_name']): ids.append((id, 0)) continue if any(key == alias for alias in cape['s_alias'][1:]): ids.append((id, 1)) continue if key == cape['s_alias'][0]: ids.append((id, 2)) continue # SEMI-FUZZY MATCH 1 if key in [ words for segments in cape['s_name'] for words in segments.split() ]: ids.append((id, 3)) continue if key in [ words for segments in cape['s_alias'][1:] for words in segments.split() ]: ids.append((id, 4)) continue if key in cape['s_alias'][0].split(): ids.append((id, 5)) continue # SEMI-FUZZY MATCH 2 if any(alias.startswith(key) for alias in cape['s_name']): ids.append((id, 6)) continue if any(alias.startswith(key) for alias in cape['s_alias'][1:]): ids.append((id, 7)) continue if cape['s_alias'][0].startswith(key): ids.append((id, 8)) continue # FUZZY MATCH if any(key in alias for alias in cape['s_name']): ids.append((id, 9)) continue if any(key in alias for alias in cape['s_alias'][1:]): ids.append((id, 10)) continue if key in cape['s_alias'][0]: ids.append((id, 11)) continue if ids: ids.sort(key=lambda tup: tup[1]) #ID cape = shared_var['capes'][ids[0][0]] #NAME message = '[#' + str(ids[0][0]) + '] ' + cape['name'] #ALIASES if [x for x in cape['alias'] if x]: message = message + ' (AKA ' + ', '.join( [x for x in cape['alias'] if x]) + ')' #OWNER + NPC/PC message = message + ' is' if cape['owner']: if cape['owner'].endswith(('s', 'z')): message = message + ' ' + cape['owner'] + "' " else: message = message + ' ' + cape['owner'] + "'s " if cape['character type']: message = message + cape['character type'] else: message = message + 'character' else: if cape['character type']: if cape['character type'].lower( ) == 'NPC' or cape['character type'].lower().startswith( ('a', 'e', 'i', 'o', 'u')): message = message + ' an ' + cape['character type'] else: message = message + ' a ' + cape['character type'] else: message = message + ' a character' #CAMPAIGN if cape['campaign']: message = message + ' from ' + cape['campaign'] + '.' else: message = message + ' from an unknown campaign.' #EVERYTHING ELSE for key in ('alignment', 'status', 'affiliation', 'classification', 'power', 'notes'): if cape[key]: message = message + ' | ' + key.upper() + ': ' + cape[key] #OUTPUT message = re.sub('(?i)wildbow', "'bow", message) say(bot, message) if len(ids) > 1: say( bot, 'See also: ' + ', '.join(shared_var['capes'][id[0]]['name'] + ' [#' + str(id[0]) + ']' for id in ids[1:10])) return else: return say(bot, 'No cape found.')
def refresh(bot, trigger): """Forces the cache to update.""" if not trigger.group(2) or trigger.group(2).lower() == 'luck': cache_luck() return say(bot, "Luck cache updated.")
def classifications(bot, trigger): """Returns the current classification counts.""" string = '' for i, v in enumerate(['Mover', 'Shaker', 'Brute', 'Breaker', 'Master', 'Tinker', 'Blaster', 'Thinker', 'Striker', 'Changer', 'Trump', 'Stranger']): string = string + ' | ' + v + ': ' + shared_var['classes'][i] return say(bot, string[3:])
def unclaim(bot, trigger): """Reverses a claim on a trigger, moving it back to the Weaver Dice trigger spreadsheet.""" if trigger.sender.lower() != '#weaverdice': return say(bot,'Please perform unclaims in #Weaverdice.') #Validate command if not trigger.group(2): return say(bot,"Specify a used trigger from 2+.") trigger_index = int(trigger.group(2)) if (trigger_index<2): return say(bot,"Specify a used trigger from 2+.") delay=get_delay_timer('claim') if delay>0: return say(bot,"ZzZz...["+str(delay)+"s]") set_delay_timer('claim',15) #Initialize spreadsheet spreadsheet = google_sheet_get(shared_var['trigger_sheet']) worksheet2 = spreadsheet.worksheet('Used') h = worksheet2.row_count #Sort through used trigger list and fetch string/author. Grab the whole thing so the cache can be updated. used_triggers = [["","","","",""] for y in range(h)] cell_list = worksheet2.range('A1:E'+str(h)) for cell in cell_list: used_triggers[cell.row-1][cell.col-1] = cell.value trigger_string = used_triggers[trigger_index-1][1] if not trigger_string: return say(bot,"Used trigger '"+str(trigger_index)+"' is blank.") if used_triggers[trigger_index-1][2]: trigger_author = used_triggers[trigger_index-1][2] else: trigger_author = "?" trigger_string = trigger_string.encode('utf-8', 'ignore').decode('utf-8') trigger_author = trigger_author.encode('utf-8', 'ignore').decode('utf-8') say(bot,'Unclaiming trigger. This might take a moment...') #Fetch trigger list and find an empty slot to insert this trigger in. Update cache while we're at it. worksheet = spreadsheet.worksheet('Triggers') worksheet_height = worksheet.row_count triggers = worksheet.col_values(1) triggers += [None] * (worksheet_height - len(triggers)) update_trigger_cache(triggers) # Find the empty slot slot = None for i, dic in enumerate(shared_var['trigger_list']): if dic['blank']: slot = i + 1 break if slot is None: return say(bot,"...The trigger list is full.") #Update trigger list + cache worksheet.update_cell(slot, 1, trigger_string) worksheet.update_cell(slot, 2, trigger_author) shared_var['trigger_list'][slot-1] = { 'prefix': '['+str(slot)+']: ', 'text': trigger_string, 'blank': False } #Remove used trigger from trigger list used_triggers.pop(trigger_index-1) used_triggers.append([""]*5) h = len(used_triggers) for cell in cell_list: cell.value = used_triggers[cell.row-1][cell.col-1] worksheet2.update_cells(cell_list) #Update trigger cache used_triggers.pop() update_used_cache([row[1] for row in used_triggers[1:]]) return say(bot,'...Used Trigger {'+str(trigger_index)+'} moved to Trigger slot ['+str(slot)+'].')
def claim(bot, trigger): """Moves a trigger to the used section of the Weaver Dice trigger spreadsheet. The square brackets around Player_Name should be included.""" if trigger.sender.lower() != '#weaverdice': return say(bot,'Please perform claims in #Weaverdice.') #Validate command if not trigger.group(2): return say(bot,"Specify a trigger from 1-100.") data = shared_var['re_claim'].match(trigger.group(2)) if data.group(1): if is_integer(data.group(1)): trigger_index = int(data.group(1)) else: return say(bot,"Invalid trigger index.") else: return say(bot,"Specify a trigger from 1-100.") game = data.group(2).strip() if data.group(2) else '?' claimer = data.group(3).strip()[1:-1] if data.group(3) else trigger.nick description = data.group(4).strip() if data.group(4) else '' delay=get_delay_timer('claim') if delay>0: return say(bot,"ZzZz...["+str(delay)+"s]") set_delay_timer('claim',15) #Initialize spreadsheet spreadsheet = google_sheet_get(shared_var['trigger_sheet']) trigger_worksheet = spreadsheet.worksheet('Triggers') trigger_worksheet_height = trigger_worksheet.row_count used_worksheet = spreadsheet.worksheet('Used') used_worksheet_height = used_worksheet.row_count say(bot,'Claiming trigger. This might take a moment...') #Sort through trigger list and fetch the trigger string/author. Might as well grab the whole thing so the trigger cache can be updated. triggers = [["",""] for y in range(trigger_worksheet_height)] cell_list = trigger_worksheet.range('A1:B'+str(trigger_worksheet_height)) for cell in cell_list: triggers[cell.row-1][cell.col-1] = cell.value trigger_string = triggers[trigger_index-1][0] if not trigger_string: return say(bot,"...Trigger '"+str(trigger_index)+"' is blank.") trigger_string=trigger_string.encode('utf-8', 'ignore').decode('utf-8') trigger_author = triggers[trigger_index-1][1] if not trigger_author: trigger_author="?" else: trigger_author=trigger_author.encode('utf-8', 'ignore').decode('utf-8') #Sort through used trigger list and find blank spot. Grab the whole thing so the cache can be updated. used_triggers = used_worksheet.col_values(2) used_triggers += [None] * (used_worksheet_height - len(used_triggers)) update_used_cache(used_triggers[1:]) #Find blank spot to append used trigger. If none is available, append a row. try: slot = used_triggers[1:].index(None)+2 used_worksheet.update_cell(slot, 1, game) used_worksheet.update_cell(slot, 2, trigger_string) used_worksheet.update_cell(slot, 3, trigger_author) used_worksheet.update_cell(slot, 4, claimer) used_worksheet.update_cell(slot, 5, description) shared_var['used_list'][slot-2] = { 'prefix': '{'+str(slot)+'}: ', 'text': trigger_string.encode('utf-8', 'ignore').decode('utf-8'), 'blank': False } except ValueError: used_worksheet.append_row([game,trigger_string,trigger_author,claimer,description]) shared_var['used_list'].append({ 'prefix': '{'+str(used_worksheet_height+1)+'}: ', 'text': trigger_string.encode('utf-8', 'ignore').decode('utf-8'), 'blank': False }) slot = used_worksheet_height+1 #Update trigger list triggers.pop(trigger_index-1) triggers.append([""]*2) for cell in cell_list: cell.value = triggers[cell.row-1][cell.col-1] if not cell.value: cell.value="" trigger_worksheet.update_cells(cell_list) #Update trigger cache update_trigger_cache([row[0] for row in triggers]) #Fin return say(bot,'...Trigger ['+str(trigger_index)+'] moved to Used Trigger slot {'+str(slot)+'}.')
def refresh(bot, trigger): """Forces the cache to update.""" if not trigger.group(2) or trigger.group(2).lower() == 'cards': cache_cards(bot) return say(bot, "Card cache updated.")
def refresh(bot, trigger): """Forces the cache to update.""" if not trigger.group(2) or trigger.group(2).lower() == 'triggers': cache_triggers() return say(bot,"Trigger cache updated.")
def cards(bot, query, count=0): global recursion_limit global recursions recursion_limit = 50 recursions = 0 def get_deck(key): if not isinstance(key, list): if key.lower() in shared_var['cards'] and len( shared_var['cards'][key.lower()]) > 0: return shared_var['cards'][key.lower()] if key.lower() in shared_var['cards_by_group'] and len( shared_var['cards_by_group'][key.lower()]) > 0: return shared_var['cards_by_group'][key.lower()] if key.lower() in shared_var['cards_by_keyword'] and len( shared_var['cards_by_keyword'][key.lower()]) > 0: return shared_var['cards_by_keyword'][key.lower()] return None else: decks = [] for k in key: if k.lower() in shared_var['cards'] and len( shared_var['cards'][k.lower()]) > 0: decks = decks + shared_var['cards'][k.lower()] if k.lower() in shared_var['cards_by_group'] and len( shared_var['cards_by_group'][k.lower()]) > 0: decks = decks + shared_var['cards_by_group'][k.lower()] if k.lower() in shared_var['cards_by_keyword'] and len( shared_var['cards_by_keyword'][k.lower()]) > 0: decks = decks + shared_var['cards_by_keyword'][k.lower()] if decks: return decks else: return None def process_card(card, prefix=[]): global recursions recursions = recursions + 1 if recursions > recursion_limit: return {'output': '', 'queue': []} new_queue = [] text = card['text'] #inline cards for index, value in enumerate(card['inline_cards']): keep = value[0].lower().startswith('keep!') if keep: value[0] = value[0][5:] subdeck = get_deck(value) if not subdeck: return say(bot, "Invalid card '" + ' | '.join(value) + "'") else: options = [x for x in subdeck if x['id'] not in drawn_cards] if not options: options = subdeck # Draw card by odds r = random.uniform(0, sum(item['odds'] for item in options)) s = 0.0 for x in options: subcard = x s += x['odds'] if r < s: break response = process_card(subcard) if not keep: drawn_cards.append(subcard['id']) insert = response['output'] if value[0][0].isupper(): insert = insert[:1].upper() + insert[1:] text = text.replace('{' + str(index + 1) + '}', insert) text = text.replace('{!' + str(index + 1) + '}', insert.capitalize()) #a(n) replacement match = shared_var['re_card_an'].search(text) number = 0 while match and number < 50: article = indefinite_article(match.group(2)) text = text[:match.start(1)] + article + text[match.end(1):] match = shared_var['re_card_an'].search(text) #output output = ''.join(['[' + x + '] ' for x in prefix]) + text #additional cards sub_count = 0 for subcard in card['cards']: show = True card_index = None primary = False if count > 0 else True sep = False ending = False keep = False for tag in subcard['tags']: negate = False if tag and tag[0] == '!': negate = True t = tag[1:] else: t = tag #Draw Order Rejection if t in positions: if positions.index(t) >= count: if negate: show = False elif not negate: show = False #Sub-Draw Order Rejection if is_integer(t): if sub_count >= int(t): if not negate: show = False elif negate: show = False #Percentage if t[-1] == '%' and is_float(t[:-1]): target = float(t[:-1]) if random.uniform(0, 100.0) > target: if not negate: show = False elif negate: show = False #Card Index if t[0] == '#': if is_integer(t[1:]): card_index = int(t[1:]) else: card_index = t[1:] #Separator if t == 'S': sep = not negate #Primary if t == 'P': primary = not negate #Primary if t == 'K': keep = not negate #Add to Queue if show: if sep and (count > 1 or len(new_queue) > 0): new_queue.append(separator) new_queue.append({ 'key': subcard['keyword'], 'pre': subcard['preface'], 'card': card_index, 'primary': primary, 'keep': keep }) sub_count = sub_count + 1 return {'output': output, 'queue': new_queue} #Loop Through Queue queue = query for q in queue: if isinstance(q, dict) and 'primary' not in q: q['primary'] = True drawn_cards = [] separator = '-------' positions = [ '0th', '1st', '2nd', '3rd', '4th', '5th', '6th', '7th', '8th', '9th', '10th' ] while len(queue) > 0 and count < 16: data = queue.pop(0) if not isinstance(data, dict): if len(queue) > 0 or data != separator: say(bot, data) continue if data['primary']: count = count + 1 deck = get_deck(data['key']) if not deck: return say(bot, "Invalid card '" + str(data['key']) + "'") else: if 'card' in data and data['card'] is not None: if isinstance(data['card'], int): if data['card'] > 0 and data['card'] <= len(deck): card = deck[data['card'] - 1] else: return say( bot, "Invalid card '" + str(data['key']) + "' #" + str(data['card'])) else: options = [ x for x in deck if data['card'].lower() in x['names'] and x['id'] not in drawn_cards ] if not options: options = [ x for x in deck if data['card'].lower() in x['names'] ] if not options: return say( bot, "Invalid card '" + str(data['key']) + "' " + '"' + str(data['card']) + '"') card = random.choice(options) else: options = [x for x in deck if x['id'] not in drawn_cards] if not options: options = deck # Draw card by odds r = random.uniform(0, sum(item['odds'] for item in options)) s = 0.0 for x in options: card = x s += x['odds'] if r < s: break response = process_card(card, data['pre']) if 'keep' not in data or not data['keep']: drawn_cards.append(card['id']) if response: queue = response['queue'] + queue say(bot, response['output'], 3) else: return
def dibs(bot, trigger): """Claims a cape name. To see all of the cape names you've claimed, use '$dibs'""" if trigger.group(2): name = trigger.group(2).strip() # Make sure the name is not already a cape for id, cape in enumerate(shared_var['capes']): # PERFECT MATCH if any(name.lower() == alias for alias in cape['s_name']): return say( bot, 'This name is already in use. [Cape #' + str(id) + ']') if any(name.lower() == alias for alias in cape['s_alias'][1:]): return say( bot, 'This name is already in use. [Cape #' + str(id) + ']') if name.lower() == cape['s_alias'][0]: return say( bot, 'This name is already in use. [Cape #' + str(id) + ']') # Update the dibs cache say(bot, 'Calling dibs. This might take a moment...') cache_dibs() # Make sure the name is not already claimed cape = next((item for item in shared_var['dibs'] if item['name'].upper() == name.upper()), None) if cape: if cape['owner'].upper() == trigger.nick.upper(): return say(bot, 'You already called dibs on that name.') else: return say( bot, cape['owner'] + ' already called dibs on that name.') # Add it to the spreadsheet owner = trigger.nick spreadsheet = google_sheet_get(shared_var['sheet']) worksheet = spreadsheet.worksheet('Dibs') # Try to find a blank row if len(shared_var['dibs']) + 1 < worksheet.row_count: index = len(shared_var['dibs']) slot = index shared_var['dibs'].append({'name': '', 'owner': ''}) else: slot = None for index, cape in enumerate(shared_var['dibs']): if cape['name'] == '': slot = index break # Update worksheet and cache if slot is not None: worksheet.update_cell(slot + 2, 1, name) worksheet.update_cell(slot + 2, 2, owner) shared_var['dibs'][index]['name'] = name shared_var['dibs'][index]['owner'] = owner else: worksheet.append_row([name, owner]) # Add it to the cache shared_var['dibs'].append({'name': name, 'owner': owner}) return say(bot, 'Done!') else: # Show all capes with dibs capes = [ cape['name'] for cape in shared_var['dibs'] if cape['owner'].upper() == trigger.nick.upper() ] if len(capes) == 0: return say(bot, 'Your have no capes.') else: return say(bot, 'Your capes are: ' + ', '.join(capes))
def process_card(card, prefix=[]): global recursions recursions = recursions + 1 if recursions > recursion_limit: return {'output': '', 'queue': []} new_queue = [] text = card['text'] #inline cards for index, value in enumerate(card['inline_cards']): keep = value[0].lower().startswith('keep!') if keep: value[0] = value[0][5:] subdeck = get_deck(value) if not subdeck: return say(bot, "Invalid card '" + ' | '.join(value) + "'") else: options = [x for x in subdeck if x['id'] not in drawn_cards] if not options: options = subdeck # Draw card by odds r = random.uniform(0, sum(item['odds'] for item in options)) s = 0.0 for x in options: subcard = x s += x['odds'] if r < s: break response = process_card(subcard) if not keep: drawn_cards.append(subcard['id']) insert = response['output'] if value[0][0].isupper(): insert = insert[:1].upper() + insert[1:] text = text.replace('{' + str(index + 1) + '}', insert) text = text.replace('{!' + str(index + 1) + '}', insert.capitalize()) #a(n) replacement match = shared_var['re_card_an'].search(text) number = 0 while match and number < 50: article = indefinite_article(match.group(2)) text = text[:match.start(1)] + article + text[match.end(1):] match = shared_var['re_card_an'].search(text) #output output = ''.join(['[' + x + '] ' for x in prefix]) + text #additional cards sub_count = 0 for subcard in card['cards']: show = True card_index = None primary = False if count > 0 else True sep = False ending = False keep = False for tag in subcard['tags']: negate = False if tag and tag[0] == '!': negate = True t = tag[1:] else: t = tag #Draw Order Rejection if t in positions: if positions.index(t) >= count: if negate: show = False elif not negate: show = False #Sub-Draw Order Rejection if is_integer(t): if sub_count >= int(t): if not negate: show = False elif negate: show = False #Percentage if t[-1] == '%' and is_float(t[:-1]): target = float(t[:-1]) if random.uniform(0, 100.0) > target: if not negate: show = False elif negate: show = False #Card Index if t[0] == '#': if is_integer(t[1:]): card_index = int(t[1:]) else: card_index = t[1:] #Separator if t == 'S': sep = not negate #Primary if t == 'P': primary = not negate #Primary if t == 'K': keep = not negate #Add to Queue if show: if sep and (count > 1 or len(new_queue) > 0): new_queue.append(separator) new_queue.append({ 'key': subcard['keyword'], 'pre': subcard['preface'], 'card': card_index, 'primary': primary, 'keep': keep }) sub_count = sub_count + 1 return {'output': output, 'queue': new_queue}