Exemplo n.º 1
0
    def dharok_attack(self, other: NPC) -> DamageData:
        """Returns a distribution of scythe damage and probability values"""
        dharok_set = [
            "dharok's greataxe", "dharok's helm", "dharok's platebody",
            "dharok's platelegs"
        ]
        assert self.wearing(dharok_set)

        self.hitpoints_current = 1
        max_hit_scale_factor = 1 + (
            (self.hitpoints - self.hitpoints_current) / 100 *
            (self.hitpoints / 100))

        attack_roll_modifier, damage_modifier = (1, max_hit_scale_factor)
        damage_type_defence_roll = self.style.damage_type

        attack_roll = self.player_maximum_attack_roll(other,
                                                      attack_roll_modifier)
        defence_roll = other.npc_maximum_defence_roll(damage_type_defence_roll)
        accuracy = cb.accuracy(attack_roll, defence_roll)
        max_hit = self.player_max_hit(other, damage_modifier)
        attack_distribution = cb.hit_distribution(max_hit, accuracy)
        AttackDistribution = DamageData(attack_distribution, self.attack_speed,
                                        accuracy)

        return AttackDistribution
Exemplo n.º 2
0
    def attack_npc(self,
                   other: NPC,
                   special_attack: bool = False) -> DamageData:
        """Returns accuracy and max hit against an NPC, special attack assumed to be false by default"""
        if special_attack:
            attack_roll_modifier = self.special_accuracy_modifier
            damage_modifier = [
                self.special_damage_modifier_1, self.special_damage_modifier_2
            ]
            damage_type_defence_roll = self.special_defence_roll

        else:
            attack_roll_modifier, damage_modifier = (1, 1)
            damage_type_defence_roll = self.style.damage_type

        attack_roll = self.player_maximum_attack_roll(other,
                                                      attack_roll_modifier)
        defence_roll = other.npc_maximum_defence_roll(damage_type_defence_roll)
        accuracy = cb.accuracy(attack_roll, defence_roll)
        max_hit = self.player_max_hit(other, damage_modifier)
        attack_distribution = cb.hit_distribution(max_hit, accuracy)
        AttackDistribution = DamageData(attack_distribution, self.attack_speed,
                                        accuracy)

        return AttackDistribution
Exemplo n.º 3
0
    def scythe_attack(self, other: NPC) -> DamageData:
        """Returns a distribution of scythe damage and probability values"""
        assert self.wearing('scythe of vitur')

        MainAttack = self.attack_npc(other)
        base_max_hit = MainAttack.max_hit
        accuracy = MainAttack.accuracy

        distributions = [MainAttack.damage_distribution]
        damage_modifiers = [0.5, 0.25]

        for modifier in damage_modifiers:
            distributions.append(
                cb.hit_distribution(math.floor(base_max_hit * modifier),
                                    accuracy))

        combined_distribution = convolution_list(distributions)
        ScytheAttack = DamageData(combined_distribution, self.attack_speed,
                                  1 - (1 - accuracy)**len(distributions))

        return ScytheAttack
Exemplo n.º 4
0
    def chinchompa(self,
                   other: NPC,
                   targets: int = 1,
                   distance: int = None) -> DamageData:
        """Returns a DamageData object representing a chinchompa thrown at many NPCs"""
        assert isinstance(self.style, RangedStyle)
        maximum_targets = 11
        targets = min([maximum_targets, targets])

        if distance:
            mod_tuple = self.style.distance_modifier_tuple

            range_tuple = ((0 <= distance <= 3), (4 <= distance <= 6),
                           (7 <= distance))
            attack_roll_modifier = float(np.dot(mod_tuple, range_tuple))

        else:
            attack_roll_modifier = 1

        damage_modifier = 1

        attack_roll = self.player_maximum_attack_roll(other,
                                                      attack_roll_modifier)
        defence_roll = other.npc_maximum_defence_roll(cb.ranged)
        accuracy = cb.accuracy(attack_roll, defence_roll)
        max_hit = self.player_max_hit(other, damage_modifier)
        attack_distribution_given_hit = cb.hit_distribution(
            max_hit, prob_hit=1, num=targets)  # all or nothing distr.
        attack_distribution_modified = {}

        for key, val in attack_distribution_given_hit.items():
            attack_distribution_modified[key] = val * accuracy

        attack_distribution_modified[0] += 1 - accuracy
        ChinchompaAttack = DamageData(attack_distribution_modified,
                                      self.attack_speed, accuracy)

        return ChinchompaAttack
Exemplo n.º 5
0
    def crossbow_distribution(self,
                              other: NPC,
                              style_bonus_attack: int,
                              style_bonus_strength: int,
                              pot_bonus: int,
                              attack_modifier: cb.modifier_types,
                              strength_modifier: cb.modifier_types,
                              bolt_type: str,
                              kandarin_hard_diary: bool = True) -> dict:
        """TODO: Make this work with the new styleReturns a crossbow damage/probability distribution

        TODO: implement the other bolts actually"""
        if bolt_type != 'ruby':
            raise Exception

        base_spec_chance, damage_modifier = cb.enchanted_bolts_spec_chance[
            bolt_type]

        spec_chance = base_spec_chance * (1 + kandarin_hard_diary * 0.10)

        base_acc, base_max = self.attack_npc(other, style_bonus_attack,
                                             style_bonus_strength, pot_bonus,
                                             "ranged", attack_modifier,
                                             strength_modifier)

        spec_acc, _ = self.attack_npc(other,
                                      style_bonus_attack,
                                      style_bonus_strength,
                                      pot_bonus,
                                      "ranged",
                                      attack_modifier,
                                      strength_modifier,
                                      attack_roll_modifier=2)

        spec_acc = max([1 * (bolt_type == "diamond"), spec_acc])

        ranged_visible = self.ranged + pot_bonus

        # modifies spec_max by flat % or % visible ranged level depending on bolt type
        spec_max = math.floor(
            base_max * (1 + damage_modifier *
                        (bolt_type in cb.enchanted_bolts_flat_percent)) +
            ranged_visible *
            (bolt_type in cb.enchanted_bolts_percent_visible_ranged_level))

        spec_max = (bolt_type !=
                    'ruby') * spec_max + (bolt_type == 'ruby') * min(
                        [math.floor(other.hitpoints_current * 0.20), 100])

        base_distribution = cb.hit_distribution(base_max, base_acc)

        for dmg, prob in base_distribution.items():
            base_distribution[dmg] = prob * (1 - spec_chance)

        spec_distribution = {0: 1 - spec_acc, spec_max: spec_acc}

        for dmg, prob in spec_distribution.items():
            if dmg in base_distribution:
                base_distribution[dmg] += prob * spec_chance

            else:
                base_distribution[dmg] = prob * spec_chance

        prob_sum = sum(base_distribution.values())
        assert math.fabs(prob_sum - 1) < 1e10

        return base_distribution