Files
dungeon-sheets/tests/test_encounter.py
T
2021-05-23 15:52:50 -04:00

239 lines
7.9 KiB
Python

#!/usr/bin/env python
from unittest import TestCase, skip
from dungeonsheets.armor import ChainShirt
from dungeonsheets.character import Character
from dungeonsheets.encounter import Encounter
from dungeonsheets.encounter.actions import Attack
from dungeonsheets.encounter.events import AttackEvent
from dungeonsheets.monsters import Monster, GiantRat
from dungeonsheets.stats import Ability
from dungeonsheets.dice import roll
class TestEncounter(TestCase):
"""Tests for features and feature-related activities."""
def test_simple_rat_fight(self):
"""A fight against a giant rat"""
char = SimpleRanger()
class StravajiaxenAttack(Attack):
# TODO: Get default player attacks as a result of
# creating a player character and classes
def __init__(self, subj, obj):
self.subj = subj
self.obj = obj
def execute(self):
result = roll(20) + self.subj.dexterity.modifier + self.subj.proficiency_bonus
damage = roll(1, 8) + self.subj.dexterity.modifier
is_hit = result >= self.obj.armor_class
if is_hit:
self.obj.current_hp -= damage
return AttackEvent(self, result, damage, is_hit)
char.default_actions.append(StravajiaxenAttack)
class GiantRatAttack(Attack):
def __init__(self, subj, obj):
self.subj = subj
self.obj = obj
def execute(self):
result = roll(20) + 4
damage = roll(1, 4) + 2
is_hit = result >= self.obj.armor_class
if is_hit:
self.obj.current_hp -= damage
return AttackEvent(self, result, damage, is_hit)
enemy = GiantRat()
enemy.name = "Nameless Rat" # I don't want things to be personal...
enemy.default_actions.append(GiantRatAttack)
battle = Encounter([char], [enemy])
battle.reset()
results = battle.simulate()
for event in results:
print(str(event))
print(results)
@skip('NotImplementedError')
def test_langdedrosa_fight(self):
"""Can I run an encounter against Langdedrosa Cyanwrath?"""
char = Character()
char.set_attrs(name="Stravajiaxen")
char.set_attrs(weapons=["greataxe"])
char.set_attrs(armor="split mail")
# Check that race gets set to an object
char.set_attrs(race="half orc")
char.set_attrs(inspiration=False)
class LangdedrosaCyanwrath(Monster):
"""
**Action Surge (Recharges on a Short or Long Rest).** On his turn, Langdedrosa
can take one additional action.
**Improved Critical.** Langdedrosa's weapon attacks score a critical hit on a
roll of 19 or 20.
**Multiattack:** Schlangdedrosa attacks twice, either with his greatsword or spear.
**Greatsword.** Melee Weapon Attack: +6 to hit, reach 5 ft., one target.
Hit: 11 (2d6 + 4) slashing damage.
**Spear.** Melee or Ranged Weapon Attack: +6 to hit, reach 5 ft. or
ranged 20/60 ft., one target. Hit: 7 (1d6 + 4) piercing damage.
**Lightning Breath (Recharge 5-6)**. Schlangdedrosa breathes lightning in a
30-foot line that is 5 feet wide. Each creature in the line must make a DC 13
Dexterity saving throw, taking 22 (4d10) lightning damage on a failed save, or
half as much damage on a successful one.
**Climbing speed:** 30 ft.
"""
name = "Langdedrosa Cyanwrath"
description = "Medium humanoid (half-dragon), lawful evil"
challenge_rating = 4
armor_class = 17
skills = "Athletics +6, Intimidation +3, Perception +4"
senses = "blindsight 10 ft., darkvision 60ft., passive Perception 14"
strength = Ability(19)
dexterity = Ability(13)
constitution = Ability(16)
intelligence = Ability(10)
wisdom = Ability(14)
charisma = Ability(12)
speed = 30
swim_speed = 0
fly_speed = 0
hp_max = 57
hit_dice = "6d12+18"
lang = LangdedrosaCyanwrath()
battle = Encounter([char], [lang])
results = battle.simulate()
class SimpleRanger(Character): # Taken from ranger2.py
"""This file describes the heroic adventurer Ranger2.
It's used primarily for saving characters from create-character,
where there will be many missing sections.
Modify this file as you level up and then re-generate the character
sheet by running ``makesheets`` from the command line.
"""
dungeonsheets_version = "0.9.4"
name = "Stravajiaxen"
player_name = "Ben"
# Be sure to list Primary class first
classes = ['Ranger'] # ex: ['Wizard'] or ['Rogue', 'Fighter']
levels = [3] # ex: [10] or [3, 2]
subclasses = ["Horizon Walker"] # ex: ['Necromacy'] or ['Thief', None]
background = "Uthgardt Tribe Member"
race = "Lizardfolk"
alignment = "Neutral good"
xp = 0
hp_max = 24
inspiration = 0 # integer inspiration value
# Ability Scores
strength = Ability(13)
dexterity = Ability(15)
constitution = Ability(12)
intelligence = Ability(8)
wisdom = Ability(15)
charisma = Ability(12)
# Select what skills you're proficient with
# ex: skill_proficiencies = ('athletics', 'acrobatics', 'arcana')
skill_proficiencies = ('athletics', 'insight', 'investigation')
# Any skills you have "expertise" (Bard/Rogue) in
skill_expertise = ()
# Named features / feats that aren't part of your classes, race, or background.
# Also include Eldritch Invocations and features you make multiple selection of
# (like Maneuvers for Fighter, Metamagic for Sorcerors, Trick Shots for
# Gunslinger, etc.)
# Example:
# features = ('Tavern Brawler',) # take the optional Feat from PHB
features = ()
# If selecting among multiple feature options: ex Fighting Style
# Example (Fighting Style):
# feature_choices = ('Archery',)
feature_choices = ('dueling',)
# Weapons/other proficiencies not given by class/race/background
weapon_proficiencies = () # ex: ('shortsword', 'quarterstaff')
_proficiencies_text = () # ex: ("thieves' tools",)
# Proficiencies and languages
languages = """Dwarvish, Common, Draconic"""
# Inventory
# TODO: Get yourself some money
cp = 0
sp = 0
ep = 0
gp = 0
pp = 0
# TODO: Put your equipped weapons and armor here
weapons = ('rapier', 'hand crossbow') # Example: ('shortsword', 'longsword')
magic_items = () # Example: ('ring of protection',)
armor = ChainShirt # Eg "leather armor"
shield = "" # Eg "shield"
equipment = """TODO: list the equipment and magic items your character carries"""
attacks_and_spellcasting = """TODO: Describe how your character usually attacks
or uses spells."""
# List of known spells
# Example: spells_prepared = ('magic missile', 'mage armor')
spells_prepared = () # Todo: Learn some spells
# Which spells have not been prepared
__spells_unprepared = ()
# all spells known
spells = spells_prepared + __spells_unprepared
# Wild shapes for Druid
wild_shapes = () # Ex: ('ape', 'wolf', 'ankylosaurus')
# Backstory
# Describe your backstory here
personality_traits = """TODO: How does your character behave? See the PHB for
examples of all the sections below"""
ideals = """TODO: What does your character believe in?"""
bonds = """TODO: Describe what debts your character has to pay,
and other commitments or ongoing quests they have."""
flaws = """TODO: Describe your characters interesting flaws.
"""
features_and_traits = """TODO: Describe other features and abilities your
character has."""