Scrutinizer GitHub App not installed

We could not synchronize checks via GitHub's checks API since Scrutinizer's GitHub App is not installed for this repository.

Install GitHub App

Failed Conditions
Push — main ( 5797ad...3faf69 )
by Dan
29s queued 24s
created

AttackForcesProcessor::build()   F

Complexity

Conditions 22
Paths > 20000

Size

Total Lines 128
Code Lines 71

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 22
eloc 71
nc 122880
nop 1
dl 0
loc 128
rs 0
c 1
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php declare(strict_types=1);
2
3
namespace Smr\Pages\Player;
4
5
use AbstractSmrPlayer;
6
use Globals;
7
use Smr\Database;
8
use Smr\Epoch;
9
use Smr\Page\PlayerPageProcessor;
10
use Smr\SectorLock;
11
use SmrForce;
12
13
class AttackForcesProcessor extends PlayerPageProcessor {
14
15
	public function __construct(
16
		private readonly int $ownerAccountID,
17
		private readonly bool $bump = false
18
	) {}
19
20
	public function build(AbstractSmrPlayer $player): never {
21
		$ship = $player->getShip();
22
23
		$forces = SmrForce::getForce($player->getGameID(), $player->getSectorID(), $this->ownerAccountID);
24
		$forceOwner = $forces->getOwner();
25
26
		if ($player->hasNewbieTurns()) {
27
			create_error('You are under newbie protection!');
28
		}
29
		if ($player->hasFederalProtection()) {
30
			create_error('You are under federal protection.');
31
		}
32
		if ($player->isLandedOnPlanet()) {
33
			create_error('You cannot attack forces whilst on a planet!');
34
		}
35
		if (!$player->canFight()) {
36
			create_error('You are not allowed to fight!');
37
		}
38
		if ($player->forceNAPAlliance($forceOwner)) {
39
			create_error('You cannot attack allied forces!');
40
		}
41
42
		// The attack is processed slightly differently if the attacker bumped into mines
43
		// when moving into sector
44
		$bump = $this->bump;
45
46
		if ($bump) {
47
			if (!$forces->hasMines()) {
48
				create_error('No mines in sector!');
49
			}
50
		} else {
51
			if (!$forces->exists()) {
52
				create_error('These forces no longer exist.');
53
			}
54
			if ($player->getTurns() < $forces->getAttackTurnCost($ship)) {
55
				create_error('You do not have enough turns to attack these forces!');
56
			}
57
			if (!$ship->hasWeapons() && !$ship->hasCDs()) {
58
				create_error('You cannot attack without weapons!');
59
			}
60
		}
61
62
		// take the turns
63
		if ($bump) {
64
			$player->takeTurns($forces->getBumpTurnCost($ship));
65
		} else {
66
			$player->takeTurns($forces->getAttackTurnCost($ship), 1);
67
		}
68
69
		// delete plotted course
70
		$player->deletePlottedCourse();
71
72
		// A message will be sent if scouts are present before the attack.
73
		// Sending occurs after the attack so we can link the combat log.
74
		$sendMessage = $forces->hasSDs();
75
76
		// ********************************
77
		// *
78
		// * F o r c e s   a t t a c k
79
		// *
80
		// ********************************
81
82
		$results = ['Attackers' => ['TotalDamage' => 0],
83
						'Forces' => [],
84
						'Forced' => $bump];
85
86
		$attackers = $player->getSector()->getFightingTradersAgainstForces($player, $bump);
87
88
		//decloak all attackers
89
		foreach ($attackers as $attacker) {
90
			$attacker->getShip()->decloak();
91
			if (!$bump) {
92
				$attacker->setLastSectorID(0);
93
			}
94
		}
95
96
		// If mines are bumped, the forces shoot first. Otherwise player shoots first.
97
		if ($bump) {
98
			$results['Forces'] = $forces->shootPlayers($attackers, $bump);
99
		}
100
101
		$results['Attackers'] = ['TotalDamage' => 0];
102
		foreach ($attackers as $attacker) {
103
			$playerResults = $attacker->shootForces($forces);
104
			$results['Attackers']['Traders'][$attacker->getAccountID()] = $playerResults;
105
			$results['Attackers']['TotalDamage'] += $playerResults['TotalDamage'];
106
		}
107
108
		if (!$bump) {
109
			$results['Forces'] = $forces->shootPlayers($attackers, $bump);
110
			$forces->updateExpire();
111
		}
112
113
		// Add this log to the `combat_logs` database table
114
		$db = Database::getInstance();
115
		$logId = $db->insert('combat_logs', [
116
			'game_id' => $db->escapeNumber($player->getGameID()),
117
			'type' => $db->escapeString('FORCE'),
118
			'sector_id' => $db->escapeNumber($forces->getSectorID()),
119
			'timestamp' => $db->escapeNumber(Epoch::time()),
120
			'attacker_id' => $db->escapeNumber($player->getAccountID()),
121
			'attacker_alliance_id' => $db->escapeNumber($player->getAllianceID()),
122
			'defender_id' => $db->escapeNumber($forceOwner->getAccountID()),
123
			'defender_alliance_id' => $db->escapeNumber($forceOwner->getAllianceID()),
124
			'result' => $db->escapeObject($results, true),
125
		]);
126
127
		if ($sendMessage) {
128
			$message = 'Your forces in sector ' . Globals::getSectorBBLink($forces->getSectorID()) . ' are under <span class="red">attack</span> by ' . $player->getBBLink() . '! [combatlog=' . $logId . ']';
129
			$forces->ping($message, $player, true);
130
		}
131
132
		// If player died they are now in another sector, and thus locks need reset
133
		if ($player->isDead()) {
134
			saveAllAndReleaseLock(updateSession: false);
135
			// Grab the lock in the new sector to avoid reloading session
136
			SectorLock::getInstance()->acquireForPlayer($player);
137
		}
138
139
		// If player or target is dead there is no continue attack button
140
		if ($player->isDead() || !$forces->exists()) {
141
			$displayOwnerID = 0;
142
		} else {
143
			$displayOwnerID = $forces->getOwnerID();
144
		}
145
146
		$container = new AttackForces($displayOwnerID, $results, $player->isDead());
147
		$container->go();
148
	}
149
150
}
151