Exemplo n.º 1
0
def damage_roll(pc, power, attack_type=None):
    melee_weapon = pc.get_melee_weapon(equipped=False)
    ranged_weapon = pc.get_ranged_weapon(equipped=False)
    implement = pc.get_equipped_implement()

    if attack_type is None:
        attack_type = power.attack_types[0]

    damage_modifier = power.damage_modifier
    if damage_modifier == abilities.dexterity and \
            power == powers.ranged_basic_attack and \
            attack_type == powers.ranged_weapon and \
            ranged_weapon is not None and \
            ranged_weapon.range_type == weapons.melee_range_type and \
            weapons.heavy_thrown_property in ranged_weapon.properties:
        damage_modifier = abilities.strength
    if isinstance(damage_modifier, dict):
        damage_modifier = damage_modifier[attack_type]

    weapon = melee_weapon
    weapon = ranged_weapon if attack_type.range_type in (
        powers.ranged_range_type, powers.area_range_type
    ) else weapon

    value = ''
    damage_multiplier = power.damage_multiplier(pc)
    if keywords.weapon in power.keywords and power.damage_dice == dice.weapon:
        if weapon is None:
            return None
        damage_multiplier *= weapon.damage_multiplier
    if damage_multiplier > 0:
        value = str(damage_multiplier)

    if keywords.weapon in power.keywords and power.damage_dice == dice.weapon:
        if weapon is None:
            return None
        damage_dice = weapon.damage_dice
        if pc.dnd_class == classes.rogue and weapon == weapons.shuriken:
            damage_dice = dice.larger_dice(damage_dice)
        value += str(damage_dice)

    if power.damage_dice is not None and power.damage_dice != dice.weapon:
        value += str(power.damage_dice)

    if power.bonus_damage_dice is not None:
        for d in power.bonus_damage_dice:
            value += ' + ' + str(power.bonus_damage_dice[d](pc)) + str(d)

    mod_value = 0
    if damage_modifier is not None:
        if isinstance(damage_modifier, tuple):
            for mod in damage_modifier:
                mod_value += calc.mod(pc.ability_value(mod))
        else:
            mod_value += calc.mod(pc.ability_value(damage_modifier))

    if keywords.weapon in power.keywords:
        if weapon is not None:
            if weapon.magical_bonus > 0:
                mod_value += weapon.magical_bonus

    # feat bonus
    feat_bonus = 0
    for feat in pc.known_feats:
        if isinstance(feat, feats.WeaponFocus) and pc.check_feat(feat):
            weapon = pc.get_melee_weapon(equipped=False)
            if attack_type == powers.ranged_weapon:
                weapon = pc.get_ranged_weapon(equipped=False)
            if feat.weapon_group in weapon.weapon_groups:
                feat_bonus = max(feat_bonus, (pc.level + 9) // 10)
        if feat == feats.goliath_greatweapon_prowess and pc.check_feat(feat):
            weapon = pc.get_melee_weapon(equipped=False)
            if weapon.category in (weapons.simple_weapon_category, weapons.military_weapon_category) and \
                    weapon.hands == 2:
                feat_bonus = max(feat_bonus, 1 + (pc.level + 9) // 10)
        if feat == feats.dwarven_weapon_training and pc.check_feat(feat):
            weapon = pc.get_melee_weapon(equipped=False)
            if weapons.axe_group in weapon.weapon_groups or weapons.hammer_group in weapon.weapon_groups:
                feat_bonus = max(feat_bonus, 2)
    if pc.check_feat(feats.astral_fire):
        if keywords.fire in power.keywords or keywords.radiant in power.keywords:
            feat_bonus = max(feat_bonus, (pc.level + 9) // 10)
    if pc.check_feat(feats.raging_storm):
        if keywords.lightning in power.keywords or keywords.thunder in power.keywords:
            feat_bonus = max(feat_bonus, (pc.level + 9) // 10)

    mod_value += feat_bonus

    if keywords.implement in power.keywords and implement is not None:
        if pc.is_proficient_in(implement):
            mod_value += implement.magical_bonus

    # other bonuses
    if pc.check_feat(feats.hellfire_blood) and (keywords.fire in power.keywords or keywords.fear in power.keywords):
        mod_value += 1

    if mod_value > 0 and len(value) > 0:
        value += ' + ' + str(mod_value)
    return value
Exemplo n.º 2
0
def print_pc_info(pc):
    print("=======================================")
    print()
    print(" *** " + pc.name)
    print()
    print("{:<19s}{:s}".format("раса:", str(pc.race)))
    print("{:<19s}{:s}".format("класс:", str(pc.dnd_class)))
    print("{:<19s}{:s}".format("уровень:", str(pc.level)))
    print("{:<19s}{:s}".format("xp:", str(pc.xp)))
    print()
    print("{:<19s}{:s}".format("пол:", str(pc.gender)))
    print("{:<19s}{:s}".format("возраст:", str(pc.age)))
    print("{:<19s}{:s}".format("рост:", str(pc.height)))
    print("{:<19s}{:s}".format("вес:", str(pc.weight)))
    print("{:<19s}{:s}".format("мировоззрение:", str(pc.alignment)))
    print("{:<19s}{:s}".format("божество:", str(pc.god)))
    print()
    print("{:<19s}{:s}".format("скорость:", str(pc.speed_value())))
    print("{:<19s}{:s}".format("инициатива:", str(pc.initiative_value())))
    print("{:<19s}{:s}".format("хитпоинты:", str(pc.max_hitpoints_value())))
    print("{:<19s}{:s}".format("раненый:", str(pc.bloodied_value())))
    print("{:<19s}{:s}".format("исцеление на:", str(pc.healing_surge_value())))
    print("{:<19s}{:s}".format("исцелений в день:", str(pc.healing_surges_number_value())))
    print("{:<19s}{:s}".format("языки:", str(pc.languages)))
    print("{:<19s}{:s}".format("черты:", str(pc.known_feats)))
    print()
    print("инвентарь: {")
    total_worth = 0
    total_weight = 0
    for money in lists.list_money():
        if money in pc.equipment:
            total_worth += money.price * pc.equipment[money]
            total_weight += money.weight * pc.equipment[money]
            print("    {:s}: {:d}".format(str(money), pc.equipment[money]))
    print()
    for item in sorted(pc.equipment):
        if not isinstance(item, items.Money):
            if isinstance(item, common.Priceable):
                if item.price >= 0:
                    total_worth += item.price * pc.equipment[item]
                total_weight += item.weight * pc.equipment[item]
            print("    {:s}: {:d}".format(str(item), pc.equipment[item]))
    print("}")
    print("надето: {")
    for part in sorted(characters.body_parts):
        if pc.equipped_items[part]:
            print(
                "    "
                + str(part)
                + ": "
                + str(pc.equipped_items[part])
                + " ("
                + ("есть опыт" if pc.is_proficient_in(pc.equipped_items[part]) else "нет опыта")
                + ")"
            )
    print("}")
    print()
    print("оружие наготове:")

    if pc.get_melee_weapon(equipped=True) is not None:
        print("{:<19s}{:s}".format("рукопашное:", str(pc.get_melee_weapon(equipped=True))))
    elif pc.get_melee_weapon(equipped=False) is not None:
        print("{:<19s}{:s}".format("рукопашное:", str(pc.get_melee_weapon(equipped=False)) + " (не экипировано)"))
    else:
        print("{:<19s}{:s}".format("рукопашное:", "None"))

    if pc.get_ranged_weapon(equipped=True) is not None:
        print("{:<19s}{:s}".format("дальнобойное:", str(pc.get_ranged_weapon(equipped=True))))
    elif pc.get_ranged_weapon(equipped=False) is not None:
        print("{:<19s}{:s}".format("дальнобойное:", str(pc.get_ranged_weapon(equipped=False)) + " (не экипировано)"))
    else:
        print("{:<19s}{:s}".format("дальнобойное:", "None"))

    print("{:<19s}{:s}".format("инструмент:", str(pc.get_equipped_implement())))
    print()
    print("общая ценность инвентаря: " + "{:.2f}".format(total_worth))
    print("общий вес инвентаря: " + "{:.2f}".format(total_weight))

    print()
    for ability in lists.list_abilities():
        print(
            "{:14s} {:>4d} {:>+4d}".format(ability.name, pc.ability_value(ability), calc.mod(pc.ability_value(ability)))
        )
    print()
    for defence in lists.list_defences():
        print("{:14s} {:>4d}".format(defence.name, pc.defence_value(defence)))
    print()
    for skill in lists.list_skills():
        print(
            "{:<16s} {:>2d}{:<s}".format(
                skill.name, pc.skill_value(skill), " (тренирован)" if skill in pc.trained_skills else ""
            )
        )
    print()
    print("таланты (" + str(powers.at_will_frequency) + "):")
    for power in pc.get_at_will_powers():
        print_power_info(power, pc)
    print()
    print("таланты (" + str(powers.encounter_frequency) + "):")
    for power in pc.get_encounter_powers():
        print_power_info(power, pc)
    print()
    print("таланты (" + str(powers.daily_frequency) + "):")
    for power in pc.get_daily_powers():
        print_power_info(power, pc)
    print()
Exemplo n.º 3
0
def attack_roll(pc, power, attack_type=None):
    if power.ability is None:
        return None

    melee_weapon = pc.get_melee_weapon(equipped=False)
    ranged_weapon = pc.get_ranged_weapon(equipped=False)
    implement = pc.get_equipped_implement()

    if attack_type is None:
        attack_type = power.attack_types[0]

    ability = power.ability
    if ability == abilities.dexterity and \
            power == powers.ranged_basic_attack and \
            attack_type == powers.ranged_weapon and \
            ranged_weapon is not None and \
            ranged_weapon.range_type == weapons.melee_range_type and \
            weapons.heavy_thrown_property in ranged_weapon.properties:
        ability = abilities.strength
    if isinstance(ability, dict):
        ability = ability[attack_type]

    value = pc.level // 2 + calc.mod(pc.ability_value(ability))
    if power.ability_modifier:
        value += power.ability_modifier(pc)

    weapon = melee_weapon
    weapon = ranged_weapon if attack_type.range_type in (
        powers.ranged_range_type, powers.area_range_type
    ) else weapon

    if keywords.weapon in power.keywords:
        if weapon is None:
            return None
        if pc.is_proficient_in(weapon):
            value += weapon.proficiency_bonus
        if pc.dnd_class == classes.fighter and pc.fighter_weapon_talent_type == weapon.hands:
            value += 1
        if pc.dnd_class == classes.rogue and weapon == weapons.dagger:
            value += 1
        if weapon.magical_bonus > 0:
            value += weapon.magical_bonus

    if keywords.implement in power.keywords and implement is not None:
        if pc.is_proficient_in(implement):
            value += implement.magical_bonus

    # feat bonus
    feat_bonus = 0
    for feat in pc.known_feats:
        if isinstance(feat, feats.WeaponExpertise) and pc.check_feat(feat):
            weapon = pc.get_melee_weapon(equipped=False)
            if attack_type == powers.ranged_weapon:
                weapon = pc.get_ranged_weapon(equipped=False)
            if feat.weapon_group in weapon.weapon_groups:
                feat_bonus = max(feat_bonus, 1 if pc.level < 11 else (2 if pc.level < 21 else 3))
        if isinstance(feat, feats.ImplementExpertise):
            if keywords.implement in power.keywords and implement is not None \
                    and isinstance(implement, feat.implement_type.__class__):
                feat_bonus = max(feat_bonus, 1 if pc.level < 11 else (2 if pc.level < 21 else 3))
    value += feat_bonus

    # racial bonus
    # dragonborn fury
    if pc.race == races.dragonborn:
        value += 1 if pc.current_hitpoints <= pc.bloodied_value() else 0

    # other bonuses
    if pc.check_feat(feats.hellfire_blood) and (keywords.fire in power.keywords or keywords.fear in power.keywords):
        value += 1

    return "1к20 + " + str(value)