def __init__(self):
        super().__init__()

        # Basic pyqt init for gui window
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.configuration = json.load(open('configuration.json', 'r'))

        # Class variables to hold state of check boxes
        self.inspire_courage_enabled = False
        self.haste_enabled = False
        self.two_weapon_fighting_enabled = False
        self.deadly_aim_enabled = False
        self.point_blank_enabled = False
        self.improved_point_blank_enabled = False
        self.up_close_and_deadly_enabled = False

        # Connections to toggle state on check box click
        self.ui.inspire_courage_check_box.clicked.connect(self.inspire_courage_toggled)
        self.ui.haste_check_box.clicked.connect(self.haste_toggled)
        self.ui.two_weapon_fighting_check_box.clicked.connect(self.two_weapon_fighting_toggled)
        self.ui.deadly_aim_check_box.clicked.connect(self.deadly_aim_toggled)
        self.ui.point_blank_check_box.clicked.connect(self.point_blank_toggled)
        self.ui.improved_point_blank_check_box.clicked.connect(self.improved_point_blank_shot_toggled)
        self.ui.close_and_deadly_check_box.clicked.connect(self.up_close_and_deadly_toggled)

        # Auto update when spin box toggled
        self.ui.num_hits_spin_box.valueChanged.connect(self.update_output)
        self.ui.crit_multiplier_spin_box.valueChanged.connect(self.update_output)
        self.ui.up_close_and_deadly_spin_box.valueChanged.connect(self.update_output)

        # Initialize output with initial settings
        self.update_output()
예제 #2
0
    def __init__(self):
        super().__init__()

        # Basic pyqt init for gui window
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.configuration = json.load(
            open(resource_path("configuration.json"), "r"))

        # Class variables to hold state of check boxes
        self.two_handed_enabled = True
        self.weapon_song_enabled = False
        self.haste_enabled = False
        self.power_attack_enabled = False

        # Connections to toggle state on check box click
        self.ui.two_handed_check_box.clicked.connect(self.two_handed_toggled)
        self.ui.inspire_courage_check_box.clicked.connect(
            self.inspire_courage_toggled)
        self.ui.haste_check_box.clicked.connect(self.haste_toggled)
        self.ui.power_attack_check_box.clicked.connect(
            self.power_attack_toggled)

        # Auto update when spin box toggled
        self.ui.num_hits_spin_box.valueChanged.connect(self.update_output)

        # Initialize output with initial settings
        self.update_output()
    def __init__(self):
        super().__init__()

        # Basic pyqt init for gui window
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.configuration = json.load(open('configuration.json', 'r'))

        # Initialize tracked resources
        grit_pool = self.configuration['GRIT_POOL']
        self.ui.grit_pool_spin_box.setMaximum(grit_pool)
        self.ui.grit_pool_spin_box.setValue(grit_pool)

        # Class variables to hold state of check boxes
        self.inspire_courage_enabled = False
        self.haste_enabled = False
        self.two_weapon_fighting_enabled = False
        self.deadly_aim_enabled = False
        self.point_blank_enabled = False
        self.improved_point_blank_enabled = False
        self.up_close_and_deadly_enabled = False
        self.rapid_shot_enabled = False

        # Close program on Ctrl+Q
        shortcut_close = QShortcut(QKeySequence('Ctrl+Q'), self)
        shortcut_close.activated.connect(self.close)

        # Connections to toggle state on check box click
        self.ui.inspire_courage_check_box.toggled.connect(
            self.inspire_courage_toggled)
        self.ui.haste_check_box.toggled.connect(self.haste_toggled)
        self.ui.two_weapon_fighting_check_box.toggled.connect(
            self.two_weapon_fighting_toggled)
        self.ui.deadly_aim_check_box.toggled.connect(self.deadly_aim_toggled)
        self.ui.point_blank_check_box.toggled.connect(self.point_blank_toggled)
        self.ui.improved_point_blank_check_box.toggled.connect(
            self.improved_point_blank_shot_toggled)
        self.ui.close_and_deadly_check_box.toggled.connect(
            self.up_close_and_deadly_toggled)
        self.ui.rapid_shot_check_box.toggled.connect(self.rapid_shot_toggled)

        # Auto update when spin box toggled
        self.ui.num_hits_spin_box.valueChanged.connect(self.update_output)
        self.ui.crit_multiplier_spin_box.valueChanged.connect(
            self.update_output)
        self.ui.up_close_and_deadly_spin_box.valueChanged.connect(
            self.update_output)

        # Initialize output with initial settings
        self.update_output()
