예제 #1
0
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)
예제 #2
0
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)
예제 #3
0
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]')
예제 #4
0
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.")
예제 #5
0
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)+'}.')
예제 #6
0
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.')
예제 #7
0
def cache_cards(bot):
    bot.memory['card_help'] = {}
    shared_var['cards'] = {}
    shared_var['cards_by_keyword'] = {}
    shared_var['cards_by_group'] = {}
    shared_var['cards_by_name'] = {}

    shared_var['card_commands'] = []
    shared_var['card_sub_commands'] = []

    spreadsheet = google_sheet_get(shared_var['sheet'])
    worksheets = spreadsheet.worksheets()
    id = 0

    for worksheet in worksheets:
        values = worksheet.get_all_values()
        key_group = worksheet.title.lower()
        key_group = '' if key_group == 'main' else key_group + ' '

        for row in values:
            key_deck = row[0].lower()
            if key_group == '' and key_deck != 'commands':
                shared_var['card_sub_commands'].append(key_deck)

            for col in row[1:]:
                if col.strip():
                    help = ''
                    tmp_card = {
                        'text': col,
                        'cards': [],
                        'names': [],
                        'inline_cards': [],
                        'odds': 1
                    }

                    #Inline Cards
                    match = shared_var['re_inline_cards'].search(
                        tmp_card['text'])
                    number = 1
                    while match and number < 50:
                        tmp_card['inline_cards'].append(
                            [x.strip() for x in match.group(1).split('|')])
                        tmp_card['text'] = tmp_card['text'][:match.start(
                            1)] + str(number) + tmp_card['text'][match.end(1):]
                        match = shared_var['re_inline_cards'].search(
                            tmp_card['text'])
                        number = number + 1

                    #Sub Cards
                    match = shared_var['re_cards'].search(tmp_card['text'])
                    number = 0
                    while match and number < 50:
                        sub_card_data = match.group(1).split('|')
                        sub_card_data += [''] * (3 - len(sub_card_data))
                        subcard = {'keyword': [], 'preface': [], 'tags': []}

                        if sub_card_data[0].strip():
                            subcard['keyword'] = [
                                x.strip() for x in sub_card_data[0].split(',')
                            ]

                        if sub_card_data[1].strip():
                            subcard['preface'] = [
                                x.strip() for x in sub_card_data[1].split(',')
                            ]

                        if sub_card_data[2].strip():
                            subcard['tags'] = [
                                x.strip() for x in sub_card_data[2].split(',')
                            ]

                        tmp_card['cards'].append(subcard)

                        tmp_card['text'] = tmp_card['text'][:match.start(
                        )] + tmp_card['text'][match.end():]
                        match = shared_var['re_cards'].search(tmp_card['text'])
                        number = number + 1

                    #Help
                    match = shared_var['re_card_help'].search(tmp_card['text'])
                    if match:
                        help = match.group(1).strip()
                        tmp_card['text'] = tmp_card['text'][:match.start(
                        )] + tmp_card['text'][match.end():]

                    #Names
                    match = shared_var['re_card_names'].search(
                        tmp_card['text'])
                    number = 0
                    while match and number < 50:
                        tmp_card['names'].append(
                            match.group(1).strip().lower())
                        tmp_card['text'] = tmp_card['text'][:match.start(
                        )] + tmp_card['text'][match.end():]
                        match = shared_var['re_card_names'].search(
                            tmp_card['text'])
                        number = number + 1

                    #Odds
                    match = shared_var['re_card_odds'].search(tmp_card['text'])
                    number = 0
                    while match and number < 50:
                        if is_integer(match.group(1).strip().lower()):
                            tmp_card['odds'] = int(
                                match.group(1).strip().lower())
                        tmp_card['text'] = tmp_card['text'][:match.start(
                        )] + tmp_card['text'][match.end():]
                        match = shared_var['re_card_odds'].search(
                            tmp_card['text'])
                        number = number + 1

                    tmp_card['text'] = tmp_card['text'].strip()

                    tmp_card['id'] = id
                    id = id + 1

                    #Group + Keyword
                    if key_group + key_deck in shared_var['cards']:
                        shared_var['cards'][key_group +
                                            key_deck].append(tmp_card)
                    else:
                        shared_var['cards'][key_group + key_deck] = [tmp_card]

                    #Keyword
                    if key_deck in shared_var['cards_by_keyword']:
                        shared_var['cards_by_keyword'][key_deck].append(
                            tmp_card)
                    else:
                        shared_var['cards_by_keyword'][key_deck] = [tmp_card]

                    #Group
                    if key_group.strip() in shared_var['cards_by_group']:
                        shared_var['cards_by_group'][key_group.strip()].append(
                            tmp_card)
                    else:
                        shared_var['cards_by_group'][key_group.strip()] = [
                            tmp_card
                        ]

                    #Name
                    for name in tmp_card['names']:
                        if key_group + key_deck + ' ' + name in shared_var[
                                'cards_by_name']:
                            shared_var['cards_by_name'][key_group + key_deck +
                                                        ' ' +
                                                        name].append(tmp_card)
                        else:
                            shared_var['cards_by_name'][key_group + key_deck +
                                                        ' ' +
                                                        name] = [tmp_card]

                    #Commands
                    if key_group + key_deck == 'commands':
                        shared_var['card_commands'] = shared_var[
                            'card_commands'] + tmp_card['names']
                        if help:
                            for name in tmp_card['names']:
                                bot.memory['card_help'][name] = help

    bot.memory['card_commands'] = shared_var['card_commands']
예제 #8
0
    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}