Passed
Push — master ( 6d8b29...d7e053 )
by Janko
27:40
created

AttackShipBehaviour::action()   B

Complexity

Conditions 6
Paths 3

Size

Total Lines 46
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 0
Metric Value
cc 6
eloc 25
nc 3
nop 4
dl 0
loc 46
ccs 0
cts 27
cp 0
crap 42
rs 8.8977
c 0
b 0
f 0
1
<?php
2
3
namespace Stu\Lib\Pirate\Behaviour;
4
5
use Override;
0 ignored issues
show
Bug introduced by
The type Override was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use Stu\Lib\Map\DistanceCalculationInterface;
7
use Stu\Lib\Pirate\Component\PirateAttackInterface;
8
use Stu\Lib\Pirate\Component\PirateNavigationInterface;
9
use Stu\Lib\Pirate\Component\TrapDetectionInterface;
10
use Stu\Lib\Pirate\PirateBehaviourEnum;
11
use Stu\Lib\Pirate\PirateReactionInterface;
12
use Stu\Lib\Pirate\PirateReactionMetadata;
13
use Stu\Module\Logging\LoggerUtilFactoryInterface;
14
use Stu\Module\Logging\PirateLoggerInterface;
15
use Stu\Module\Prestige\Lib\PrestigeCalculationInterface;
16
use Stu\Module\Ship\Lib\Battle\FightLibInterface;
17
use Stu\Module\Ship\Lib\FleetWrapperInterface;
18
use Stu\Orm\Entity\ShipInterface;
19
use Stu\Orm\Repository\ShipRepositoryInterface;
20
21
class AttackShipBehaviour implements PirateBehaviourInterface
22
{
23
    private PirateLoggerInterface $logger;
24
25
    public function __construct(
26
        private ShipRepositoryInterface $shipRepository,
27
        private DistanceCalculationInterface $distanceCalculation,
28
        private PirateNavigationInterface $pirateNavigation,
29
        private FightLibInterface $fightLib,
30
        private PrestigeCalculationInterface $prestigeCalculation,
31
        private PirateAttackInterface $pirateAttack,
32
        private TrapDetectionInterface $trapDetection,
33
        LoggerUtilFactoryInterface $loggerUtilFactory
34
    ) {
35
        $this->logger = $loggerUtilFactory->getPirateLogger();
36
    }
37
38
    #[Override]
39
    public function action(
40
        FleetWrapperInterface $fleet,
41
        PirateReactionInterface $pirateReaction,
42
        PirateReactionMetadata $reactionMetadata,
43
        ?ShipInterface $triggerShip
44
    ): ?PirateBehaviourEnum {
45
        $leadWrapper = $fleet->getLeadWrapper();
46
        $leadShip = $leadWrapper->get();
47
48
        $piratePrestige = $this->prestigeCalculation->getPrestigeOfSpacecraftOrFleet($leadShip);
49
50
        $this->logger->log(sprintf('    piratePrestige %d', $piratePrestige));
51
52
        $targets = $this->shipRepository->getPirateTargets($leadShip);
53
54
        $this->logger->log(sprintf('    %d targets in reach', count($targets)));
55
56
        $filteredTargets = array_filter(
57
            $targets,
58
            fn(ShipInterface $target): bool =>
59
            $this->fightLib->canAttackTarget($leadShip, $target, true, false, false)
60
                && !$this->trapDetection->isAlertTrap($target->getLocation(), $leadShip)
61
                && ($target === $triggerShip
62
                    || $this->targetHasEnoughPrestige($piratePrestige, $target))
63
        );
64
65
        $this->logger->log(sprintf('    %d filtered targets in reach', count($filteredTargets)));
66
67
        if ($filteredTargets === []) {
68
            return null;
69
        }
70
71
        usort(
72
            $filteredTargets,
73
            fn(ShipInterface $a, ShipInterface $b): int =>
74
            $this->distanceCalculation->shipToShipDistance($leadShip, $a) - $this->distanceCalculation->shipToShipDistance($leadShip, $b)
75
        );
76
77
        $closestShip = current($filteredTargets);
78
79
        if ($this->pirateNavigation->navigateToTarget($fleet, $closestShip->getLocation())) {
80
            $this->pirateAttack->attackShip($fleet, $closestShip);
81
        }
82
83
        return null;
84
    }
85
86
    private function targetHasEnoughPrestige(int $piratePrestige, ShipInterface $target): bool
87
    {
88
        $targetPrestige = $this->prestigeCalculation->getPrestigeOfSpacecraftOrFleet($target);
89
        $this->logger->log(sprintf('      targetPrestige %d', $targetPrestige));
90
91
        return $targetPrestige >= 0.33 * $piratePrestige;
92
    }
93
}
94