def ranged_critical(roll): damage = 0 if roll == 1: return 'The target has disadvantage on all attack rolls until the end of your next turn.' elif roll == 2: damage = roll_result(3, 6) return 'The target must succeed a DC 14 con save or fall into shock and take {} psychic damage'.format( str(damage)) elif roll < 5: return 'The target loses their reaction, if they currently have one.' elif roll < 11: return 'The target drops their weapon.' elif roll < 13: return "Unless prevented by the reload property, you can make an additional ranged attack on this target." elif roll < 15: removal_damage = roll_result(2, 6) return "You strike the target's leg. Their movement reduces by 10ft until they use their action to remove the projectile and take {} piercing damage.".format( str(removal_damage)) elif roll < 18: internal_damage = roll_result(2, 8) return "The target suffers internal injuries, receiving {} piercing damage.".format( str(internal_damage)) elif roll < 20: return 'The target blinded for the next 10 minutes.' else: return 'You gain an extra action this turn'
def natural_critical(roll): if roll == 1: return 'The target is frightened until the end of your next turn.' elif roll == 2: return 'The target must use all their movement to move away from you in a straight line.' elif roll < 5: return "If the enemy's holding a weapon, you destroy it." elif roll < 7: return "Your ferocity damages the enemy's armor, reducing their AC by 1." elif roll < 9: return "You can use your bonus action to perform a grapple on the target if they are not already grappled." elif roll < 11: return 'If the target is holding a weapon, you can steal it from them.' elif roll < 13: return "The target's movement is reduced to 0 until the start of your next turn." elif roll < 15: temp_hp = roll_result(3, 6) return "Adrenaline pumps through your veins, granting you {} temporary HP".format( str(temp_hp)) elif roll < 17: return "You move quickly, allowing you to repeat this attack using a bonus action." elif roll < 20: return 'The target goes prone. If the target is already prone, they instead take 1d6 bludgeoning damage.' else: return 'You gain an extra action this turn'
def random_object(): objects = [ 'banana', 'short sword', 'potted plant', 'cat', 'miniature statue of themself', 'jar of mayonaise', 'can of peanut brittle that actually contains a springloaded snake toy', 'comfortable sweater', 'bar of premium dark chocolate', 'purse' ] roll = roll_result(10) return objects[roll]
def get_category(): category_dict = { "1": HOSTILE, "2": HARMFUL, "3": NEUTRAL, "4": NEUTRAL, "5": POSITIVE, "6": POSITIVE } result = roll_result(6) return category_dict[str(result)]
def select_x(x, options): selected = [] for i in range(x): selection_made = False while not selection_made: roll = roll_result(len(options))-1 selected_option = options[roll] if selected_option not in selected: print("Picked {}".format(selected_option)) selected.append(selected_option) selection_made = True else: print("Already picked {}".format(selected_option)) return selected
def fumble(category): roll = roll_result(20) result = "" if category == NATURAL: result = natural_fumble(roll) elif category == RANGED: result = ranged_fumble(roll) elif category == MAGIC: result = magic_fumble(roll) elif category == MELEE: result = melee_fumble(roll) else: return "Invalid fumble category" ret = "Critical {} fumble {}: {}".format(category, roll, result) return ret
def critical(category): roll = roll_result(20) result = "" if category == NATURAL: result = natural_critical(roll) elif category == RANGED: result = ranged_critical(roll) elif category == MAGIC: result = magic_critical(roll) elif category == MELEE: result = melee_critical(roll) else: return "Invalid critical category" ret = "{} critical {} In addition to double damage dice: {}".format( category, roll, result) return ret
def magic_critical(roll): if roll == 1: return 'If the target has resistance to this damage type, it loses it for 10 minutes. If not, it instead becomes vulnerable to this damage type for 10 minutes.' elif roll == 2: return 'One creature you choose within 5 feet of the target is also damaged by this spell.' elif roll < 5: return 'The spell was accidentally quickened. If the casting time was already a bonus action or reaction, it did not use the bonus action or reaction.' elif roll < 7: return 'Your spell is super effective! You may reroll all damage dice and take the higher of the two values.' elif roll < 11: hours = roll_result(1, 4) return 'The enemy turns into a {} for {} hours, or until they take damage'.format( random_object(), str(hours)) elif roll < 14: return 'You strike a rich layline and regain up to one expended spell slot of desired level.' elif roll < 18: return 'You weaken the enemy to this damage type. Immunity downgrades to resistance, resistance is lost, and if they lack resistance, they gain vulnerability.' elif roll < 20: return wild_magic() else: return 'You gain an extra action this turn'
def wild_magic(): outcomes = { "1": "Shadowy tendrils lash around you. Each creature of your choice that you can see within 30 feet of you must succeed on a Constitution saving throw or take 1d12 necrotic damage. You also gain 1d12 temporary hit points.", "2": "You teleport up to 30 feet to an unoccupied space you can see.", "3": "An intangible spirit, which looks like a flumph or a pixie (your choice), appears within 5 feet of one creature of your choice that you can see within 30 feet of you. At the end of the current turn, the spirit explodes, and each creature within 5 feet of it must succeed on a Dexterity saving throw or take 1d6 force damage.", "4": "Magic infuses one weapon of your choice that you are holding. Until the end of your next turn, the weapon's damage type changes to force, and it gains the light and thrown properties, with a normal range of 20 feet and a long range of 60 feet. If the weapon leaves your hand, the weapon reappears in your hand at the end of the current turn.", "5": "Whenever a creature hits you with an attack roll before your rage ends, that creature takes 1d6 force damage, as magic lashes out in retribution.", "6": "Until the end of your next turn, you are surrounded by multi colored, protective lights. You gain a +1 bonus to AC, and while within 10 feet of you, your allies gain the same bonus.", "7": "Flowers and vines temporarily grow around you. Until the end of your next turn, the ground within 15 feet of you is difficult terrain for your enemies.", "8": "A bolt of light shoots from your chest. Another creature of your choice that you can see within 30 feet of you must succeed on a Constitution saving throw or take 1d6 radiant damage and be blinded until the start of your next turn.", } roll = roll_result(8) return "You hit a ley line and trigger a wild magic surge {}: {}".format( str(roll), outcomes[str(roll)])
def get_encounter(): category = get_category() table = get_table(category) roll = roll_result(len(table))-1 encounter = table[roll] return "{} {}: {}".format(category, roll, encounter)