Example #1
0
 def encounter(self):
     size = {0: 1, 1: d3(1), 3: d6(1),
             6: d6(2), 9: d6(3), 12: d6(4),
             15: d6(5)}
     for s, n in size.items():
         if self.stats.Pac <= s:
             return n
Example #2
0
 def events_and_mishaps(self, n):
     r = (d6(1), d6(1))
     if not self.terms[n]['S']:
         self.terms[n]['EM'] = 'm[%d]' % r[0]
         self.history += [' Experienced a Mishap (Roll=%d).' % r[0]]
     else:
         self.terms[n]['EM'] = 'e[%d,%d]' % r
         self.history += [' Experienced an Event (Roll=%d,%d).' % r]
Example #3
0
 def events_and_mishaps(self, n):
     r = (d6(1), d6(1))
     if not self.terms[n]['S']:
         self.terms[n]['EM'] = 'm[%d]' % r[0]
         self.history += [' Experienced a Mishap (Roll=%d).' % r[0]]
     else:
         self.terms[n]['EM'] = 'e[%d,%d]' % r
         self.history += [' Experienced an Event (Roll=%d,%d).' % r]
Example #4
0
 def encounter(self):
     size = {
         0: 1,
         1: d3(1),
         3: d6(1),
         6: d6(2),
         9: d6(3),
         12: d6(4),
         15: d6(5)
     }
     for s, n in size.items():
         if self.stats.Pac <= s:
             return n
Example #5
0
 def __init__(self, name):
     pt.Character.__init__(self,
                           name,
                           class_type='Sorcerer',
                           hitdice=dice.d6(),
                           prof_save={
                               'con': 1,
                               'cha': 1
                           },
                           cantrips_by_lvl=caster_cantrips,
                           spells_by_lvl=caster_spell_slots,
                           spells_slots={
                               1: 2,
                               2: 3,
                               3: 4,
                               4: 5,
                               5: 6,
                               6: 7,
                               7: 8,
                               8: 9,
                               9: 10,
                               10: 11,
                               11: 12,
                               12: 12,
                               13: 13,
                               14: 13,
                               15: 14,
                               16: 14,
                               17: 15,
                               18: 15,
                               19: 15,
                               20: 15
                           })
Example #6
0
 def __new__(cls, method=None, value=None):
     if not value > -1:
         if method == "heroic":
             value = sum(sorted([d6(1) for i in range(3)])[-2:])
         elif method == "superheroic":
             value = d6(2)+3
         elif method == "mediocre":
             value = d3(4)
         elif method == "extreme":
             value = d16(1)-1
         elif method == "alternating":
             value = sum([d for j, d in enumerate(sorted([d6(1)
                          for i in range(4)])) if j % 2 == 1])
         else:
             value = d6(2)
     return super(Stat, cls).__new__(cls, value)
Example #7
0
    def roll(self):
        """Roll the dice for this attack, returning a dict:
            hits: dict of hit results
            wounds: dict of wound results

            Also stores the results in self.hits and self.wounds
        """

        hits = dice.d6(self.number, self.hit).roll()

        self.hits = hits

        wounds = dice.d6(hits['passes'], self.wound).roll()

        self.wounds = wounds

        return {'hits': hits, 'wounds': wounds}
Example #8
0
    def stat_wounds(self, attack):
        ''' calculate casualty statistics of this attack '''

        remaining_wounds = attack.stat()['wounds']
        model = self.models[0]
        save = model['profile'].best_save(attack)

        return remaining_wounds - dice.d6(remaining_wounds, save).stat()
Example #9
0
 def determine_dwarf_type(self):
     roll = dice.d6()
     if roll == 1:
         self.star_type = "G"
     elif roll == 2:
         self.star_type = "K"
     else:
         self.star_type = "M"
Example #10
0
    def shoot(self, target):
        roll = dice.d6()

        hit = dice.hit(self, self.dex)
        if hit == True:
            self.deal_dmg(roll, self.dex, target)
        elif hit == False:
            print(f"{self.name} shot, but missed!\nOh the humility!\n")
