- 6r@csdZdkZdkZdkZdZ dfdYZJdfdYZvdfdYZd fd YZd fd YZ d fdYZ dfdYZ dfdYZ dfdYZ dS(s( Basic classes for the DBM army editor. Ncs5|djo d| Sn  d|SdS(s$Dump a year number in calendar form.is%d BCEs%d CEN(sn(sn((slistclasses.pysyearssArmycs tZdZJedZPedZVdZ`dZfdZdZ dZ d Z d Z RS( Nc st|_|oNxDtiD]-}||ijo||_Pnq&Wtn||_|i o |ii o|ii dd|_n||_ |i tjo|io~ xt|ii D ]c\}}!|tjo"d|_ #Pn4$||ijo %|i i ||_ &PnqWn!'|ii o(d|_ nn,|ii|fg|_-|ii|_.x|D.]} /x|iiD/]} 0| i| jo1xtiD1]}2|i| ijou3td|i4dt5d| i6dh7d|} 8t| _9| | _:|ii| | f<PnqW?|ii| tfnqWqWG||_It|_dS(Nisdbmtypeserasvariants active_alliessparts(sNonesselfsdbmtypesArmysarmylists army_typesnames NameErrorsvariantsvariantsserasvalueserassindexs active_alliessbasenamesactive_ally_namesalliesspotential_allysarmytypespartsssubarmysTruesalliedsappendsFalse( sselfsdbmtypesvariantseras active_alliesspartssarmytypesvalues army_typespotential_allysactive_ally_namessubarmy((slistclasses.pys__init__s\                   % cslJK|tjoL|i}nM|ddjoN|d }nOt|ii||dSdS(Nis=s0(sbasesNonesselfsbasenamesnamesintspartssget(sselfsnamesbase((slistclasses.pysgetJs cspPQ|tjoR|i}nS|ddjo!T|d |i||}nU||i||Zscs\ti|S(N(sressearchsstrsx(sx(sstr(slistclasses.pys\scs ]d|jS(Ns=(sx(sx((slistclasses.pys]scs:_iiddi|iddidjS(Ns:isenabled(sselfsdbmtypesmapsjoinsxssplitsenabled(sx(sself(slistclasses.pys_sN( stypesstrsreducesoperatorsconcatsmapsfiltersselfspartsskeyssraw(sselfsstrsraw((sselfsstrslistclasses.pysselectVs !csB`ab| o cdSn#ettitd|SdS(s0Return the total count of a specified select seticseti|dS(Ns(sintsselfsgetsx(sx(sself(slistclasses.pysesN(ssetsreducesoperatorsaddsmap(sselfsset((sselfslistclasses.pyssum`s  c sfghg}ixq|iiDi]`}j|id|i}kt|i i |d}lt |i t djo5m|o'n|i||||i|fnnrt|i tosx{|i i Ds]j}t|d|i}u|id|} v| o2w|i|| ||id|i|fnqWn7{t|i to||oY}|i |d}~x;|i i D~]!}|i|joPnqWtn|i||||i|fnt|i toxz|i i D]i}|d|i}t|i i |d} | o'|i|| | |i|fnqWnt|i to|o|i i d}|i|d|i||i||i|fx|i i dD]q}|d|i}t|i i |d} | o/|i|| || ||i|fnqWnnqW|SdS(s;Return order of battle of units with nonzero count in army.s:s0sis=iN(s unit_listsselfsdbmtypesitemssitemsbasenamesnamesouterkeysintspartssgets outercountstypesunitsappendscosts isinstancesGroupspartsinnerkeysranges innercounts Alternativespartnames NameErrorsSelectsPosseschief( sselfsouterkeys outercountsinnerkeys unit_listsitemschiefspartspartnames innercount((slistclasses.pysorder_of_battlefsV   +  :    '  / 5  ?csJt|iitijo|ii|Sn|iiSdS(N(stypesselfsdbmtypesrequired_terrainstypess LambdaType(sself((slistclasses.pysrequired_terrainscsJt|iitijo|ii|Sn|iiSdS(N(stypesselfsdbmtypesoptional_terrainstypess LambdaType(sself((slistclasses.pysoptional_terrainscsSxC|iiD]2}t|itdjpt|ito#|i|i |i |nt|it o|i|i |i |xY|ii D]H}|i|djo)|i|i |i|i d<PnqWn@t|itot}xM|ii D]<}|itj o#|i|i tt}nq;W|o qn|i |}x-|ii D]}|i|i dqWd}x|djoxto|ii |t|ii }|d7}|i|i d}|i|djo2|i o'|itjp||i|djo+|i|i ||d8}PnqWqWnvt|ito_|i|i |i |x6|ii D]%}|i|i |i |qWnqWdS(sBSet defaults for this individual army; it must have an era member.ssenableds=iiN( sselfsdbmtypesitemssitemstypesunits isinstancesGroupssetspathsdefaults AlternativespartsspartsenabledsnamesbasenamesSelectsFalsesdefaults_forceds forcedefaultsNonesTruescountsjslensgetsnewvaluesfollowssrangesallowedsPosse(sselfscountsdefaults_forcedsjsitemspartsnewvalue((slistclasses.pyscompute_defaultssT 2# !       # N  csag} g}|iiot|idjoVxL|iiD]+td|i oPnqNW| i dng}g}h}d}x|iD]\}}|iio9|ii|\}}| |7} ||7}nxJ|iiD]9}|i|djo q-n|i|} |ip|ioE|i|id| ||i<|io|d7}nn|i|}t|itdjp#t|itpt|it oj|i|djo  q-n | |djp| |djo |i |i|i!nn t|it"o d}x|ii$D]}|i|djo qn|i|} |ip|ioB|i|id| ||<|io|d7}nn| o)|i'o|i(|i)|i'djo|i ||i!n|| 7}qW||djp||djoex[|ii$D]J}|i|djo |i|o|i ||i!nqWnn,t|it*o | o!|ii$d}"d}#x|ii$dD#]}$|i|djo %qn&|i|} '|i|} (| | djp| | djo(*|i ||i!+|| 7}nqW,|o|i|t o-|i dnnnq-WqW.|os/||7}0t|djo/1| i d |d|i|dfn3| i d d i-|n4|oS5t|djo6| i d |dn8| i d d i-|n:d};xd|iD;]V\}}<|i|d}=|djo>| i d|n@||7}qaWB|djoC| i dnD||i1i2joE| i d|i1i2nF|i1d o|o |djoG| i dnH| |fSdS(sValidate an army list.ics|djS(Ni(sxsclique(sx(sclique(slistclasses.pysss%Some of your allies are incompatible.isenabledissFollowers need a chief.s%s is out of range at %s.sFields %s are out of range.s, s#Unit %s needs the proper commander.s Units %s need proper commanders.s)%s troops must have at least one general.is)No army may have more than four generals.s"At least %d generals must be used.s mix_generalss;Subgenerals and ally-generals cannot be mixed in this army.N(3serrorssfieldssselfsdbmtypes ally_cliquesslens active_alliesscliquesfiltersappends outofranges subordinatessgeneral_countss ally_generalssnamessubarmysvalidatespsqsitemssitemsenabledscountsgenerals ally_generalsgetsbasenamesallowedstypesunits isinstancesGroups AlternativespathsSelectstotalspartssparts partcountsfollowsssumsselectsPosseschiefs partallowedsjoinstotal_generalssallynames partialcountsflagss min_generals(sselfsallynames subordinatess ally_generalss partialcountstotal_generalsspartsallowedssubarmys partalloweds partcountscountscliqueserrorssnamespsfieldss outofrangesqsitemschiefsgeneral_countsstotal((scliqueslistclasses.pysvalidates  &          # E %"     6% )'    %$  /! !  &( s__name__s __module__s__init__sNonesgetssetsselectssumsorder_of_battlesrequired_terrainsoptional_terrainscompute_defaultssvalidate(((slistclasses.pysArmy s  <  :   :sArmyTypecs_JtZdZKLhdd<edpsspartscsri|S(N(sselfstraversesfuncsx(sx(sselfsfunc(slistclasses.pysrs( stopnodesNonesselfsfuncs isinstancesArmyTypesmapsitemsshasattrsunitsparts(sselfsfuncstopnode((sselfsfuncslistclasses.pystraverseks   csstd|idSdS(Ns[s](sselfsname(sself((slistclasses.pys__repr__ss( s__name__s __module__s__doc__sTruesNones__init__salliance_lookupstraverses__repr__(((slistclasses.pysArmyTypeJs $ sPeriodcsSvtZdZwxegdZ~dZdZdZeZRS(sRepresent a date range.csQxy||_z||_{||_||itjo}|i|_ndS(N(searliestsselfslatests transitionssNone(sselfsearliestslatests transitions((slistclasses.pys__init__xs    csl~|i|ijp|i|ijo tSn2tt|i|it|i|iSdS(N(sselfslatestsothersearliestsNonesPeriodsmaxsmin(sselfsother((slistclasses.pys intersects~s) cs'||ijo ||ijSdS(N(stsselfsearliestslatest(sselfst((slistclasses.pys __contains__scsR|i|ijot|iSn"t|idt|iSdS(Ns-(sselfsearliestslatestsyear(sself((slistclasses.pys__str__s( s__name__s __module__s__doc__sNones__init__s intersectss __contains__s__str__s__repr__(((slistclasses.pysPeriodvs    sItemc stZdZedeeeeeeeeeed ZdZdZdZdZ dZ dZ d Z d Z RS( sA purchase group.ics||_||_t|itdjo|i|if|_n||_||_||_||_||_ |i ot ||_ n||_ | |_ | |_ | |_| |_| |_dS(Ni(snamesselfsrangestypescostsunitsdefaults forcedefaultscarriessperiodsPeriodsvariantssforce_optionalsfollowssgenerals ally_generals exportable(sselfsnamesrangescostsunitsdefaultscarriessperiodsvariantssforce_optionalsfollowssgenerals ally_generals exportable((slistclasses.pys__init__s"             csMt|ito|id}n |i}|i|SdS(Ns=(s isinstancesselfsunits Alternativespathsunamesarmysget(sselfsarmysuname((slistclasses.pyscounts cs|iio(|io|ii|ii|i o dSn|io|i|ij o dSn|i o|i |i djo dSn|i o,t |i i to|i i|djo dSndSdS(s>Is specified item enabled for inclusion in the specified army?sdatesvariantis subordinatespossesenabledN(sselfs army_typeserassperiodsarmyseras intersectssvariantssvariantsfollowssgetsparents isinstancesunitsPossescount(sselfsarmy((slistclasses.pysenableds; ! & < csD|ip-t|itfjo|iddjSdS(sIs this an optional unit type?.iN(sselfsforce_optionalstypesrange(sself((slistclasses.pysoptionalscst|itijo|i|}n3|itjoddf}n |i}|i p|i o |SnS|i o|i oddfSn'|ddt |dddfSdS(s/Compute the allowed range of counts for a unit.iiiiN( stypesselfsrangestypess FunctionTypesarmysallowedsNonesallieds exportablesoptionalsgeneralsmax(sselfsarmysallowed((slistclasses.pysalloweds  cs|itj o|iSn|i|d}|io7|io dSn|io dSnn|SdS(s.Return a suitable default count for this item.iiN( sselfs forcedefaultsNonesallowedsarmyslowestsalliedsoptionalsgeneral(sselfsarmyslowest((slistclasses.pysdefaults   csg}|io|it|in|io |idi|in| o|idndi|SdS(s/Report conditions under which this is availables or s-s; N(s conditionssselfsperiodsappendsstrsvariantssjoin(sselfs conditions((slistclasses.pys conditionss     cs|i|}|d|djo|d }nd|}t|itijo|d7}n|SdS(Niis%d-%ds*(sselfsallowedsarmysrangesrepstypestypess FunctionType(sselfsarmysrangesrep((slistclasses.pys range_reports cs?|i}|io|d|i7}n|SdS(Ns
[%s](sselfsunitsrepscarries(sselfsrep((slistclasses.pys unit_displays  (s__name__s __module__s__doc__sNonesFalses__init__scountsenabledsoptionalsallowedsdefaults conditionss range_reports unit_display(((slistclasses.pysItems0    sSelectcs tZdZdZRS(s,Express 'choose subunits from alternatives'.cs||_dS(N(spartssself(sselfsparts((slistclasses.pys__init__s(s__name__s __module__s__doc__s__init__(((slistclasses.pysSelectss Alternativecs tZdZdZRS(s)Express 'choose block from alternatives'.cs||_dS(N(spartssself(sselfsparts((slistclasses.pys__init__s(s__name__s __module__s__doc__s__init__(((slistclasses.pys AlternativessGroupcs tZdZdZRS(sExpress 'choose all'.cs||_dS(N(spartssself(sselfsparts((slistclasses.pys__init__s(s__name__s __module__s__doc__s__init__(((slistclasses.pysGroupssPossecs tZdZdZRS(sBLike Select, but first (chieftain) unit must be present if any arecs||_dS(N(spartssself(sselfsparts((slistclasses.pys__init__s(s__name__s __module__s__doc__s__init__(((slistclasses.pysPossessAlliancecs,tZeeedZdZRS(Ncs ||_ ||_ ||_ |tjo t|_nPt|tdjot||_nt|d|d|_||_dS(Nii( snamesselfsdbmtypesvariantsperiodsNonestypesPeriodsvariants(sselfsnamesdbmtypesvariantsperiodsvariants((slistclasses.pys__init__s   cs{|i}|io"|dt|id7}n|io%|ddi|id7}n|SdS(Ns (s)s [s, s](sselfsnamesrepsperiodsreprsvariantssjoin(sselfsrep((slistclasses.pys__repr__s   " %(s__name__s __module__sNones__init__s__repr__(((slistclasses.pysAlliances  (s__doc__stypessoperatorsresyearsArmysArmyTypesPeriodsItemsSelects AlternativesGroupsPossesAlliance( sArmyTypesGroupsItemsArmysPeriodsresAlliancestypessyearsoperators AlternativesPossesSelect((slistclasses.pys?s  >,f