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   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 134
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 75
dl 0
loc 134
rs 10
c 1
b 0
f 0
wmc 21

1 Method

Rating   Name   Duplication   Size   Complexity  
F build() 0 132 21
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