Example #11
0
 def get_stats(self, sentient=False):
     self.stats = Stats(animal=True)
     s = cap(d6(2) + self.dms["size"], 1, len(SIZES)) - 1
     self.stats.Str = Stat(value=SIZES[s][1])
     self.stats.Dex = Stat(value=SIZES[s][2])
     self.stats.End = Stat(value=SIZES[s][3])
     if not sentient:
         i = choice([0, 1])
         self.stats.Int = Stat(value=i)
     self.size = SIZES[s][0]
Example #12
0
 def get_terrain(self, terrain=None):
     if terrain:
         t = terrain
     else:
         t = choice(TERRAIN.keys())
     m = d6(1)-1
     self.movement = TERRAIN[t][2][m][0]
     self.dms["type"] += TERRAIN[t][0]
     self.dms["size"] += TERRAIN[t][1] + TERRAIN[t][2][m][1]
     self.terrain = t
Example #13
0
 def get_terrain(self, terrain=None):
     if terrain:
         t = terrain
     else:
         t = choice(TERRAIN.keys())
     m = d6(1) - 1
     self.movement = TERRAIN[t][2][m][0]
     self.dms["type"] += TERRAIN[t][0]
     self.dms["size"] += TERRAIN[t][1] + TERRAIN[t][2][m][1]
     self.terrain = t
Example #14
0
 def muster(self, n):
     ben = d6(1)
     career = self.terms[n]['Career'].replace(' Officer', '')
     self.terms[n]['Ben'] = ben
     if choice((0, 1)) == 1:
         self.benefit(ben, career)
     else:
         credits = CREDITS[career][ben - 1]
         self.credits += credits
         self.history += [' Acquired %d.' % credits]
Example #15
0
 def muster(self, n):
     ben = d6(1)
     career = self.terms[n]['Career'].replace(' Officer', '')
     self.terms[n]['Ben'] = ben
     if choice((0, 1)) == 1:
         self.benefit(ben, career)
     else:
         credits = CREDITS[career][ben - 1]
         self.credits += credits
         self.history += [' Acquired %d.' % credits]
Example #16
0
 def get_stats(self, sentient=False):
     self.stats = Stats(animal=True)
     s = cap(d6(2) + self.dms["size"], 1, len(SIZES)) - 1
     self.stats.Str = Stat(value=SIZES[s][1])
     self.stats.Dex = Stat(value=SIZES[s][2])
     self.stats.End = Stat(value=SIZES[s][3])
     if not sentient:
         i = choice([0, 1])
         self.stats.Int = Stat(value=i)
     self.size = SIZES[s][0]
Example #17
0
    def take_wounds(self, attack):
        """ Take saves on inflicted wounds, apply wounds, and remove casualties

        Arguments:
            attack: a WoundingAttack object describing the attack

        Returns:
            the total number of unsaved wounds suffered by the unit
        """

        unsaved = 0
        remaining_wounds = attack.wounds['passes']

        while remaining_wounds and self.alive:
            # determine the number of wounds we can roll for now
            model = self.models[0]
            wounds_to_take = remaining_wounds
            wounds_characteristic = model['profile'].wounds
            max_wounds = model['count'] * wounds_characteristic - model['wounds'];
            if wounds_to_take > max_wounds:
                wounds_to_take = max_wounds
            remaining_wounds -= wounds_to_take

            save = model['profile'].best_save(attack)

            # roll the dice
            roll = dice.d6(wounds_to_take, save).roll()

            # inflict casualties
            casualties = roll['fails']
            unsaved += casualties
            # handle wounded models first
            if model['wounds']:
                to_go = wounds_characteristic - model['wounds']
                if casualties >= to_go:
                    model['wounds'] = 0
                    model['count'] -= 1
                else :
                    model['wounds'] += to_go

                casualties -= to_go

            # handle further casualties
            if casualties:
                model['count'] -= math.floor(casualties / model['profile'].wounds)

                # add leftover wounds
                model['wounds'] = casualties % model['profile'].wounds

            # remove eradicated models
            if model['count'] < 1:
                self.removeModel(model)

        return unsaved
