class Quiver(Item, Holster): name: str = 'quiver' char: str = ']' material: str = 'leather' size: Size = Size(80, 10, 10) weight: int = 900 slot_type: str = (BODY_SLOT.ON_SHOULDER, ) slots: Tuple[HolsterSlot] = (HolsterSlot(ITEM_SLOT.ARROW, 20, 6000, Size(90, 10, 10)), )
def cb(scr): root_layout = RootLayout(dim=Dim(w, h), border=0, logger=Logger(__file__), scr=scr, curses=curses) game = GameModel(create_peep('human', name='Super Dad')) game.player.body.wear(clothes.cloak(size=Size(1.1, 1.1, 1.1), thick=1.0)) game.player.body.wear(armor.helm(size=Size(1.15, 1.1, 1.1), thick=1.0)) # game.player.body.wear(armor.shield(size=Size(1.4, 1.1, 1.0), thick=1.1)) game.player.body.wear(weapons.sword(size=Size(1.0, 1.0, 1.0))) game.goto_level(1, placement='<') main(root_layout, game)
def create_dragon(height, weight): height *= 2 weight *= 20 slot_definitions = ( # Upper Bodywear ('head', ( 'cover', # dragon helm (like horse helm) 'on', # crown - only over supple materials like cloth/flexible leather )), ('neck', ('around',)), # huge necklass, collar, belt as collar... ('body',( 'cover', # dragon armor - cover all except bottom/under-side 'under', # under-armor/plate/shield 'on', # saddle, pack )), # Hands / Arms ('l_arm', ('around',)), # huge bracelet, band, belt as band ('r_arm', ('around',)), ('l_leg', ('around',)), # huge bracelet, band, belt as band ('r_leg', ('around',)), ) parts = [] for name, slotnames in slot_definitions: bslots = list(BodySlot(slotname) for slotname in slotnames) parts.append(BodyPart(name, slots=bslots)) ret = Body('dragon', Size(height, int(height/4), int(height/10)), weight, list(parts)) update_dragon_proportions(ret, (90, 70, 180)) return ret
def belt(size=Size(1.0, 1.0, 1.0), thick=1.0, pos=(0,0), **params): ret = Belt(**params) ret.size = size.copy(0.01, 0.2, 0.15) ret.thick = thick * 0.5 / 175 ret.weigth = 0.2/65 ret.pos = pos return ret
class Arrow(Item): name = 'arrow' char = '-' material = 'wood' size = Size(90, 2, 2) # cm (about 3 ft) weight = 100 # grams slot_type = ITEM_SLOT.ARROW
def shield(size=Size(1.0, 1.0, 1.0), thick=1.0, **params): ret = Shield(**params) ret.size = AVERAGE_SHIELD_SIZE.copy(size.h, size.w, size.d) ret.thick = thick * AVERAGE_SHIELD_THICK vol = ret.size.h * ret.size.w * ret.thick # todo: factor in curvature of shield (d) avol = AVERAGE_SHIELD_SIZE.h * AVERAGE_SHIELD_SIZE.w * AVERAGE_SHIELD_THICK ret.weight = AVERAGE_SHIELD_WEIGHT * (vol / avol) return ret
def sword(size=Size(1.0, 1.0, 1.0), **params): ret = Sword(**params) ret.size = size.copy(*AVERAGE_SWORD_SIZE.as_tuple()) vol = ret.size.volume() avol = AVERAGE_SWORD_SIZE.volume() ret.weight = AVERAGE_SWORD_WEIGHT * (vol / avol) return ret
def helm(size=Size(1.0, 1.0, 1.0), thick=1.0, **params): ret = Helm(**params) ret.size = size.copy(*AVERAGE_HELM_SIZE.as_tuple()) ret.thick = AVERAGE_HELM_THICK * thick vol = ret.thick * ret.size.cover_area() avol = AVERAGE_HELM_THICK * AVERAGE_HELM_SIZE.cover_area() ret.weight = AVERAGE_HELM_WEIGHT * (vol / avol) return ret
def update_dragon_proportions(body, head): dratio = DotDict({ # 'Name': (height, width, depth) in proportion to head 'head': (1.00, 1.00, 1.00), 'neck': (0.90, 0.90, 1.50), 'body': (2.50, 1.25, 5.00), 'tail_base': (1.20, 1.20, 1.40), 'tail_mid': (0.90, 0.90, 1.30), 'tail_tip': (0.60, 0.60, 1.20), 'l_arm': (3.75, 0.90, 0.90), 'r_arm': (3.75, 0.90, 0.90), 'l_leg': (3.75, 0.90, 0.90), 'r_leg': (3.75, 0.90, 0.90), }) for part in body.parts: ratio = dratio[part.name] part.size = Size(ratio[0] * head[0], ratio[1] * head[1], ratio[2] * head[2])
'%%%...............%%%', '%%%%.............%%%%', '%%%%%...........%%%%%', '%%%%%%.........%%%%%%', '%%%%%%%.......%%%%%%%', '%%%%%%%%.....%%%%%%%%', '%%%%%%%%%...%%%%%%%%%', '%%%%%%%%%%>%%%%%%%%%%', '%%%%%%%%%%%%%%%%%%%%%', ], 'peeps': [ create_peep('big bird', name='Steve', pos=(10, 18)), ], 'items': [ weapons.sword(name="sword_of_justice", size=Size(1.2, 1.1, 1.0), pos=(10, 3)), armor.shield(name="shield_of_justice", size=Size(1.1, 1.1, 1.1), pos=(11, 3)), Item("bow_of_justice", '}', Size(3, 5, 4), 10, '', pos=(9, 3)), armor.helm(name="helm_of_justice", size=Size(1.1, 1.1, 1.1), pos=(10, 4)), Item("chestplate_of_justice", '+', Size(3, 5, 4), 10, '', pos=(11, 4)), armor.boots(name="boots_of_justice",
def boots(size=Size(1.0, 1.0, 1.0), thick=1.0, **params): # average human head height is 2/15 of total height or 0.133 units ret = Boots(**params) ret.size = size.copy(0.090, 0.060, 0.167) ret.thick = thick return ret
# width=1.0, (shoulder width and head size) # depth=1.0, (fatness) # # These three measures make up the body-type of a humanoid. Implied with that body type are different proportions, # so a very tall measure will infer a relatively smaller head because of the shoulder-to-height ratio. # This is to make construction of all equipment for a body-type more convenenient. # Armor fit for a tall thin sodier could be created: # armor.jacket(1.2, 1.0, 0.8) - a long thin jacket (normal shoulder width) # armor.boots(1.2, 1.0, 0.8) - boots fitting a long and narrow foot. # armor.helm(1.2, 1.0, 0.8) - a helm fitting a tall thin person # # So a Titan of human proportions could be expressed: # 2.0, 2.0, 2.0 AVERAGE_HELM_SIZE = Size( 0.133, 0.10, 0.09) # average human head height is 2/15 of total height or 0.133 units AVERAGE_HELM_THICK = 0.5 / 175 AVERAGE_HELM_WEIGHT = 3 / 65 @dataclass class Helm(Item): name: str = 'helm' char: str = '^' fit_info: FitInfo = FitInfo('cover', 'fitted', 'head') def helm(size=Size(1.0, 1.0, 1.0), thick=1.0, **params): ret = Helm(**params) ret.size = size.copy(*AVERAGE_HELM_SIZE.as_tuple())
def create_humanoid(height, weight, body2head=7.5): # body proportions in a straight standing position # average male height in cm: Dunadain: 180, Human: 175, Dwarf: 135, Hobbit: 105 part_sizes = ( # height in proportion to overall height, (width, depth) in proportion to height ('body', 1.000, (0.240, 0.08)), # overall body proportions with 0.240 biacromial (between shoulderblades) # standing proportions ('head', 0.133, (0.6, 0.8)), # for 7.5 body-to-head ratio ('neck', 0.025, (3.0, 3.0)), # contribution to overall height. actual neck length is about 50% more ('torso', 0.305, (0.787, 0.190)), # torso/back ('waist', 0.030, (9.0, 5.0)), ('legs', 0.470, (0.26, 0.26)), # waist-to-ankle ('foot', 0.037, (1.0, 2.0)), # ankle-to-heal # heights add up to 1 # armspan components (in proportion to height) ('arm', 0.265, (0.125, 0.125)), # shoulder-to-wrist ('wrist', 0.020, (2.5, 1.0)), # wrist ('hand', 0.115, (0.8, 0.1)), # wrist-to-fingertips ('back', 0.305, (0.787, 0.0)), # 2-dimensional back of torso (hxw) ) finger_sizes = ( ('index', .043, (0.2, 0.2)), ('middle', .047, (0.2, 0.2)), ('ring', .043, (0.2, 0.2)), ('pinky', .036, (0.2, 0.2)), ) # store parts by name with labels to define side (left/right) and detail (index finger) symmetrical = {'foot', 'arm', 'wrist', 'hand'} parts_by_name = {} for name, h, (w_fac, d_fac), in part_sizes: size = Size(h, h*w_fac, h*d_fac) if name in symmetrical: parts = ( BodyPart(name, size, ('left', 'subdom')), BodyPart(name, size, ('right', 'dom')), # right dominant ) else: parts = (BodyPart(name, size),) parts_by_name[name] = parts fingers = [] for side in ('left', 'right'): for name, h, (w_fac, d_fac), in finger_sizes: size = Size(h, h*w_fac, h*d_fac) fingers.append(BodyPart('finger', size, (side, name))) parts_by_name['finger'] = tuple(fingers) # worn items are 'cover' slots that support 1-2 layers wear_info = ( ('body', 'cover', ('loose',), 1), # 1: cloak, cape, ... ('head', 'cover', ('fitted',), 2), # 1: hood, padded cap, ... 2: helmet, crown, hat, ... ('torso', 'cover', ('fitted',), 2), # 1: jerkin, chainmail; 2: plate, cuirass, chest plate... ('arm', 'cover', ('fitted',), 1), # 1: bracers ('hand', 'cover', ('fitted',), 1 ), # 1 glove, gauntlet, OR rings ('legs', 'cover', ('fitted',), 2), # 1: breeches, pants, leather-leggings, cargo-pants, ... # 2: leg guards, samurai armor, poleyn, chausses (chain), plate, ('foot', 'cover', ('fitted',), 2), # 1: wool-socks, .. 2: boots, sandles, shoes, slippers, ... ) carry = ( ('back', 'strap', ('strap',), 2), # strap over shoulder: backpack, shield, quiver, sack... ('hand', 'held', ('held',), 1), # shield, weapon, bag, wand, staff, any item, ... ) accessorize = ( # loose necklass, amulet, neck scarf, ... # tight collar/protector or necklass with clasp ('neck', 'around', ('loose', 'fitted-clasp'), 1), # clapsed or tied tight: belt, sash, scabbard, knife-belt, dart-belt, ... ('waist', 'around', ('fitted-clasp',), 1), # loose bracelets that slip over the hand and tight bracelets with clasps ('wrist', 'around', ('loose', 'fitted-clasp'), 1), # fitted rings ('index', 'middle', 'ring', 'pinky') ('finger', 'around', ('fitted',), 1), ) for slot_defs in (wear_info, carry, accessorize): for part_name, wear_type, fit, max_count in slot_defs: for part in parts_by_name[part_name]: part.slots.append(BodySlot(wear_type, max_count, fit)) return Body('humanoid', Size(height, height/4, height/8), weight, parts_by_name)
from dataclasses import dataclass from lib.items.item import Item, FitInfo from lib.model import register_yaml, Size AVERAGE_CLOAK_SIZE = Size(0.8, 1.05, 1.05) AVERAGE_CLOAK_THICK = 0.3 / 175 AVERAGE_CLOAK_WEIGHT = 1 / 65 @dataclass class Cloak(Item): name: str = 'cloak' char: str = '(' fit_info: FitInfo = FitInfo('cover', 'loose', 'body') def cloak(h=1.0, w=1.0, d=1.0, thick=1.0, **params): # average human body dimensions (h,w,d) are 1.0 x 0.25 x 0.125 ret = Cloak(**params) ret.size = AVERAGE_CLOAK_SIZE.copy(h, w, d) ret.thick = thick * AVERAGE_CLOAK_THICK vol = ret.thick * ret.size.cover_area() avol = AVERAGE_CLOAK_THICK * AVERAGE_CLOAK_SIZE.cover_area() ret.weight = AVERAGE_CLOAK_WEIGHT * (vol/avol) return ret @dataclass class Belt(Item): name: str = 'belt' char: str = '_' fit_info: FitInfo = FitInfo('around', 'fitted-clasp', 'waist')
from dataclasses import dataclass from lib.model import Size from lib.items.item import Item, FitInfo AVERAGE_SWORD_SIZE = Size(0.4, .02, .0025) AVERAGE_SWORD_WEIGHT = 3 / 65 @dataclass class Sword(Item): name: str = 'sword' char: str = '/' fit_info: FitInfo = FitInfo('held', 'held', 'hand', ('dom', )) # depth is the thickness of the sword. def sword(size=Size(1.0, 1.0, 1.0), **params): ret = Sword(**params) ret.size = size.copy(*AVERAGE_SWORD_SIZE.as_tuple()) vol = ret.size.volume() avol = AVERAGE_SWORD_SIZE.volume() ret.weight = AVERAGE_SWORD_WEIGHT * (vol / avol) return ret