예제 #4
0
    def __init__(self):
        super().__init__()

        # Basic pyqt init for gui window
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.configuration = json.load(open("configuration.json", "r"))

        # Class variables to hold state of check boxes
        self.two_handed_enabled = True
        self.inspire_courage_enabled = False
        self.haste_enabled = False
        self.raging_enabled = False
        self.power_attack_enabled = False
        self.enlarged_enabled = False
        self.surprise_accuracy_enabled = False
        self.powerful_blow_enabled = False
        self.flanking_enabled = False
        self.deadly_juggernaut_enabled = False

        # Connections to toggle state on check box click
        self.ui.two_handed_check_box.clicked.connect(self.two_handed_toggled)
        self.ui.inspire_courage_check_box.clicked.connect(
            self.inspire_courage_toggled)
        self.ui.haste_check_box.clicked.connect(self.haste_toggled)
        self.ui.raging_check_box.clicked.connect(self.raging_toggled)
        self.ui.power_attack_check_box.clicked.connect(
            self.power_attack_toggled)
        self.ui.enlarged_check_box.clicked.connect(self.enlarged_toggled)
        self.ui.surprise_accuracy_check_box.clicked.connect(
            self.surprise_accuracy_toggled)
        self.ui.powerful_blow_check_box.clicked.connect(
            self.powerful_blow_toggled)
        self.ui.flanking_bonus_check_box.clicked.connect(self.flanking_toggled)
        self.ui.deadly_juggernaut_check_box.clicked.connect(
            self.deadly_juggernaut_toggled)

        # Auto update when spin box toggled
        self.ui.kills_spin_box.valueChanged.connect(self.update_output)
        self.ui.num_hits_spin_box.valueChanged.connect(self.update_output)

        # Initialize output with initial settings
        self.update_output()
예제 #5
0
    def __init__(self):
        super().__init__()

        # Basic pyqt init for gui window
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.configuration = json.load(open("configuration.json", "r"))

        # Class variables to hold state of check boxes
        self.inspire_courage_enabled = False
        self.haste_enabled = False
        self.raging_enabled = False
        self.charging_enabled = False
        self.flanking_enabled = False
        self.sneak_attack_enabled = False

        # Storage variables for other numbers
        self.bleed_stacks = 0
        self.dex_mod = 0

        # Connections to toggle state on check box click
        self.ui.inspire_courage_check_box.clicked.connect(
            self.inspire_courage_toggled)
        self.ui.haste_check_box.clicked.connect(self.haste_toggled)
        self.ui.raging_check_box.clicked.connect(self.raging_toggled)
        self.ui.charging_check_box.clicked.connect(self.charging_toggled)
        self.ui.flanking_bonus_check_box.clicked.connect(self.flanking_toggled)
        self.ui.flanking_bonus_check_box.clicked.connect(self.flanking_toggled)
        self.ui.sneak_attack_check_box.clicked.connect(
            self.sneak_attack_toggled)
        self.ui.bleed_stacks_spinbox.valueChanged.connect(
            self.bleed_stacks_changed)
        self.ui.reset_stacks_button.clicked.connect(self.bleed_stacks_reset)
        self.ui.dex_mod_spinbox.valueChanged.connect(self.dex_mod_changed)

        # Auto update when spin box toggled
        self.ui.num_hits_spin_box.valueChanged.connect(self.update_output)

        # Initialize output with initial settings
        self.update_output()