Example #18
0
 def __init__(self, name):
     pt.Character.__init__(self,
                           name,
                           class_type='Wizard',
                           hitdice=dice.d6(),
                           prof_saves={
                               'int': 1,
                               'wis': 1
                           },
                           cantrips_by_lvl=caster_cantrips,
                           spells_by_lvl=caster_spell_slots)
Example #19
0
 def generate(self):
     roll = dice.d6(2)
     num_stars = 1
     if roll == 10:
         num_stars = 2
     elif roll == 11:
         num_stars = 3
     else:
         num_stars = 4
     for i in range(num_stars):
         star = (Star()).generate()
         self.stars.append(star)
Example #20
0
 def determine_star_class(self):
     roll = dice.d6(3)
     if roll >= 3 and roll <= 5:
         self.star_class = "D"
     elif roll == 6:
         self.star_class = "VI"
     elif roll == 18:
         roll = dice.d6(3)
         if roll == 3:
             roll = dice.d100()
             if roll <= 33:
                self.star_class = "Ia"
             else:
                self.star_class = "Ib"
         elif roll == 4:
             self.star_class = "II"
         elif roll >= 5 and roll <= 12:
             self.star_class = "III"
         else:
             self.star_class = "IV"
     else:
         self.star_class = "V"
Example #21
0
 def get_behavior(self, behavior=None):
     orders = {"Herbivore": 0, "Omnivore": 1,
               "Carnivore": 2, "Scavenger": 3}
     if not behavior:
         r = cap(d6(2) + self.dms["type"], 1, 12)
         for a in range(len(ANIMAL_TYPES)):
             if r - 1 <= a:
                 behavior = ANIMAL_TYPES[r][orders[self.order]]
                 break
     else:
         a = [y for x in ANIMAL_TYPES for y in x]
         self.order = ORDERS[divmod(a.index(behavior), 6)[1]][1]
     self.behavior = behavior
Example #22
0
 def get_skills(self):
     self.skills = SkillSet()
     self.skills.update(STARTING_SKILLS)
     for b in BEHAVIORS[self.behavior]:
         attr, n = b
         if attr in STATS:
             self.stats[attr] = Stat(self.stats[attr] + n)
         elif attr in self.skills:
             self.skills[attr] += n
         else:
             self.skills[attr] = n
     for r in range(d6(1)):
         sk = choice(self.skills.keys())
         self.skills[sk] += 1
Example #23
0
 def get_skills(self):
     self.skills = SkillSet()
     self.skills.update(STARTING_SKILLS)
     for b in BEHAVIORS[self.behavior]:
         attr, n = b
         if attr in STATS:
             self.stats[attr] = Stat(self.stats[attr] + n)
         elif attr in self.skills:
             self.skills[attr] += n
         else:
             self.skills[attr] = n
     for r in range(d6(1)):
         sk = choice(self.skills.keys())
         self.skills[sk] += 1
Example #24
0
def main(argv):

    slack = slacker.Slacker(private.sixthWorld)

    charactername = argv[0]
    difficulty = argv[1]
    channelname = argv[2]

    modifiers = \
        {
            'sexy sleepwear': 4,
            'pheromone augmentation': 2
        }
    last = len(modifiers) - 1

    mod_bonus = 0
    for key, value in modifiers.items():
        mod_bonus += value

    character = get_data(charactername)

    die_pool = character['Charisma'] + character['Seduction'] + mod_bonus

    # create good looking description
    description = ''
    description += ('_' + character['Name'] + ' ' + __actionname__ + '_\n')

    description += (
        "Charisma(" + str(character['Charisma']) + ")  + " +
        "Seduction(" + str(character['Seduction']) + ") + ")

    for i, key in enumerate(modifiers):
        if i == last:
            operator = '= '
        else:
            operator = '+ '
        description += (
            str(key) + "(" + str(modifiers[key]) + ") " + operator)

    description += ("*" + str(die_pool) + "d6*")
    
    # perform the roll
    roll = d6(die_pool)

    # send results to slack
    output = check(difficulty, roll)
    slack.chat.post_message(channelname, description + '\n' + str(roll) + "\n" + output, username=character['Name'], icon_url=character['imageURL'])
