public function getAttackNumberModifierByDistance(
        Distance $targetDistance,
        EncounterRange $currentEncounterRange,
        MaximalRange $currentMaximalRange
    ): int
    {
        if ($targetDistance->getBonus()->getValue() > $currentMaximalRange->getValue()) { // comparing distance bonuses in fact
            throw new DistanceIsOutOfMaximalRange(
                "Given distance {$targetDistance->getBonus()} ({$targetDistance->getMeters()} meters)"
                . " is out of maximal range {$currentMaximalRange}"
                . ' (' . $currentMaximalRange->getInMeters($this->tables) . ' meters)'
            );
        }
        if ($currentEncounterRange->getValue() > $currentMaximalRange->getValue()) {
            throw new EncounterRangeCanNotBeGreaterThanMaximalRange(
                "Got encounter range {$currentEncounterRange} greater than given maximal range {$currentMaximalRange}"
            );
        }
        $attackNumberModifier = $this->tables->getAttackNumberByContinuousDistanceTable()
            ->getAttackNumberModifierByDistance($targetDistance);
        if ($targetDistance->getBonus()->getValue() > $currentEncounterRange->getValue()) { // comparing distance bonuses in fact
            $attackNumberModifier += $currentEncounterRange->getValue() - $targetDistance->getBonus()->getValue(); // always negative
        }

        return $attackNumberModifier;
    }