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
10:59 queued 05:29
created

AttackPlanetProcessor::build()   F

Complexity

Conditions 21
Paths > 20000

Size

Total Lines 132
Code Lines 74

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 21
eloc 74
nc 98304
nop 1
dl 0
loc 132
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 Smr\Database;
7
use Smr\Epoch;
8
use Smr\Page\PlayerPageProcessor;
9
use Smr\SectorLock;
10
use SmrPlayer;
11
12
class AttackPlanetProcessor extends PlayerPageProcessor {
13
14
	public function build(AbstractSmrPlayer $player): never {
15
		$account = $player->getAccount();
16
		$ship = $player->getShip();
17
18
		if ($player->hasNewbieTurns()) {
19
			create_error('You are under newbie protection!');
20
		}
21
		if ($player->hasFederalProtection()) {
22
			create_error('You are under federal protection!');
23
		}
24
		if ($player->isLandedOnPlanet()) {
25
			create_error('You cannot attack planets whilst on a planet!');
26
		}
27
		if ($player->getTurns() < TURNS_TO_SHOOT_PLANET) {
28
			create_error('You do not have enough turns to attack this planet!');
29
		}
30
		if (!$ship->hasWeapons() && !$ship->hasCDs()) {
31
			create_error('What are you going to do? Insult it to death?');
32
		}
33
		if (!$player->canFight()) {
34
			create_error('You are not allowed to fight!');
35
		}
36
37
		$planet = $player->getSectorPlanet();
38
		if (!$planet->exists()) {
39
			create_error('This planet does not exist.');
40
		}
41
		if (!$planet->hasOwner()) {
42
			create_error('This planet is not claimed.');
43
		}
44
45
		$planetOwner = $planet->getOwner();
46
47
		if ($player->forceNAPAlliance($planetOwner)) {
48
			create_error('You have a planet NAP, you cannot attack this planet!');
49
		}
50
51
		// take the turns
52
		$player->takeTurns(TURNS_TO_SHOOT_PLANET);
53
54
		// ********************************
55
		// *
56
		// * P l a n e t   a t t a c k
57
		// *
58
		// ********************************
59
60
		$results = ['Attackers' => ['TotalDamage' => 0]];
61
62
		$attackers = $player->getSector()->getFightingTradersAgainstPlanet($player, $planet);
63
64
		$planet->attackedBy($player, $attackers);
65
66
		//decloak all attackers
67
		foreach ($attackers as $attacker) {
68
			$attacker->getShip()->decloak();
69
		}
70
71
		$totalShieldDamage = 0;
72
		foreach ($attackers as $attacker) {
73
			$playerResults = $attacker->shootPlanet($planet);
74
			$results['Attackers']['Traders'][$attacker->getAccountID()] = $playerResults;
75
			$results['Attackers']['TotalDamage'] += $playerResults['TotalDamage'];
76
			foreach ($playerResults['Weapons'] as $weapon) {
77
				if (isset($weapon['ActualDamage'])) { // Only set if the weapon hits
78
					$totalShieldDamage += $weapon['ActualDamage']['Shield'];
79
				}
80
			}
81
		}
82
83
		// Planet downgrades only occur on non-shield damage
84
		$downgradeDamage = $results['Attackers']['TotalDamage'] - $totalShieldDamage;
85
		$results['Attackers']['Downgrades'] = $planet->checkForDowngrade($downgradeDamage);
86
87
		$results['Planet'] = $planet->shootPlayers($attackers);
88
89
		$account->log(LOG_TYPE_PLANET_BUSTING, 'Player attacks planet, the planet does ' . $results['Planet']['TotalDamage'] . ', their team does ' . $results['Attackers']['TotalDamage'] . ' and downgrades: ' . var_export($results['Attackers']['Downgrades'], true), $planet->getSectorID());
90
91
		// Add this log to the `combat_logs` database table
92
		$db = Database::getInstance();
93
		$logId = $db->insert('combat_logs', [
94
			'game_id' => $db->escapeNumber($player->getGameID()),
95
			'type' => $db->escapeString('PLANET'),
96
			'sector_id' => $db->escapeNumber($planet->getSectorID()),
97
			'timestamp' => $db->escapeNumber(Epoch::time()),
98
			'attacker_id' => $db->escapeNumber($player->getAccountID()),
99
			'attacker_alliance_id' => $db->escapeNumber($player->getAllianceID()),
100
			'defender_id' => $db->escapeNumber($planetOwner->getAccountID()),
101
			'defender_alliance_id' => $db->escapeNumber($planetOwner->getAllianceID()),
102
			'result' => $db->escapeObject($results, true),
103
		]);
104
105
		if ($planet->isDestroyed()) {
106
			$db->write('UPDATE player SET land_on_planet = \'FALSE\' WHERE sector_id = ' . $db->escapeNumber($planet->getSectorID()) . ' AND game_id = ' . $db->escapeNumber($player->getGameID()));
107
			$planet->removeOwner();
108
			$planet->removePassword();
109
110
			// Prepare message for planet owners
111
			$planetAttackMessage = 'The defenses of ' . $planet->getCombatName() . ' have been breached. The planet is lost! [combatlog=' . $logId . ']';
112
		} else {
113
			$planetAttackMessage = 'Reports from the surface of ' . $planet->getCombatName() . ' confirm that it is under <span class="red">attack</span>! [combatlog=' . $logId . ']';
114
		}
115
116
		// Send notification to planet owners
117
		if ($planetOwner->hasAlliance()) {
118
			foreach ($planetOwner->getAlliance()->getMemberIDs() as $allyAccountID) {
119
				SmrPlayer::sendMessageFromPlanet($planet->getGameID(), $allyAccountID, $planetAttackMessage);
120
			}
121
		} else {
122
			SmrPlayer::sendMessageFromPlanet($planet->getGameID(), $planetOwner->getAccountID(), $planetAttackMessage);
123
		}
124
125
		// Update sector messages for attackers
126
		foreach ($attackers as $attacker) {
127
			if (!$player->equals($attacker)) {
128
				$db->replace('sector_message', [
129
					'account_id' => $db->escapeNumber($attacker->getAccountID()),
130
					'game_id' => $db->escapeNumber($attacker->getGameID()),
131
					'message' => $db->escapeString('[ATTACK_RESULTS]' . $logId),
132
				]);
133
			}
134
		}
135
136
		// If player died they are now in another sector, and thus locks need reset
137
		if ($player->isDead()) {
138
			saveAllAndReleaseLock(updateSession: false);
139
			// Grab the lock in the new sector to avoid reloading session
140
			SectorLock::getInstance()->acquireForPlayer($player);
141
		}
142
143
		// If they died on the shot they get to see the results
144
		$container = new AttackPlanet($planet->getSectorID(), $results, $player->isDead());
145
		$container->go();
146
	}
147
148
}
149