Example #25
0
def test_d6():
    # test object
    rolls = dice.d6(10, 3)

    # expected
    expected_roll = {'passes': 7, 'fails': 3, 2: 1, 3: 2, 4: 2, 5: 3, 6: 0, 1: 2}
    expected_stat = 6.6666666

    # roll test
    roll = rolls.roll()
    roll_result = roll == expected_roll

    # stat test
    stat = rolls.stat()
    stat_result = close_enough(stat, expected_stat)

    assert roll_result and stat_result
Example #26
0
    def age(self, n):
        age = '-' if n < 3 else d6(2) - n + 1
        if age < 1:
            age = max(-6, age)
            pens = AGING[-age]
            for p, pen in enumerate(pens):
                if pen:
                    if p == 3:
                        a = choice(('Int', 'Edu', 'Soc'))
                    else:
                        a = choice(('Str', 'Dex', 'End'))
                    self.stats[a] -= pen
                    if self.stats[a] < 0:
                        self.stats[a] = Stat(value=0)
                    self.history += [' Lost %d %s due to aging.' % (pen, a)]

        self.terms[n]['Age'] = age
Example #27
0
 def get_behavior(self, behavior=None):
     orders = {
         "Herbivore": 0,
         "Omnivore": 1,
         "Carnivore": 2,
         "Scavenger": 3
     }
     if not behavior:
         r = cap(d6(2) + self.dms["type"], 1, 12)
         for a in range(len(ANIMAL_TYPES)):
             if r - 1 <= a:
                 behavior = ANIMAL_TYPES[r][orders[self.order]]
                 break
     else:
         a = [y for x in ANIMAL_TYPES for y in x]
         self.order = ORDERS[divmod(a.index(behavior), 6)[1]][1]
     self.behavior = behavior
Example #28
0
    def age(self, n):
        age = '-' if n < 3 else d6(2) - n + 1
        if age < 1:
            age = max(-6, age)
            pens = AGING[-age]
            for p, pen in enumerate(pens):
                if pen:
                    if p == 3:
                        a = choice(('Int', 'Edu', 'Soc'))
                    else:
                        a = choice(('Str', 'Dex', 'End'))
                    self.stats[a] -= pen
                    if self.stats[a] < 0:
                        self.stats[a] = Stat(value=0)
                    self.history += [' Lost %d %s due to aging.' % (pen, a)]

        self.terms[n]['Age'] = age
Example #29
0
 def determine_mainseq_type(self):
     roll = dice.d6(3)
     if roll >= 9 and roll <= 18:
         self.star_type = "M"
     else:
         if roll == 3:
             self.star_type = "O"
         elif roll == 4:
             self.star_type = "B"
         elif roll == 5:
             self.star_type = "A"
         elif roll == 6:
             self.star_type = "F"
         elif roll == 7:
             self.star_type = "G"
         else:
             self.star_type = "K"
Example #30
0
 def lightning_bolt(self, hit, evade, enemyMod):
     if ((hit > evade + enemyMod) and self.magic_slots > 0):
         damage = (dice.d6(1) + dice.d6(1) + dice.d6(1) +
                   dice.d6(1)) + self.intMod
         self.magic_slots -= 1
     elif ((hit <= evade + enemyMod) and self.magic_slots > 0):
         damage = (dice.d6(1) + dice.d6(1)) + self.intMod
         self.magic_slots -= 1
     elif (self.magic_slots <= 0):
         print("no magic left")
         damage = 0
     return damage
