diff --git a/dungeonsheets/agent.py b/dungeonsheets/agent.py index 4f8e590..c5ee799 100644 --- a/dungeonsheets/agent.py +++ b/dungeonsheets/agent.py @@ -1,14 +1,16 @@ -from dungeonsheets.stats import Ability, ArmorClass, Initiative, Speed +from dungeonsheets.stats import Ability, ArmorClass, Initiative, Speed, Skill class Agent: """An actor in an encounter""" - strategies = ("Random", "Greedy", "KillWeakest") - strategy = "Greedy" + # General attributes + name = "" + alignment = "Neutral" # Hit points hp_max = None + # Base stats (ability scores) strength = Ability() dexterity = Ability() @@ -16,46 +18,96 @@ class Agent: intelligence = Ability() wisdom = Ability() charisma = Ability() + + # Numerical things armor_class = ArmorClass() initiative = Initiative() speed = Speed() + # Proficiencies and Languages + _saving_throw_proficiencies = tuple() # use to overwrite class proficiencies + other_weapon_proficiencies = tuple() # add to class/race proficiencies + skill_proficiencies = list() + skill_expertise = list() languages = "" + # Skills + acrobatics = Skill(ability="dexterity") + animal_handling = Skill(ability="wisdom") + arcana = Skill(ability="intelligence") + athletics = Skill(ability="strength") + deception = Skill(ability="charisma") + history = Skill(ability="intelligence") + insight = Skill(ability="wisdom") + intimidation = Skill(ability="charisma") + investigation = Skill(ability="intelligence") + medicine = Skill(ability="wisdom") + nature = Skill(ability="intelligence") + perception = Skill(ability="wisdom") + performance = Skill(ability="charisma") + persuasion = Skill(ability="charisma") + religion = Skill(ability="intelligence") + sleight_of_hand = Skill(ability="dexterity") + stealth = Skill(ability="dexterity") + survival = Skill(ability="wisdom") + + + # Inventory + cp = 0 + sp = 0 + ep = 0 + gp = 0 + pp = 0 + equipment = "" + weapons = list() + magic_items = list() + armor = None + shield = None + + # Magic + spellcasting_ability = None + _spells = list() + _spells_prepared = list() + infusions = list() + + # Features IN MAJOR DEVELOPMENT + custom_features = list() + feature_choices = list() + def __init__(self): pass @property def actions(self): """All the things I can do in a turn""" - raise NotImplementedError() + return [] @property def free_actions(self): """Stuff I can do as much as I want in a turn""" - raise NotImplementedError() + return [] @property def movement(self): """Where I can go in a turn""" - raise NotImplementedError() + return [] @property def bonus_actions(self): """Things I can do once in addition to an action""" - raise NotImplementedError() + return [] @property def reactions(self): """Things I can do in response to an action""" - raise NotImplementedError() + return [] @property def lair_actions(self): """Things I can do at initiative count 20""" - raise NotImplementedError() + return [] @property def legendary_actions(self): """Things I can do so many times in a turn after another agent acts""" - raise NotImplementedError() \ No newline at end of file + return [] \ No newline at end of file diff --git a/dungeonsheets/character.py b/dungeonsheets/character.py index b999664..3c91f21 100644 --- a/dungeonsheets/character.py +++ b/dungeonsheets/character.py @@ -149,54 +149,17 @@ def _resolve_mechanic(mechanic, module, SuperClass, warning_message=None): class Character(Agent): """A generic player character.""" - # General attirubtes - name = "" player_name = "" - alignment = "Neutral" + dungeonsheets_version = __version__ + xp = 0 + inspiration = False + attacks_and_spellcasting = "" class_list = list() _race = None _background = None - xp = 0 - # Hit points - hp_max = None - # Base stats (ability scores) - strength = Ability() - dexterity = Ability() - constitution = Ability() - intelligence = Ability() - wisdom = Ability() - charisma = Ability() - armor_class = ArmorClass() - initiative = Initiative() - speed = Speed() - inspiration = False - _saving_throw_proficiencies = tuple() # use to overwrite class proficiencies - other_weapon_proficiencies = tuple() # add to class/race proficiencies - skill_proficiencies = list() - skill_expertise = list() - languages = "" - # Skills - acrobatics = Skill(ability="dexterity") - animal_handling = Skill(ability="wisdom") - arcana = Skill(ability="intelligence") - athletics = Skill(ability="strength") - deception = Skill(ability="charisma") - history = Skill(ability="intelligence") - insight = Skill(ability="wisdom") - intimidation = Skill(ability="charisma") - investigation = Skill(ability="intelligence") - medicine = Skill(ability="wisdom") - nature = Skill(ability="intelligence") - perception = Skill(ability="wisdom") - performance = Skill(ability="charisma") - persuasion = Skill(ability="charisma") - religion = Skill(ability="intelligence") - sleight_of_hand = Skill(ability="dexterity") - stealth = Skill(ability="dexterity") - survival = Skill(ability="wisdom") + # Characteristics - attacks_and_spellcasting = "" personality_traits = ( "TODO: Describe how your character behaves, interacts with others" ) @@ -204,26 +167,8 @@ class Character(Agent): bonds = "TODO: Describe your character's commitments or ongoing quests." flaws = "TODO: Describe your character's interesting flaws." features_and_traits = "Describe any other features and abilities." - # Inventory - cp = 0 - sp = 0 - ep = 0 - gp = 0 - pp = 0 - equipment = "" - weapons = list() - magic_items = list() - armor = None - shield = None + _proficiencies_text = list() - # Magic - spellcasting_ability = None - _spells = list() - _spells_prepared = list() - infusions = list() - # Features IN MAJOR DEVELOPMENT - custom_features = list() - feature_choices = list() def __init__( self, diff --git a/dungeonsheets/encounter/__init__.py b/dungeonsheets/encounter/__init__.py index e69de29..2433ab5 100644 --- a/dungeonsheets/encounter/__init__.py +++ b/dungeonsheets/encounter/__init__.py @@ -0,0 +1 @@ +from dungeonsheets.encounter.encounter import Encounter \ No newline at end of file diff --git a/dungeonsheets/encounter/encounter.py b/dungeonsheets/encounter/encounter.py index 8d46bbe..e9ba29a 100644 --- a/dungeonsheets/encounter/encounter.py +++ b/dungeonsheets/encounter/encounter.py @@ -7,6 +7,7 @@ class Encounter: if len(parties) is not 2: raise NotImplementedError("Haven't implemented AI for 3+ groups") # TODO: Implement this + # Combine all parties into a single group self.all_agents = parties[0] for party in parties[1:]: self.all_agents += party diff --git a/dungeonsheets/stats.py b/dungeonsheets/stats.py index 8555ff4..7b570bb 100644 --- a/dungeonsheets/stats.py +++ b/dungeonsheets/stats.py @@ -240,3 +240,23 @@ class Initiative(NumericalInitiative): if has_advantage: ini += "(A)" return ini + + +########################### +# STATUS +########################### + +class CurrentHP: + """A Numerical Representation of Current HP""" + + def __get__(self, char, Character): + if not char.hp_max: + char.__set_hp_max() + return char.hp_max + + +class CurrentInitiative(NumericalInitiative): + """A Numerical Representation of a Character's Rolled Initiative""" + + def __get__(self, char, Character): + ini, has_advantage = super(CurrentInitiative, self).__get__(char, Character) \ No newline at end of file diff --git a/dungeonsheets/utils.py b/dungeonsheets/utils.py new file mode 100644 index 0000000..a8a73fb --- /dev/null +++ b/dungeonsheets/utils.py @@ -0,0 +1,6 @@ +import random + + +def roll(d, n=1): + """roll(6, 2) means roll 2d6""" + return sum([random.randint(1, d) for _ in range(n)]) \ No newline at end of file diff --git a/tests/test_encounter.py b/tests/test_encounter.py index 817145e..24fa6b9 100644 --- a/tests/test_encounter.py +++ b/tests/test_encounter.py @@ -3,17 +3,20 @@ from unittest import TestCase from dungeonsheets.character import Character +from dungeonsheets.encounter import Encounter +from dungeonsheets.monsters import Monster +from dungeonsheets.stats import Ability class TestEncounter(TestCase): """Tests for features and feature-related activities.""" - def test_simulation(): + def test_simulation(self): """Can I run an encounter against Schlangdedrosa Magentawrath?""" char = Character() char.set_attrs(name="Stravajiaxen") - char.set_attrs(weapons=["shortsword"]) - char.set_attrs(armor="leather armor", shield="shield") + 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") @@ -63,4 +66,5 @@ class TestEncounter(TestCase): schlang = SchlangdedrosaMagentawrath() - battle = Encounter([]) \ No newline at end of file + battle = Encounter([char], [schlang]) + results = battle.simulate() \ No newline at end of file