From 1629ca74602fa72430c33fbe137cccb8a35ae029 Mon Sep 17 00:00:00 2001 From: Ben Cook Date: Wed, 19 Dec 2018 11:49:31 -0500 Subject: [PATCH] v0.7.2: multiclass character now function, with correct spell slots. Need to add MulticlassProficiencies --- VERSION | 2 +- dungeonsheets/character.py | 23 +++++++++++++++-------- dungeonsheets/classes.py | 15 +++++++++++++-- dungeonsheets/make_sheets.py | 32 +++++++++++++++++--------------- examples/druid.pdf | Bin 395104 -> 395101 bytes examples/multiclass.pdf | Bin 312048 -> 312047 bytes examples/multiclass_2.pdf | Bin 498570 -> 419119 bytes examples/multiclass_2.py | 12 ++++++------ examples/rogue.pdf | Bin 134855 -> 134855 bytes examples/warlock.pdf | Bin 304061 -> 304061 bytes examples/wizard.pdf | Bin 311992 -> 311993 bytes 11 files changed, 52 insertions(+), 32 deletions(-) diff --git a/VERSION b/VERSION index 7deb86f..d5cc44d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.7.1 \ No newline at end of file +0.7.2 \ No newline at end of file diff --git a/dungeonsheets/character.py b/dungeonsheets/character.py index 6d600bb..d6db77a 100644 --- a/dungeonsheets/character.py +++ b/dungeonsheets/character.py @@ -108,6 +108,7 @@ class Character(): spellcasting_ability = None spells = tuple() spells_prepared = tuple() + # MISC def __init__(self, **attrs): """Takes a bunch of attrs and passes them to ``set_attrs``""" @@ -120,14 +121,6 @@ class Character(): 'race': race, 'background': background}) self.set_attrs(**attrs) - for c in self.class_list: - if isinstance(c, classes.Druid): - ws = self.wild_shapes - c.wild_shapes = ws - c.circle = self.circle - self.all_wild_shapes = c.all_wild_shapes - self.wild_shapes = c.wild_shapes - self.can_assume_shape = c.can_assume_shape # instantiate any spells not listed properly for S in self.spells_prepared: if S not in [type(spl) for spl in self.spells]: @@ -233,6 +226,20 @@ class Character(): self.wear_armor(val) elif attr == 'shield': self.wield_shield(val) + elif attr == 'wild_shapes': + for c in self.class_list: + if isinstance(c, classes.Druid): + c.wild_shapes = val + self.all_wild_shapes = c.all_wild_shapes + self.wild_shapes = c.wild_shapes + self.can_assume_shape = c.can_assume_shape + break + elif attr == 'circle': + for c in self.class_list: + if isinstance(c, classes.Druid) and (c.circle == ''): + c.circle = val + self.circle = val + break elif (attr == 'spells') or (attr == 'spells_prepared'): # Create a list of actual spell objects _spells = [] diff --git a/dungeonsheets/classes.py b/dungeonsheets/classes.py index f56d863..e736536 100644 --- a/dungeonsheets/classes.py +++ b/dungeonsheets/classes.py @@ -145,7 +145,7 @@ class Cleric(CharClass): class Druid(CharClass): class_name = 'Druid' - circle = "" # Moon, land + circle = "" # moon, land _wild_shapes = () hit_dice_faces = 8 saving_throw_proficiencies = ('intelligence', 'wisdom') @@ -185,7 +185,18 @@ class Druid(CharClass): 19: (4, 4, 3, 3, 3, 3, 2, 1, 1, 1), 20: (4, 4, 3, 3, 3, 3, 2, 2, 1, 1), } - + + def __init__(self, level, subclass=None, **params): + if subclass is not None: + sc = str(subclass).lower() + if 'moon' in sc: + self.circle = 'moon' + params.pop('circle', '') + elif 'land' in sc: + self.circle = 'land' + params.pop('circle', '') + super().__init__(level, **params) + @property def all_wild_shapes(self): """Return all wild shapes, regardless of validity.""" diff --git a/dungeonsheets/make_sheets.py b/dungeonsheets/make_sheets.py index 64417f9..2ba6060 100644 --- a/dungeonsheets/make_sheets.py +++ b/dungeonsheets/make_sheets.py @@ -107,14 +107,21 @@ def create_latex_pdf(char, basename, template): raise exceptions.LatexError(f'Processing of {basename}.tex failed.') -def create_spells_pdf(char, spell_class, basename, flatten=False): - class_level = (spell_class.class_name + ' ' + str(spell_class.class_level)) +def create_spells_pdf(char, basename, flatten=False): + class_level = ' / '.join([c.class_name + ' ' + str(c.class_level) + for c in char.spellcasting_classes]) + abilities = ' / '.join([c.spellcasting_ability.upper()[:3] + for c in char.spellcasting_classes]) + DCs = ' / '.join([str(char.spell_save_dc(c)) + for c in char.spellcasting_classes]) + bonuses = ' / '.join([mod_str(char.spell_attack_bonus(c)) + for c in char.spellcasting_classes]) spell_level = lambda x : (x or '') fields = { 'Spellcasting Class 2': class_level, - 'SpellcastingAbility 2': spell_class.spellcasting_ability.upper()[:3], - 'SpellSaveDC 2': char.spell_save_dc(spell_class), - 'SpellAtkBonus 2': mod_str(char.spell_attack_bonus(spell_class)), + 'SpellcastingAbility 2': abilities, + 'SpellSaveDC 2': DCs, + 'SpellAtkBonus 2': bonuses, # Number of spell slots 'SlotsTotal 19': spell_level(char.spell_slots(1)), 'SlotsTotal 20': spell_level(char.spell_slots(2)), @@ -428,17 +435,12 @@ def make_sheet(character_file, char=None, flatten=False): char_pdf = create_character_pdf(char=char, basename=char_base, flatten=flatten) pages.append(char_pdf) - for spell_class in char.spellcasting_classes: - # Create spell sheet (one for each class) - # Even though each sheet will include same spells, - # this will list all modifiers - spell_base = '{:s}_{:s}_spells'.format( - os.path.splitext(character_file)[0], - spell_class.class_name) - create_spells_pdf(char=char, spell_class=spell_class, - basename=spell_base, flatten=flatten) - sheets.append(spell_base + '.pdf') if char.is_spellcaster: + # Create spell sheet + spell_base = '{:s}_spells'.format( + os.path.splitext(character_file)[0]) + create_spells_pdf(char=char, basename=spell_base, flatten=flatten) + sheets.append(spell_base + '.pdf') # Create spell book spellbook_base = os.path.splitext(character_file)[0] + '_spellbook' try: diff --git a/examples/druid.pdf b/examples/druid.pdf index 776422aecbf9ee61f34e9bca9eb273c9a0a0010d..a0e5bb68dfce078af593c41c093405437db3870c 100644 GIT binary patch delta 4571 zcmZu!duY~W6lTs(X)2f(S~nY;MqaY_{+_psrqBW@#Fdq1N!zzYPDg@W$mo|hmX(Ho z)Q6%>!9Sw3NJ}e%ps+v*68uB4#KfG^O+~N_tLOXn?c2U{8Vts}^SejyZ?zwAUKT`Yl!pSXnEPChY z@&~Ryw6y#DpHB>5yY$d6$L8+sTzPoWM}Pfr>di@SExFqA!Mxp19=dYpDmxUa`vVxC-47l+=OSQuA4CJw#RO{HUHuKp5LGTX6yF%^V9cqAN;##=d*U~ zxRys=x_!fIG_G;vmNoNktnD4!+-zy{s@~B**Y2M<@#SwvO*GxdPS-!a?74&gP|KX= z6H7+4%sKJK!Xz{DzzV{d(s2yI(2H$`2jieQ9+Keuv<<7QaLHUs|1`uAFw{R6$?JHI@Hda3Qy? z#uP4J$lX=r_S=iOGqstI4XXIl(A7{^`XeQqNSs9*s?Rixqdark3A^YOKhrAp-OVbF zwbIVAU~m?r<(G|4!p`7DVds(&XH=a?rj%CJ1kVjEJc~0QL?)J!xa+JI!8l_zf6qmg zi3nYg5V|BY_SOnydaGZ=VOjf|JQxNc*V)wA1jk1n80SG}P zf{r!50sV)c3JHz2f!E3CD9B|1D@Vo{8+jteM9tgNSmi4|vOd+*#@fVT#e4m2G7z9s zLMx2ZNd)7p67Tt_IjM8T*`x|1F6NrD6s_m~H_DyUT2eDY;#5++j?>#tGO(_r5 z<=rS$+h?AHeW?!5l5sUz2tMF4Ckp!3iBWP`kd;kud^RGT!l^$wU&t*i4CmM%IXy zCM#=99;(B$^GXOH*%(DI-uHDF@~^-Tp(NglQ0?m70pdr&M{bv_79BxpFw@Iu1){;F zE8?#yNe#f*vmENAj93YhRf03AOs>J)N|uCpCTD;@gD^n^I9$n5d375=D|rkme%E^; zG|9saw+sD(1RnPf!xYeq!jOcTC9EPP@odaY(%1#6?-(MiXY34HtC;W!M3Z(>Q4>K; z*n1d7MzJ|&(1DI2Vlc-zN(Q?R=b5oC@)2Wjnd=bjuom_QQ=Vfm1atcj`*Z^n#;3tV z0~c^P@y!l)mThOS^WZpp&j<8AJIk=UTc&IV>M3A#PH_dq_MLdS4HTbmaj?VWV~#PU zERt(QQWgH7?#A&5L(p8d4F+UMdI#SPAqo@->u4$t>Bi{>De=z3nb0nrY3E9JG7RF# zl^Z>XnpP)+#e@X1kQ4rC13S+f$s~+T#!Xw?yZDZU%ZVckLp#8wKH6A(5OB_+OFUor zaF_Tx0y{G>g38>qMvJcmtS#UeL&2c^8I>$XByS#z4T~>##o55CY{5-z=FEx5tYQ>F zFsKx>3&s%BEI0{#Q?Td>&UM(8_+Q0M)E#?)a8mgo>(@YR{(+0H1=aaCT2aeG=;J2D z4xi=hZE&3L?Z^@wF5S5ScPv+e;u)F3m&1llnXRElkiC#^>mZx*9eLfVuxb0JTJx=W x$m@)|DW7lCkzC&A+id7aZNar$oo`PaF0b27dtvJEVbiXOsczDw`{p*+{Rd=*(s2L) delta 4547 zcmZu!ZD`eH6lczDw2Dd;G>n#OI?d{Nf6jxNVQ+#Ta)HxW8gp)9nIal#hA%iOHKR}vTQ46hqkdQKz4M;ag$tMGp65B|{Lb(Bo%4LZ zcI>IOV^?mk*!;o>(z(OSE9$cuO<#5HRySVi|JcuNs@uM0`$LVRYNqUXWb>krrVgBW z?XRXM`+mK+@V=H4cN}_e>AtoVgO6?NZaLFC?&a>G1$WLplso$SjGjG{#?K$qeErsz zWd|2D&vCb$dvxB+w@$Pk{OObK?tAO!?y5O?wt3FJn;xI|^-X&>ys_z}H4P(Q+%xCM z`P}}C*|JkT*XgF?d%L>&Cfs~}^o8+_4fRhg960{%>ebKPwtLgKHG^YmW7n6BlUMfq zSuwq@@!zu>dV4RJ{Ri&vm^u0I>!;U^X<7cv+n+!E&b*DCBj#6b7<{(l+^Sno)OLT+ z-0|b=(>E;rVg12ZK3jD6mLvVGTfSNK&(T?zI+hL`_-_2Pt|#jHPmb&TaL3MLpN@L} z-R@%pzYK2uq9$CrcIJfc=U2SCK8@}h>Z!nY1iqE{j@&uaQ$?Ls$|)CecMVn57k)Mm zRlQl^bAJp~O{<7I)o)clS7t%gsr;v|v#$2?kCdF!VlCQKzNTRu<(kt`*hO#onpWw` z-mK(UEA1Q$25T_}zS$UrdpXu(&{`R-jaYNZi!~}wBvVQ&YXWgYt4TPqK8Q>#C9&68 zBZ6_pI_|?om5B&lkP!NOfmp`gT7irYk(ExXfI9KL!P$acHVk2~PGlEIi>O01!f`}F zxs&K+B9VN#T?Y8+f9grziA;zj7n0Ee!Q>_3QZgI`kS6$yMV-fsABfyM&lq$|yvABb zesf@^oH&m{DVVHq?X>oYh6iIT3CE5CFNroJop@3rK=M=$zsle^Sz(y0fM2H|;78#! z=ZsO-F(&{ah(rwVr#jrfJhzJ|7;OWulL4&aK)}k8F+htaVocQhdK#;I$wziY^|Y}z zaafIw#cMJgphGIGOvV8lv1XMx&qu>aU1gk2Hn;BYs)NBiKM@J{N8cQKTeD=)B!u#-7OX)(1POrHMS(SA!wc z6be|nxY&%Lr#wf4_QmlriZo{!#>2=v3!G@KK(O%?ISi)*MnO$!k3iI{3&b3%g*8b_)yB1L|%Zk1zzy z1=~=hqUaXyg$W@F6bMtO0mE*eiu=Yi3*#R&i@||u)WzJkO36vwI-?n)m_wk}{0J*v zGO+Xf>KIIDT+?lS%qpl^iIdozIHE9gj6+bAU^&;UNuKv|>?J;czz(8bmPm$2l@^Zz z3@RA9%M4+M3t!aWLM0)2;?h{FG@s?r4MaPJ4;>BTBn(YrP{Yu2{@Gv*F_psJz~6$f zL*OhCkD?UUikw8<74JIOTzY>M`De)nF1I#dhAfi2hzw!YOF30tJ!!J|D~bn_B?5DE zD`7r{sU#k*mV9nkb@h~4?MVlf+B;&KYFiwAds_&tzQZr>X!T3*%iJ?Pxwa+7ElI7^ jPVJ@*lcWWHm}hjW?!eHVYpkiBdJUP{hK2_oez5jG%vaDk diff --git a/examples/multiclass.pdf b/examples/multiclass.pdf index 0090d16312a53c746101c77d180a2a14b908b682..b7cb5a30471d799b2bb111e91113985d24325892 100644 GIT binary patch delta 4451 zcmZu!U1-*26z^@XeJroqFfoXz(qsRNtrP&8g zp1Eh=?#1-L^scsr8wc+GcFWqCFKT>0mV zTh0!3ubS3z*YgYa9UgkSZT{+un+8tII8WzJbZwZk=EwzmOn1+myY=xmzkKJDp|!tk z%jo25pLJfiB8!_=e6)Z%tXW;`i}?uNYnR*dxt_{?$)D^+ciP)z|5|%}dtj@N*@8 znhq{mpFb3*XqT)i=7#g_m0xcj&hN^F;@EKhj$As}v^PJyDO1#@O8?sW+nOhSp`g7M zHkYIyZs&echa_xXIbln#d^Wo*aMHfOowDXBU4L>r%=1r`i zkX7rhOAlsn!G>nwK|GO2CfG@A$wYoOMB4zr$^d`VhSeQ5JcS>QiT4NmB8k@}BcV<@ zie!=xD&s*?BJpCfx-n}cO~#7SfjT@HG>sJxA@bGU$||(erGoMcQFzNsQi6-uU27AC zpAM7wk!L7mIBP`hv{aC}?K_P-MuM;5;vr36XeXnurdm zoy{hO4*J(c-XJC>KAhl3R=hYVnKZc|?n|0CwNk|k!};qoqa3JKORAic)jIK5b`qx9 zq(z%J5Qz7ugU<2$95m8$5;$^#RbF|=Tf!S3I7?A1&mZoSlnkFj{cM#4KA|fZ3LeeP zv-V`EUcxe3p5)N;5JY)4*4bAfQ07VYm?xyok_pjGk_-vCkElK`C(a7y;yMeo+8Z<| zV9xO7POkXfp?qsbk<%l&ka(IAkntiU#22@s2I4+%1!gHKnur0m*0`FYToe)%kSCK8 zb`ORl2B{brDS5%^lp42|l3M6QN{b)_nczXl3(?1L6-!3KPR84qu#)lnuzY1gDoIhP zf(->E@J!l*<{d#0WDb96tnP~VY4A?$Oe0}(or)M46HH;Hf&a7_yLAS z1YsjS<&3hXs^xR4-4CPCKG;YV&){<>vq}d(&avefURt9anvdt;u?;XA_7c9*x15Bw9!L?{VA8=yEyy7zK9K;6;d z?84|B7e%bM!SSTAbBVx|Y|zEC!}*(Tx0uS2ok8zKzDvNCe5{@cR-W+~$c;JT?hwmy zW>^)l-15I;dZgm=k^C)7bOE~Rg751o=$^1z7y5c2`h`>oCV>=Y(E{An*W>%Nk39u^ h=tYbFdNEddy$bfB-oE1Dk^H=Cd~-*~(&b&v{{zdmwBi5& delta 4453 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 bTu?rL!J_$_qU<8RA&oPlf)a=< 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 O+bP+>>{|yFru+||2`qyE diff --git a/examples/multiclass_2.py b/examples/multiclass_2.py index 94fa274..3d72797 100644 --- a/examples/multiclass_2.py +++ b/examples/multiclass_2.py @@ -12,7 +12,7 @@ name = 'Inara Serradon' # multiclass example classes_levels = ['wizard 3', 'druid 2'] # 4th level total subclasses = ['Necromancer', 'moon'] -circle = 'moon' +circle = 'land' player_name = 'Mark' background = "Acolyte" @@ -56,18 +56,18 @@ equipment = ( wild_shapes = ["wolf", "crocodile", "giant eagle", 'ape', 'ankylosaurus'] -druid_spells_prepared = ('shillelagh', 'poison spray', 'druidcraft', - 'speak with animals', 'entangle', 'cure wounds', - 'create or destroy water') +__druid_spells_prepared = ('shillelagh', 'poison spray', 'druidcraft', + 'speak with animals', 'entangle', 'cure wounds', + 'create or destroy water') # List of known spells spells = ('blindness deafness', 'burning hands', 'detect magic', 'false life', 'mage armor', 'mage hand', 'magic missile', 'prestidigitation', 'ray of frost', 'ray of sickness', 'shield', - 'shocking grasp', 'sleep',) + druid_spells_prepared + 'shocking grasp', 'sleep',) + __druid_spells_prepared # Which spells have been prepared (not including cantrips) spells_prepared = ('blindness deafness', 'false life', 'mage armor', - 'ray of sickness', 'shield', 'sleep',) + druid_spells_prepared + 'ray of sickness', 'shield', 'sleep',) + __druid_spells_prepared # Backstory personality_traits = """I use polysyllabic words that convey the impression of diff --git a/examples/rogue.pdf b/examples/rogue.pdf index 9a0a3a7d8a4be35a509fd5d56750e2f89a00f05a..4ae5269a253f946b148d4db949acb9dab1d695b3 100644 GIT binary patch delta 335 zcmV-V0kHnZoe0OB2!ON!K6QUBkU>wwFbswN%Dc6bri^Z)D;zgX+F?i_B5@9Fng*qD z=7bggJqaMo2fxquv%HaCI6NJ3#a)i3y%#N-Z6_XfV2wBUtQs67HfQZ_89|O{cB0!u zUa&>ebYkB^4yd1*M%!EMbH>M&{6PIW5vRBi4{?o2`C(O|?wMkIrzKiTz2cyK(p*I( zA{W=CAvpDIy(zTJIcuf_#WV3Qj&=@CW6>&*FPyyj_b8ZEu$r@;CaZ5cR)3pCVI?oh zn@?rRiMcw`Jd-cSxzT0QteqrYaLPaV0as5~7L$=V6t^pO0g#LZF*G|5DL1+ll-OC~73cJmA9fR07L$=V6t^pO0g#LZFf=eUIG4Zz0wV=5 zG%z$cx99=_XbVC!Ff%t}GdMRjVmLD~W@R>IGcz(~GB-FkWMw!sW;8cGJY``rW@KbJ hWH&H1W-((nGcjagVmLW8Ibk$1WH>oyFqe`J0yS28jD-LI diff --git a/examples/warlock.pdf b/examples/warlock.pdf index 9f6e3397eb82c989227b16cccc5649fec1df2400..0f0e6f51a40873bbc64b1cb1444c1f888d09d461 100644 GIT binary patch delta 112 zcmdmcTxjocp@tU57N!>FEi4oJSq)7rOiZRv>t|7hFt_jPXXy}jN-|5dG*2}#F-L^ Mv$UMvv6#ga0P?LOoB#j- delta 112 zcmdmcTxjocp@tU57N!>FEi4oJSq)4KObw<_>t|7hFt_jPXXy}jGEOs3Gcig_OEpb2 zHcm7#Oii>fGD%6YG)*(MG%+wVva>NaF-tQwF*8XvH84v}G&V^wFfcbaF*Y?zGq*HK MGfte|v6#ga0LDon8vpWySG2vmZ2 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 YCsVG-ciYxe#eFxs<{2{{T=G!!f9utl`Tzg`