Example #31
0
 def determine_giant_type(self):
     done = False
     while not done:
         roll = dice.d6(2)
         if roll == 2:
             self.star_type = "O"
         elif roll == 3:
             self.star_type = "M"
         elif roll == 4 or roll == 5:
             self.star_type = "B"
         elif roll >= 6 and roll <= 9:
             self.star_type = "K"
         else:
             self.star_type = "A"
         if self.star_type != "O" and self.star_type != "M":
             done = True
             
         # an excepttion is that if type O, class II, III, and IV do not exist, and type M, class IV as well. Reroll
         # 
         else:
             if self.star_type == "M" and self.star_class != "IV":
                 done = True
             elif self.star_type == "O" and (self.star_class == "Ia" or self.star_class == "Ib"):
                 done = True
Example #32
0
from dice import d6

print(d6(),d6())
Example #33
0
 def magic_missiles(self, attackee):
     dmg_amount = d6() + 1
     print(f"{self.name} attacks {attackee} doing {dmg_amount} damage")
     return dmg_amount
Example #34
0
 def cure_wounds(self):
     heal_amount = d6() + 1
     print(f"{self.name} healed for {heal_amount} health")
     Creature.heal(self, heal_amount)
Example #35
0
 def get_weap_arm(self):
     a = cap(d6(2) + self.dms['armor'], 1, 13)
     w = cap(d6(2) + self.dms['weapon'], 1, 13)
     self.armor = cap(a//2 - 1, 0, 5)
     self.weapon = WEAPONS[w-1][0]
     self.damage = 1 + self.stats.Str//10 + WEAPONS[w-1][1]
Example #36
0
def runner(action_info):

    slack = slacker.Slacker(private.sixthWorld)

    # last is used in buiding the description, to use = at the end not +
    last = len(action_info['modifiers']) - 1 
    
    # caluclate total modifier bonus
    mod_bonus = 0
    for key, value in action_info['modifiers'].items():
        mod_bonus += value
    
    # get character dictionary
    character = get_data(action_info['character_name'])
    
    # create die pool based on Attribute, Skill, Skill Group
    die_pool = 0
    if (action_info['attribute'] and action_info['skill'] != ''):
        die_pool    += character[action_info['attribute']] 
        die_pool    += character[action_info['skill']] + mod_bonus
    elif (action_info['skill'] == ''):
        die_pool    += character[action_info['attribute']]
    else:
        print('Error, action_info must have an attribute defined')
        

    # create good looking description
    # Name, Action, Attribute and Skill information
    description = ''
    description += (
        '_' + character['Name'] + ' ' + action_info['action_name'] + '_\n' +
        action_info['attribute'] + 
        "(" + str(character[action_info['attribute']]) + ")  + " +
        action_info['skill'] + 
        "(" + str(character[action_info['skill']]) + ") + "
        )

    # Modifier information
    for i, key in enumerate(action_info['modifiers']):
        if i == last:
            operator = '= '
        else:
            operator = '+ '
        description += (
            str(key) + 
            "(" + str(action_info['modifiers'][key]) + ") "
            + operator
            )

    # Die pool
    description += ("*" + str(die_pool) + "d6*")
    
    # Perform the roll
    roll = d6(die_pool)
    
    # Send results to Slack
    output = check(5, roll)
    
    try:
        slack.chat.post_message(
            '#scratch', 
            description + '\n' + str(roll) + "\n" + output, 
            username=character['Name'], 
            icon_url=character['imageURL']
            )
    except:
        print('failure sending to slack')
Example #37
0
    ("Intermittent", "Gatherer", "Pouncer", "Hijacker"),
    ("Intermittent", "Eater", "Brute Killer", "Carrion-Eater"),
    ("Intermittent", "Gatherer", "Trapper", "Intimidator"),
    ("Intermittent", "Hunter", "Pouncer", "Reducer"),
    ("Grazer", "Hunter", "Chaser", "Carrion-Eater"),
    ("Grazer", "Hunter", "Chaser", "Reducer"),
    ("Grazer", "Gatherer", "Chaser", "Hijacker"),
    ("Grazer", "Eater", "Swift Killer", "Intimidator"),
    ("Grazer", "Hunter", "Chaser", "Reducer"),
    ("Grazer", "Gatherer", "Siren", "Hijacker"),
    ("Grazer", "Gatherer", "Chaser", "Intimidator"),
)