예제 #6
0
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        # Basic pyqt init for gui window
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.configuration = json.load(
            open(resource_path("configuration.json"), "r"))

        # Class variables to hold state of check boxes
        self.two_handed_enabled = True
        self.weapon_song_enabled = False
        self.haste_enabled = False
        self.power_attack_enabled = False

        # Connections to toggle state on check box click
        self.ui.two_handed_check_box.clicked.connect(self.two_handed_toggled)
        self.ui.inspire_courage_check_box.clicked.connect(
            self.inspire_courage_toggled)
        self.ui.haste_check_box.clicked.connect(self.haste_toggled)
        self.ui.power_attack_check_box.clicked.connect(
            self.power_attack_toggled)

        # Auto update when spin box toggled
        self.ui.num_hits_spin_box.valueChanged.connect(self.update_output)

        # Initialize output with initial settings
        self.update_output()

    def two_handed_toggled(self, state):
        self.two_handed_enabled = state
        self.update_output()

    def inspire_courage_toggled(self, state):
        self.weapon_song_enabled = state
        self.update_output()

    def haste_toggled(self, state):
        self.haste_enabled = state
        self.update_output()

    def power_attack_toggled(self, state):
        self.power_attack_enabled = state
        self.update_output()

    def update_output(self):
        # Calculate strength bonus
        strength = self.configuration['STR']

        effective_strength_bonus = int((strength - 10) / 2)

        # Calculate number of attacks
        num_attacks = 1 + int((self.configuration['BAB'] - 1) / 5)

        # Calculate atack bonus
        attack_bonus = self.calculate_attack_bonus(effective_strength_bonus)

        attack_text = f' Attack Bonus: +{attack_bonus}'
        if self.haste_enabled:
            attack_text = attack_text + f'/{attack_bonus}'
        for i in range(num_attacks - 1):
            attack_text = attack_text + f'/{attack_bonus - (5 * (i + 1))}'
        self.ui.attack_bonus_label.setText(attack_text)

        # Set new spin box max
        spin_max = num_attacks
        if self.haste_enabled:
            spin_max += 1
        self.ui.num_hits_spin_box.setMaximum(spin_max)

        # Get num hits
        num_hits = int(self.ui.num_hits_spin_box.value())

        # Calculate damage
        damage = self.calculate_damage(effective_strength_bonus)
        damage *= num_hits

        die = self.configuration["DAMAGE_DIE"]

        self.ui.damage_label.setText(
            f'Damage: {num_hits * die[0]}d{die[1]} + {damage}')

        crit_mod = self.configuration["WEAPON_CRITICAL_MOD"]
        self.ui.crit_damage_label.setText(
            f'Critical Damage: {num_hits * crit_mod * die[0]}d{die[1]} + {crit_mod * damage}'
        )

    def calculate_attack_bonus(self, effective_strength_bonus):
        attack_bonus = (self.configuration['BAB'] +
                        self.configuration['WEAPON_BONUS'] +
                        effective_strength_bonus +
                        self.configuration['WEAPON_FOCUS'])

        if self.weapon_song_enabled:
            attack_bonus += self.configuration['INSPIRE']

        if self.haste_enabled:
            attack_bonus += self.configuration['HASTE']

        if self.power_attack_enabled:
            attack_bonus += self.configuration['POWER_ATTACK_ATTACK']

        return attack_bonus

    def calculate_damage(self, effective_strength_bonus):
        damage = self.configuration['WEAPON_BONUS']

        strength_damage = effective_strength_bonus
        if self.two_handed_enabled:
            strength_damage = int(strength_damage *
                                  self.configuration['TWO_HANDED_MULTI'])
        damage += strength_damage

        power_attack_damage = 6
        if self.two_handed_enabled:
            power_attack_damage = int(power_attack_damage *
                                      self.configuration['TWO_HANDED_MULTI'])
        if self.power_attack_enabled:
            damage += power_attack_damage

        if self.weapon_song_enabled:
            damage += self.configuration['INSPIRE']

        return damage
