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
Pull Request — main (#1494)
by Dan
08:06 queued 03:15
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