SIZES = (
    # 2d6: (Weight (kg), Strength, Dexterity, Endurance)
    (1, 1, d6(1), 1),
    (3, 2, d6(1), 2),
    (6, d6(1), d6(2), d6(1)),
    (12, d6(1), d6(2), d6(1)),
    (25, d6(2), d6(3), d6(2)),
    (50, d6(2), d6(4), d6(2)),
    (100, d6(3), d6(3), d6(3)),
    (200, d6(3), d6(3), d6(3)),
    (400, d6(4), d6(2), d6(4)),
    (800, d6(4), d6(2), d6(4)),
    (1600, d6(5), d6(2), d6(5)),
    (3200, d6(6), d6(1), d6(6)),
    (5000, d6(7), d6(1), d6(7)),
    (6000, d6(8), d6(1), d6(8)),
    (7000, d6(9), d6(1), d6(9)),
    (8000, d6(10), d6(1), d6(10)),
Example #38
0
 def roll(self, mods=0):
     return (d6(2) + self() + mods)
Example #39
0
# using dnd character classes to practice python classes and (more importantly) class inheritance

# not sure what main will be used for, lol

import dice
import class_types
import armor

# testing Dice
d4 = dice.d4()
d6 = dice.d6()
d8 = dice.d8()
d10 = dice.d10()
d12 = dice.d12()
d20 = dice.d20()
"""
print(f"Rolling d4: {d4.roll()}")
print(f"Rolling d4: {d4.roll()}")
print(f"Rolling d4: {d4.roll()}")

print(f"Rolling d6: {d6.roll()}")
print(f"Rolling d8: {d8.roll()}")
print(f"Rolling d20: {d20.roll()}")

print(f"Rolling 4d6, indiv: {d6.roll_indiv(4)}")
print(f"Rolling 6d8, summed: {d8.roll_sum(4)}")
"""

Drat = class_types.Bard("Drat of Hithendale")

Drat.say_name()
Example #40
0
 def levelUP(self):
     self.hp = self.hp + (dice.d6(1) + self.conMod)
     self.level += 1
Example #41
0
 def get_quirks(self):
     Q = QUIRKS.items()
     sk = sample(range(len(Q) * 6), d6(1))
     cells = [divmod(x, len(Q)) for x in sk]
     self.quirks = [Q[x][1][y] for x, y in cells]
Example #42
0
 def get_weap_arm(self):
     a = cap(d6(2) + self.dms['armor'], 1, 13)
     w = cap(d6(2) + self.dms['weapon'], 1, 13)
     self.armor = cap(a // 2 - 1, 0, 5)
     self.weapon = WEAPONS[w - 1][0]
     self.damage = 1 + self.stats.Str // 10 + WEAPONS[w - 1][1]
Example #43
0
L4 = Label(text="Total Modifier:")
E4 = Entry(bd =3)
L5 = Label(text="Result:")
if (E1.get() == ""):
	E1.insert(END, "0")
	E2.insert(END, "0")
	E3.insert(END, "0")
	E4.insert(END, "0")
v=StringVar()
L6 = Label(textvariable=v)
B1 = Button(text="Roll!", command=lambda: v.set(E2.get() + "d(" + E1.get() + '{:+}'.format(int(E3.get())) + ") " + '{:+}'.format(int(E4.get())) + " = "
	'{:+}'.format(dice.roller(int(E1.get()), int(E2.get()), int(E3.get())) + int(E4.get()))))
B2 = Button(text='d2', command=lambda: v.set("d2: " + str(dice.d2())))
B3 = Button(text="d3", command=lambda: v.set("d3: " + str(dice.d3())))
B4 = Button(text="d4", command=lambda: v.set("d4: " + str(dice.d4())))
B6 = Button(text="d6", command=lambda: v.set("d6: " + str(dice.d6())))
B8 = Button(text="d8", command=lambda: v.set("d8: " + str(dice.d8())))
B10 = Button(text="d10", command=lambda: v.set("d10: " + str(dice.d10())))
B20 = Button(text="d20", command=lambda: v.set("d20: " + str(dice.d20())))
B100 = Button(text="d100", command=lambda: v.set("d100: " + str(dice.d100())))
L1.grid(row=0, column=0, columnspan=1)
E1.grid(row=1, column=0, columnspan=1)
L2.grid(row=2, column=0, columnspan=1)
E2.grid(row=3, column=0, columnspan=1)
L3.grid(row=4, column=0, columnspan=1)
E3.grid(row=5, column=0, columnspan=1)
L4.grid(row=6, column=0, columnspan=1)
E4.grid(row=7, column=0, columnspan=1)
L5.grid(row=8, column=0, columnspan=1, sticky=W)
L6.grid(row=9, column=0, columnspan=1, sticky=W)
B1.grid(row=0, column=1, columnspan=1, sticky=W, padx = 10)
Example #44
0
 def test_6面ダイスを振る(self):
     self.assertIn(d6(), [1, 2, 3, 4, 5, 6])
Example #45
0
 def get_quirks(self):
     Q = QUIRKS.items()
     sk = sample(range(len(Q)*6), d6(1))
     cells = [divmod(x, len(Q)) for x in sk]
     self.quirks = [Q[x][1][y] for x, y in cells]
Example #46
0
    def stat(self):
        hits = dice.d6(self.number, self.hit).stat();
        wounds = dice.d6(hits, self.wound).stat();

        return {'hits': hits, 'wounds': wounds}
Example #47
0
    ("Intermittent", "Gatherer", "Pouncer", "Hijacker"),
    ("Intermittent", "Eater", "Brute Killer", "Carrion-Eater"),
    ("Intermittent", "Gatherer", "Trapper", "Intimidator"),
    ("Intermittent", "Hunter", "Pouncer", "Reducer"),
    ("Grazer", "Hunter", "Chaser", "Carrion-Eater"),
    ("Grazer", "Hunter", "Chaser", "Reducer"),
    ("Grazer", "Gatherer", "Chaser", "Hijacker"),
    ("Grazer", "Eater", "Swift Killer", "Intimidator"),
    ("Grazer", "Hunter", "Chaser", "Reducer"),
    ("Grazer", "Gatherer", "Siren", "Hijacker"),
    ("Grazer", "Gatherer", "Chaser", "Intimidator"),
    )

SIZES = (
    # 2d6: (Weight (kg), Strength, Dexterity, Endurance)
    (1, 1, d6(1), 1),
    (3, 2, d6(1), 2),
    (6, d6(1), d6(2), d6(1)),
    (12, d6(1), d6(2), d6(1)),
    (25, d6(2), d6(3), d6(2)),
    (50, d6(2), d6(4), d6(2)),
    (100, d6(3), d6(3), d6(3)),
    (200, d6(3), d6(3), d6(3)),
    (400, d6(4), d6(2), d6(4)),
    (800, d6(4), d6(2), d6(4)),
    (1600, d6(5), d6(2), d6(5)),
    (3200, d6(6), d6(1), d6(6)),
    (5000, d6(7), d6(1), d6(7)),
    (6000, d6(8), d6(1), d6(8)),
    (7000, d6(9), d6(1), d6(9)),
    (8000, d6(10), d6(1), d6(10)),