예제 #7
0
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        # Basic pyqt init for gui window
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.configuration = json.load(open("configuration.json", "r"))

        # Class variables to hold state of check boxes
        self.inspire_courage_enabled = False
        self.haste_enabled = False
        self.raging_enabled = False
        self.charging_enabled = False
        self.flanking_enabled = False
        self.sneak_attack_enabled = False

        # Storage variables for other numbers
        self.bleed_stacks = 0
        self.dex_mod = 0

        # Connections to toggle state on check box click
        self.ui.inspire_courage_check_box.clicked.connect(
            self.inspire_courage_toggled)
        self.ui.haste_check_box.clicked.connect(self.haste_toggled)
        self.ui.raging_check_box.clicked.connect(self.raging_toggled)
        self.ui.charging_check_box.clicked.connect(self.charging_toggled)
        self.ui.flanking_bonus_check_box.clicked.connect(self.flanking_toggled)
        self.ui.flanking_bonus_check_box.clicked.connect(self.flanking_toggled)
        self.ui.sneak_attack_check_box.clicked.connect(
            self.sneak_attack_toggled)
        self.ui.bleed_stacks_spinbox.valueChanged.connect(
            self.bleed_stacks_changed)
        self.ui.reset_stacks_button.clicked.connect(self.bleed_stacks_reset)
        self.ui.dex_mod_spinbox.valueChanged.connect(self.dex_mod_changed)

        # Auto update when spin box toggled
        self.ui.num_hits_spin_box.valueChanged.connect(self.update_output)

        # Initialize output with initial settings
        self.update_output()

    def inspire_courage_toggled(self, state):
        self.inspire_courage_enabled = state
        self.update_output()

    def haste_toggled(self, state):
        self.haste_enabled = state
        self.update_output()

    def raging_toggled(self, state):
        self.raging_enabled = state
        self.update_output()

    def charging_toggled(self, state):
        self.charging_enabled = state
        self.update_output()

    def flanking_toggled(self, state):
        self.flanking_enabled = state
        self.update_output()

    def sneak_attack_toggled(self, state):
        self.sneak_attack_enabled = state
        self.update_output()

    def bleed_stacks_changed(self, number):
        self.bleed_stacks = number
        self.update_output()

    def bleed_stacks_reset(self):
        self.bleed_stacks = 0
        self.ui.bleed_stacks_spinbox.setValue(0)
        self.update_output()

    def dex_mod_changed(self, number):
        self.dex_mod = number
        self.update_output()

    def update_output(self):
        raw_dex = self.configuration['DEX']
        if self.raging_enabled:
            raw_dex += self.configuration['RAGE_DEX_BONUS']

        # Adjust for penalty or bonus dex
        dex_adjustment = int(self.dex_mod / 2)

        # Convert from raw number to bonus/mod
        bonus_dex = int((raw_dex - 10) / 2) + dex_adjustment

        # Calculate Attack Bonus
        attack_bonus = self.calculate_attack_bonus(bonus_dex)

        # Calculate number of attacks
        num_attacks = 1 + int((self.configuration['BAB'] - 1) / 5)

        attack_text = f' Attack Bonus: +{attack_bonus}'
        if self.haste_enabled or self.configuration['SPEED_WEAPON']:
            attack_text = attack_text + f'/{attack_bonus}'
        for i in range(num_attacks - 1):
            attack_text = attack_text + f'/{attack_bonus - (5 * (i + 1))}'
        self.ui.attack_bonus_label.setText(attack_text)

        # Set new spin box max
        spin_max = num_attacks
        if self.haste_enabled:
            spin_max += 1
        self.ui.num_hits_spin_box.setMaximum(spin_max)

        # Get num hits
        num_hits = int(self.ui.num_hits_spin_box.value())

        # Calculate Damage Bonus
        damage = self.calculate_damage(bonus_dex) * num_hits

        # Calculate Dice
        dice, crit_dice = self.calculate_dice(num_hits)

        self.ui.damage_label.setText(f'Damage: {dice} + {damage}')

        crit_mod = self.configuration["WEAPON_CRITICAL_MOD"]
        self.ui.crit_damage_label.setText(
            f'Critical Damage: {crit_dice} + {crit_mod * damage}')

    def calculate_attack_bonus(self, dex):
        attack_bonus = self.configuration['BAB'] + self.configuration[
            'WEAPON_BONUS'] + self.configuration['WEAPON_FOCUS'] + dex

        if self.inspire_courage_enabled:
            attack_bonus += self.configuration['INSPIRE']

        if self.haste_enabled:
            attack_bonus += self.configuration['HASTE']

        if self.charging_enabled:
            attack_bonus += self.configuration['CHARGE']

        if self.flanking_enabled:
            attack_bonus += self.configuration['FLANKING']

        if self.sneak_attack_enabled:
            attack_bonus += self.configuration['SNEAK_ATTACK_BONUS']

        attack_bonus += self.bleed_stacks

        return attack_bonus

    def calculate_damage(self, dex):
        damage = self.configuration['WEAPON_BONUS'] + dex

        if self.inspire_courage_enabled:
            damage += self.configuration['INSPIRE']

        return damage

    def calculate_dice(self, hits):
        weapon_dice = self.configuration['DAMAGE_DIE']

        crit_multiplier = self.configuration['WEAPON_CRITICAL_MOD']

        sneak_dice = self.configuration['SNEAK_DAMAGE_DIE']

        extra_crit_dice = self.configuration["BONUS_CRIT_DICE"]

        bleed_dice = self.configuration[
            "BLEEDING_CRITICAL_DICE_PER_STACK"] * self.bleed_stacks

        # Limit the bonus dice to 5 as per weapon description
        if bleed_dice > 5:
            bleed_dice = 5

        if self.sneak_attack_enabled:
            dice = f'{hits * (weapon_dice[0] + sneak_dice[0])}d6'
            crit_dice = f'{hits * (crit_multiplier * weapon_dice[0] + sneak_dice[0] + extra_crit_dice + bleed_dice)}d6'
        else:
            dice = f'{hits * (weapon_dice[0])}d6'
            crit_dice = f'{hits * (crit_multiplier * weapon_dice[0] + extra_crit_dice + bleed_dice)}d6'

        return dice, crit_dice
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        # Basic pyqt init for gui window
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.configuration = json.load(open('configuration.json', 'r'))

        # Class variables to hold state of check boxes
        self.inspire_courage_enabled = False
        self.haste_enabled = False
        self.two_weapon_fighting_enabled = False
        self.deadly_aim_enabled = False
        self.point_blank_enabled = False
        self.improved_point_blank_enabled = False
        self.up_close_and_deadly_enabled = False

        # Connections to toggle state on check box click
        self.ui.inspire_courage_check_box.clicked.connect(self.inspire_courage_toggled)
        self.ui.haste_check_box.clicked.connect(self.haste_toggled)
        self.ui.two_weapon_fighting_check_box.clicked.connect(self.two_weapon_fighting_toggled)
        self.ui.deadly_aim_check_box.clicked.connect(self.deadly_aim_toggled)
        self.ui.point_blank_check_box.clicked.connect(self.point_blank_toggled)
        self.ui.improved_point_blank_check_box.clicked.connect(self.improved_point_blank_shot_toggled)
        self.ui.close_and_deadly_check_box.clicked.connect(self.up_close_and_deadly_toggled)

        # Auto update when spin box toggled
        self.ui.num_hits_spin_box.valueChanged.connect(self.update_output)
        self.ui.crit_multiplier_spin_box.valueChanged.connect(self.update_output)
        self.ui.up_close_and_deadly_spin_box.valueChanged.connect(self.update_output)

        # Initialize output with initial settings
        self.update_output()

    def inspire_courage_toggled(self, state):
        self.inspire_courage_enabled = state
        self.update_output()

    def haste_toggled(self, state):
        self.haste_enabled = state
        self.update_output()

    def two_weapon_fighting_toggled(self, state):
        self.two_weapon_fighting_enabled = state
        self.update_output()

    def deadly_aim_toggled(self, state):
        self.deadly_aim_enabled = state
        self.update_output()

    def improved_point_blank_shot_toggled(self, state):
        self.improved_point_blank_enabled = state
        self.point_blank_enabled = state
        self.ui.point_blank_check_box.setChecked(state)
        self.update_output()

    def point_blank_toggled(self, state):
        self.point_blank_enabled = state
        self.update_output()

    def up_close_and_deadly_toggled(self, state):
        self.up_close_and_deadly_enabled = state
        self.ui.up_close_and_deadly_spin_box.setEnabled(state)
        self.update_output()

    def update_output(self):
        # Calculate dex bonus
        dex_bonus = (self.configuration['DEX'] - 10) // 2

        # Calculate Attack Bonus
        attack_bonus = self.calculate_attack_bonus(dex_bonus)

        # Calculate number of attacks
        num_attacks = 1 + ((self.configuration['BAB'] - 1) // 5)

        # Main Attacks
        attack_text = f' Attack Bonus: + {attack_bonus}'
        if self.two_weapon_fighting_enabled:
            attack_text += f'/{attack_bonus}'

        # Haste Attack
        if self.haste_enabled:
            attack_text += f'/{attack_bonus}'

        # Iterative Attacks
        for i in range(num_attacks - 1):
            # Add more iteratives so long as the required feats are had
            if self.two_weapon_fighting_enabled and self.configuration['TWO_WEAPON_FIGHTING_LEVEL'] > i+1:
                attack_text += f'/{attack_bonus - (5 * (i + 1))}'

            attack_text += f'/{attack_bonus - (5 * (i + 1))}'

        self.ui.attack_bonus_label.setText(attack_text)

        # Set new spin box max
        spin_max = num_attacks
        if self.haste_enabled:
            spin_max += 1

        if self.two_weapon_fighting_enabled:
            spin_max += self.configuration['TWO_WEAPON_FIGHTING_LEVEL']

        self.ui.num_hits_spin_box.setMaximum(spin_max)

        # Get num hits
        num_hits = int(self.ui.num_hits_spin_box.value())

        # Set up close and deadly maximum to number of hits
        self.ui.up_close_and_deadly_spin_box.setMaximum(num_hits)

        # Calculate Damage Bonus
        damage = self.calculate_damage(dex_bonus) * num_hits

        # Calculate Dice
        dice, crit_dice = self.calculate_dice(num_hits)

        self.ui.damage_label.setText(f'Damage: {dice} + {damage}')

        crit_mod = int(self.ui.crit_multiplier_spin_box.value())
        self.ui.crit_damage_label.setText(f'Critical Damage: {crit_dice} + {crit_mod * damage}')

    def calculate_attack_bonus(self, dex_bonus):
        conf = self.configuration

        attack_bonus = conf['BAB'] + conf['WEAPON_BONUS'] + dex_bonus + conf['ATTACK_BONUS']

        if self.inspire_courage_enabled:
            attack_bonus += conf['INSPIRE']

        if self.haste_enabled:
            attack_bonus += conf['HASTE']

        if self.deadly_aim_enabled:
            attack_bonus += conf['DEADLY_AIM_PENALTY']

        if self.point_blank_enabled:
            attack_bonus += conf['POINT_BLANK']

        if self.improved_point_blank_enabled:
            attack_bonus += conf['IMPROVED_POINT_BLANK']

        if self.two_weapon_fighting_enabled:
            attack_bonus += conf['TWO_WEAPON_FIGHTING_PENALTY']

        return attack_bonus

    def calculate_damage(self, dex_bonus):
        damage = self.configuration['WEAPON_BONUS'] + dex_bonus + self.configuration['DAMAGE_BONUS']

        if self.inspire_courage_enabled:
            damage += self.configuration['INSPIRE']

        if self.point_blank_enabled:
            damage += self.configuration['POINT_BLANK']

        if self.improved_point_blank_enabled:
            damage += self.configuration['IMPROVED_POINT_BLANK']

        if self.deadly_aim_enabled:
            damage += self.configuration['DEADLY_AIM_BONUS']

        return damage

    def calculate_dice(self, hits):
        weapon_dice = self.configuration['DAMAGE_DIE']

        crit_multiplier = int(self.ui.crit_multiplier_spin_box.value())

        dice = f'{hits * (weapon_dice[0])}d{weapon_dice[1]}'
        crit_dice = f'{hits * (crit_multiplier * weapon_dice[0])}d{weapon_dice[1]}'

        if self.up_close_and_deadly_enabled:
            num_dice = self.configuration['UP_CLOSE_AND_DEADLY_DICE'][0]
            die_type = self.configuration['UP_CLOSE_AND_DEADLY_DICE'][1]

            num_invocations = int(self.ui.up_close_and_deadly_spin_box.value())

            up_close_and_deadly_dice = f'{num_invocations * num_dice}d{die_type}'
            dice += f' + {up_close_and_deadly_dice}'
            crit_dice += f' + {up_close_and_deadly_dice}'

        return dice, crit_dice
예제 #9
0
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        # Basic pyqt init for gui window
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.configuration = json.load(open("configuration.json", "r"))

        # Class variables to hold state of check boxes
        self.two_handed_enabled = True
        self.inspire_courage_enabled = False
        self.haste_enabled = False
        self.raging_enabled = False
        self.power_attack_enabled = False
        self.enlarged_enabled = False
        self.surprise_accuracy_enabled = False
        self.powerful_blow_enabled = False
        self.flanking_enabled = False
        self.deadly_juggernaut_enabled = False

        # Connections to toggle state on check box click
        self.ui.two_handed_check_box.clicked.connect(self.two_handed_toggled)
        self.ui.inspire_courage_check_box.clicked.connect(
            self.inspire_courage_toggled)
        self.ui.haste_check_box.clicked.connect(self.haste_toggled)
        self.ui.raging_check_box.clicked.connect(self.raging_toggled)
        self.ui.power_attack_check_box.clicked.connect(
            self.power_attack_toggled)
        self.ui.enlarged_check_box.clicked.connect(self.enlarged_toggled)
        self.ui.surprise_accuracy_check_box.clicked.connect(
            self.surprise_accuracy_toggled)
        self.ui.powerful_blow_check_box.clicked.connect(
            self.powerful_blow_toggled)
        self.ui.flanking_bonus_check_box.clicked.connect(self.flanking_toggled)
        self.ui.deadly_juggernaut_check_box.clicked.connect(
            self.deadly_juggernaut_toggled)

        # Auto update when spin box toggled
        self.ui.kills_spin_box.valueChanged.connect(self.update_output)
        self.ui.num_hits_spin_box.valueChanged.connect(self.update_output)

        # Initialize output with initial settings
        self.update_output()

    def two_handed_toggled(self, state):
        self.two_handed_enabled = state
        self.update_output()

    def inspire_courage_toggled(self, state):
        self.inspire_courage_enabled = state
        self.update_output()

    def haste_toggled(self, state):
        self.haste_enabled = state
        self.update_output()

    def raging_toggled(self, state):
        self.raging_enabled = state
        self.update_output()

    def power_attack_toggled(self, state):
        self.power_attack_enabled = state
        self.update_output()

    def enlarged_toggled(self, state):
        self.enlarged_enabled = state
        self.update_output()

    def surprise_accuracy_toggled(self, state):
        self.surprise_accuracy_enabled = state
        self.update_output()

    def powerful_blow_toggled(self, state):
        self.powerful_blow_enabled = state
        self.update_output()

    def flanking_toggled(self, state):
        self.flanking_enabled = state
        self.update_output()

    def deadly_juggernaut_toggled(self, state):
        self.deadly_juggernaut_enabled = state
        self.update_output()

    def update_output(self):
        # Calculate strength bonus
        strength = self.configuration['STR']
        if self.raging_enabled:
            strength += self.configuration['RAGE_STR_BONUS']
        if self.enlarged_enabled:
            strength += self.configuration['ENLARGE_STR_BONUS']
        effective_strength_bonus = int((strength - 10) / 2)

        # Calculate number of attacks
        num_attacks = 1 + int((self.configuration['BAB'] - 1) / 5)

        # Calculate atack bonus
        attack_bonus = self.calculate_attack_bonus(effective_strength_bonus)

        attack_text = f' Attack Bonus: +{attack_bonus}'
        if self.haste_enabled:
            attack_text = attack_text + f'/{attack_bonus}'
        for i in range(num_attacks - 1):
            attack_text = attack_text + f'/{attack_bonus - (5 * (i + 1))}'
        self.ui.attack_bonus_label.setText(attack_text)

        # Set new spin box max
        spin_max = num_attacks
        if self.haste_enabled:
            spin_max += 1
        self.ui.num_hits_spin_box.setMaximum(spin_max)

        # Get num hits
        num_hits = int(self.ui.num_hits_spin_box.value())

        # Calculate damage
        die, damage = self.calculate_damage(effective_strength_bonus)
        damage *= num_hits
        self.ui.damage_label.setText(
            f'Damage: {num_hits * die[0]}d{die[1]} + {damage}')

        crit_mod = self.configuration["WEAPON_CRITICAL_MOD"]
        self.ui.crit_damage_label.setText(
            f'Critical Damage: {num_hits * crit_mod * die[0]}d{die[1]} + {crit_mod * damage}'
        )

    def calculate_attack_bonus(self, effective_strength_bonus):
        attack_bonus = self.configuration['BAB'] + self.configuration[
            'WEAPON_BONUS'] + effective_strength_bonus

        if self.inspire_courage_enabled:
            attack_bonus += self.configuration['INSPIRE']

        if self.haste_enabled:
            attack_bonus += self.configuration['HASTE']

        if self.power_attack_enabled:
            attack_bonus += self.configuration['POWER_ATTACK_ATTACK']

        if self.enlarged_enabled:
            attack_bonus += self.configuration['ENLARGE']

        if self.surprise_accuracy_enabled:
            attack_bonus += self.configuration['SURPRISE_ACCURACY']

        if self.flanking_enabled:
            attack_bonus += self.configuration['FLANKING']

        if self.deadly_juggernaut_enabled:
            attack_bonus += self.ui.kills_spin_box.value()

        return attack_bonus

    def calculate_damage(self, effective_strength_bonus):
        damage = self.configuration['WEAPON_BONUS']

        strength_damage = effective_strength_bonus
        if self.two_handed_enabled:
            strength_damage = int(strength_damage *
                                  self.configuration['TWO_HANDED_MULTI'])
        damage += strength_damage

        if self.powerful_blow_enabled:
            damage += self.configuration['POWERFUL_BLOW']

        power_attack_damage = 6
        if self.two_handed_enabled:
            power_attack_damage = int(power_attack_damage *
                                      self.configuration['TWO_HANDED_MULTI'])
        if self.power_attack_enabled:
            damage += power_attack_damage

        if self.inspire_courage_enabled:
            damage += self.configuration['INSPIRE']

        if self.deadly_juggernaut_enabled:
            damage += self.ui.kills_spin_box.value()

        if self.enlarged_enabled:
            die = self.configuration['ENLARGE_DAMAGE_DIE']
        else:
            die = self.configuration['DAMAGE_DIE']

        return die, damage