mirror of
https://github.com/Threnklyn/dungeon-sheets.git
synced 2026-05-20 04:53:27 +02:00
updated create-character to include weapons and armor
This commit is contained in:
+18
-13
@@ -55,7 +55,7 @@ class Armor():
|
||||
dexterity_mod_max = None
|
||||
strength_required = None
|
||||
stealth_disadvantage = False
|
||||
weight = 0 # In lbs
|
||||
weight = 0 # In lbs
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
@@ -65,23 +65,23 @@ class Armor():
|
||||
|
||||
|
||||
class NoArmor(Armor):
|
||||
name = "No armor"
|
||||
name = "No Armor"
|
||||
|
||||
|
||||
class LightArmor(Armor):
|
||||
name = "Generic Light Armor"
|
||||
name = "Light Armor"
|
||||
|
||||
|
||||
class MediumArmor(Armor):
|
||||
name = "Generic Medium Armor"
|
||||
name = "Medium Armor"
|
||||
|
||||
|
||||
class HeavyArmor(Armor):
|
||||
name = "Generic Heavy Armor"
|
||||
name = "Heavy Armor"
|
||||
|
||||
|
||||
class PaddedArmor(LightArmor):
|
||||
name = "Padded armor"
|
||||
name = "Padded Armor"
|
||||
cost = "5 gp"
|
||||
base_armor_class = 11
|
||||
weight = 8
|
||||
@@ -89,21 +89,21 @@ class PaddedArmor(LightArmor):
|
||||
|
||||
|
||||
class LeatherArmor(LightArmor):
|
||||
name = "Leather armor"
|
||||
name = "Leather Armor"
|
||||
cost = "10 gp"
|
||||
base_armor_class = 11
|
||||
weight = 10
|
||||
|
||||
|
||||
class StuddedArmor(LightArmor):
|
||||
name = "Studded leather armor"
|
||||
class StuddedLeatherArmor(LightArmor):
|
||||
name = "Studded Leather Armor"
|
||||
cost = "45 gp"
|
||||
base_armor_class = 12
|
||||
weight = 13
|
||||
|
||||
|
||||
class HideArmor(MediumArmor):
|
||||
name = "Hide armor"
|
||||
name = "Hide Armor"
|
||||
cost = "10 gp"
|
||||
base_armor_class = 12
|
||||
dexterity_mod_max = 2
|
||||
@@ -111,7 +111,7 @@ class HideArmor(MediumArmor):
|
||||
|
||||
|
||||
class ChainShirt(MediumArmor):
|
||||
name = "Chain shirt"
|
||||
name = "Chain Shirt"
|
||||
cost = "50 gp"
|
||||
base_armor_class = 13
|
||||
dexterity_mod_max = 2
|
||||
@@ -119,7 +119,7 @@ class ChainShirt(MediumArmor):
|
||||
|
||||
|
||||
class ScaleMail(MediumArmor):
|
||||
name = "Scale mail"
|
||||
name = "Scale Mail"
|
||||
cost = "50 gp"
|
||||
base_armor_class = 14
|
||||
dexterity_mod_max = 2
|
||||
@@ -145,7 +145,7 @@ class HalfPlate(MediumArmor):
|
||||
|
||||
|
||||
class RingMail(HeavyArmor):
|
||||
name = "Ring mail"
|
||||
name = "Ring Mail"
|
||||
cost = "30 gp"
|
||||
base_armor_class = 14
|
||||
dexterity_mod_max = 0
|
||||
@@ -191,3 +191,8 @@ class ElvenChain(MediumArmor):
|
||||
dexerity_mod_max = 2
|
||||
weight = 20
|
||||
|
||||
|
||||
light_armors = [PaddedArmor, LeatherArmor, StuddedLeatherArmor]
|
||||
medium_armors = [HideArmor, ChainShirt, ScaleMail, Breastplate, HalfPlate]
|
||||
heavy_armors = [RingMail, ChainMail, SplintArmor, PlateMail]
|
||||
all_armors = light_armors + medium_armors + heavy_armors
|
||||
|
||||
@@ -720,7 +720,6 @@ class Character():
|
||||
make_sheet(filename, character=self,
|
||||
flatten=kwargs.get('flatten', True))
|
||||
|
||||
|
||||
|
||||
def read_character_file(filename):
|
||||
"""Create a character object from the given definition file.
|
||||
|
||||
@@ -14,7 +14,8 @@ import subprocess
|
||||
import npyscreen
|
||||
import jinja2
|
||||
|
||||
from dungeonsheets import character, race, dice, background, classes
|
||||
from dungeonsheets import (character, race, dice, background, classes, weapons,
|
||||
armor)
|
||||
|
||||
|
||||
def read_version():
|
||||
@@ -29,6 +30,9 @@ races = {r.name: r for r in race.available_races}
|
||||
|
||||
backgrounds = {b.name: b for b in background.available_backgrounds}
|
||||
|
||||
all_weapons = (weapons.simple_melee_weapons + weapons.martial_melee_weapons +
|
||||
weapons.simple_ranged_weapons + weapons.martial_ranged_weapons)
|
||||
|
||||
|
||||
class LinkedListForm(npyscreen.ActionForm):
|
||||
prev_page = None
|
||||
@@ -85,7 +89,7 @@ class App(npyscreen.NPSAppManaged):
|
||||
# Create the PDF character sheet
|
||||
if self.getForm('SAVE').make_pdf.value:
|
||||
log.debug("Creating PDF")
|
||||
self.character.to_pdf(filename, template_file='empty_template.txt')
|
||||
self.character.to_pdf(filename)
|
||||
subprocess.call(['makesheets', filename])
|
||||
|
||||
def update_max_hp(self):
|
||||
@@ -122,11 +126,15 @@ class App(npyscreen.NPSAppManaged):
|
||||
name="Choose ability scores:", formid='ABILITIES')
|
||||
self.addForm("SKILLS", SkillForm, name="Choose skill proficiencies",
|
||||
formid='SKILLS')
|
||||
self.addForm("WEAPONS", WeaponForm, name="Choose weapons",
|
||||
formid='WEAPONS')
|
||||
self.addForm("ARMOR", ArmorForm, name="Choose armor",
|
||||
formid='ARMOR')
|
||||
self.addForm("SAVE", SaveForm, name="Save character:", formid='SAVE')
|
||||
|
||||
# Initialized the DoublyLinkedList
|
||||
forms = ['MAIN', 'RACE', 'CLASS1', 'BACKGROUND',
|
||||
'ALIGNMENT', 'ABILITIES', 'SKILLS', 'SAVE']
|
||||
forms = ['MAIN', 'RACE', 'CLASS1', 'BACKGROUND', 'ALIGNMENT',
|
||||
'ABILITIES', 'SKILLS', 'WEAPONS', 'ARMOR', 'SAVE']
|
||||
for i in range(len(forms)-1):
|
||||
form = self.getForm(forms[i])
|
||||
form.add_next(forms[i+1])
|
||||
@@ -522,6 +530,7 @@ class SkillForm(LinkedListForm):
|
||||
race_skills = tuple(self.parentApp.character.race.skill_proficiencies)
|
||||
all_skills = new_skills + bg_skills + race_skills
|
||||
self.parentApp.character.skill_proficiencies = all_skills
|
||||
self.parentApp.getForm('WEAPONS').update_options()
|
||||
log.debug(f"Skill proficiencies: {all_skills}")
|
||||
super().to_next()
|
||||
|
||||
@@ -529,6 +538,85 @@ class SkillForm(LinkedListForm):
|
||||
super().to_prev()
|
||||
|
||||
|
||||
class WeaponForm(LinkedListForm):
|
||||
def create(self):
|
||||
self.instructions = self.add(
|
||||
npyscreen.FixedText, editbale=False,
|
||||
value=("Please select your weapons."))
|
||||
self.remaining = self.add(
|
||||
npyscreen.TitleText, name="Remaining:",
|
||||
value=3, editable=False)
|
||||
self.weapons = self.add(
|
||||
npyscreen.TitleMultiSelect, name="Weapons:",
|
||||
values=tuple([wpn.name for wpn in all_weapons]),
|
||||
value_changed_callback=self.update_remaining)
|
||||
|
||||
def on_ok(self):
|
||||
new_weapons = self.weapons.get_selected_objects()
|
||||
if new_weapons is not None:
|
||||
new_weapons = tuple(s.lower() for s in new_weapons)
|
||||
else:
|
||||
new_weapons = ()
|
||||
for wpn in new_weapons:
|
||||
self.parentApp.character.wield_weapon(wpn)
|
||||
log.debug(f"Weapons wielded: {new_weapons}")
|
||||
super().to_next()
|
||||
|
||||
def update_remaining(self, widget=None):
|
||||
num_choices = 3
|
||||
num_selected = len(self.weapons.value)
|
||||
remaining = num_choices - num_selected
|
||||
log.debug(f'Remaining: {remaining}')
|
||||
self.remaining.value = str(remaining)
|
||||
self.display()
|
||||
|
||||
def update_options(self):
|
||||
available_weapons = []
|
||||
for wpn in all_weapons:
|
||||
if self.parentApp.character.is_proficient(wpn()):
|
||||
available_weapons.append(wpn.name)
|
||||
self.weapons.values = available_weapons
|
||||
self.parentApp.getForm('ARMOR').update_options()
|
||||
self.display()
|
||||
|
||||
def on_cancel(self):
|
||||
super().to_prev()
|
||||
|
||||
|
||||
class ArmorForm(LinkedListForm):
|
||||
def create(self):
|
||||
self.instructions = self.add(
|
||||
npyscreen.FixedText, editbale=False,
|
||||
value=("Please select your armor."))
|
||||
self.shield = self.add(npyscreen.Checkbox, name="Shield? ",
|
||||
value=False)
|
||||
self.armor = self.add(
|
||||
npyscreen.TitleSelectOne, name="Armor:",
|
||||
values=tuple([a.name for a in armor.all_armors]))
|
||||
|
||||
def on_ok(self):
|
||||
my_armor = self.armor.get_selected_objects()[0]
|
||||
if my_armor.lower() is not "no armor":
|
||||
self.parentApp.character.wear_armor(my_armor)
|
||||
if self.shield.value:
|
||||
self.parentApp.character.wield_shield('shield')
|
||||
super().to_next()
|
||||
|
||||
def update_options(self):
|
||||
available_armors = [armor.NoArmor]
|
||||
if 'light armor' in self.parentApp.character.proficiencies_text.lower():
|
||||
available_armors.extend(armor.light_armors)
|
||||
if 'medium armor' in self.parentApp.character.proficiencies_text.lower():
|
||||
available_armors.extend(armor.medium_armors)
|
||||
if 'heavy armor' in self.parentApp.character.proficiencies_text.lower():
|
||||
available_armors.extend(armor.heavy_armors)
|
||||
self.armor.values = [a.name for a in available_armors]
|
||||
self.display()
|
||||
|
||||
def on_cancel(self):
|
||||
super().to_prev()
|
||||
|
||||
|
||||
class SaveForm(LinkedListForm):
|
||||
def create(self):
|
||||
self.instructions = self.add(
|
||||
@@ -540,6 +628,7 @@ class SaveForm(LinkedListForm):
|
||||
npyscreen.TitleText, name='Filename:')
|
||||
self.make_pdf = self.add(npyscreen.Checkbox, name="Create PDF:",
|
||||
value=True)
|
||||
|
||||
def on_ok(self):
|
||||
super().to_next()
|
||||
|
||||
|
||||
@@ -69,10 +69,10 @@ gp = 0
|
||||
pp = 0
|
||||
|
||||
# TODO: Put your equipped weapons and armor here
|
||||
weapons = () # Example: ('shortsword', 'longsword')
|
||||
weapons = {{ char.weapons }} # Example: ('shortsword', 'longsword')
|
||||
magic_items = () # Example: ('ring of protection',)
|
||||
armor = "" # Eg "leather armor"
|
||||
shield = "" # Eg "shield"
|
||||
armor = "{{ char.armor }}" # Eg "leather armor"
|
||||
shield = "{{ char.shield }}" # Eg "shield"
|
||||
|
||||
equipment = """TODO: list the equipment and magic items your character carries"""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user