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

SaveProcessor   A

Complexity

Total Complexity 37

Size/Duplication

Total Lines 161
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 103
dl 0
loc 161
rs 9.44
c 1
b 0
f 0
wmc 37

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
F build() 0 154 36
1
<?php declare(strict_types=1);
2
3
namespace Smr\Pages\Admin\UniGen;
4
5
use Exception;
6
use Smr\Exceptions\UserError;
7
use Smr\Page\AccountPageProcessor;
8
use Smr\PlanetTypes\PlanetType;
9
use Smr\Race;
10
use Smr\Request;
11
use SmrAccount;
12
use SmrGalaxy;
13
use SmrLocation;
14
use SmrPort;
15
use SmrSector;
16
17
/**
18
 * @param array<int, SmrSector> $sectors
19
 * @param callable $condition True if sector is valid
20
 */
21
function findValidSector(array $sectors, callable $condition): SmrSector {
22
	if (count($sectors) == 0) {
23
		throw new UserError('There are no eligible sectors for this action!');
24
	}
25
	$key = array_rand($sectors);
26
	$sector = $sectors[$key];
27
	if ($condition($sector) !== true) {
28
		unset($sectors[$key]);
29
		return findValidSector($sectors, $condition);
30
	}
31
	return $sector;
32
}
33
34
function checkSectorAllowedForLoc(SmrSector $sector, SmrLocation $location): bool {
35
	if ($location->isHQ()) {
36
		// Only add HQs to empty sectors
37
		return !$sector->hasLocation();
38
	}
39
	// Otherwise, sector must meet these conditions:
40
	// 1. Does not already have this location
41
	// 2. Has fewer than 4 other locations
42
	// 3. Does not offer Fed protection
43
	return count($sector->getLocations()) < 4 && !$sector->offersFederalProtection() && !$sector->hasLocation($location->getTypeID());
44
}
45
46
function addLocationToSector(SmrLocation $location, SmrSector $sector): void {
47
	$sector->addLocation($location); //insert the location
48
	if ($location->isHQ()) {
49
		//only playable races have extra locations to add
50
		//Racial/Fed
51
		foreach ($location->getLinkedLocations() as $linkedLocation) {
52
			if (!$sector->hasLocation($linkedLocation->getTypeID())) {
53
				$sector->addLocation($linkedLocation);
54
			}
55
			if ($linkedLocation->isFed()) {
56
				$fedBeacon = $linkedLocation;
57
			}
58
		}
59
60
		//add Beacons to all surrounding areas (up to 2 sectors out)
61
		$visitedSectors = [];
62
		$links = ['Up', 'Right', 'Down', 'Left'];
63
		$fedSectors = [$sector];
64
		$tempFedSectors = [];
65
		for ($i = 0; $i < DEFAULT_FED_RADIUS; $i++) {
66
			foreach ($fedSectors as $fedSector) {
67
				foreach ($links as $link) {
68
					if ($fedSector->hasLink($link) && !isset($visitedSectors[$fedSector->getLink($link)])) {
69
						$linkSector = $sector->getLinkSector($link);
70
						if (isset($fedBeacon) && !$linkSector->hasLocation($fedBeacon->getTypeID())) {
71
							$linkSector->addLocation($fedBeacon); //add beacon to this sector
72
						}
73
						$tempFedSectors[] = $linkSector;
74
						$visitedSectors[$fedSector->getLink($link)] = true;
75
					}
76
				}
77
			}
78
			$fedSectors = $tempFedSectors;
79
			$tempFedSectors = [];
80
		}
81
	}
82
}
83
84
85
class SaveProcessor extends AccountPageProcessor {
86
87
	public function __construct(
88
		private readonly int $gameID,
89
		private readonly int $galaxyID
90
	) {}
91
92
	public function build(SmrAccount $account): never {
93
		$submit = Request::get('submit');
94
95
		if ($submit == 'Redo Connections') {
96
			$galaxy = SmrGalaxy::getGalaxy($this->gameID, $this->galaxyID);
97
			$connectivity = Request::getFloat('connect');
98
			if (!$galaxy->setConnectivity($connectivity)) {
99
				$message = '<span class="red">Error</span> : Regenerating connections failed.';
100
			} else {
101
				$message = '<span class="green">Success</span> : Regenerated connectivity with ' . $connectivity . '% target.';
102
			}
103
			SmrSector::saveSectors();
104
		} elseif ($submit == 'Create Locations') {
105
			$galSectors = SmrSector::getGalaxySectors($this->gameID, $this->galaxyID);
106
			foreach ($galSectors as $galSector) {
107
				$galSector->removeAllLocations();
108
			}
109
			foreach (SmrLocation::getAllLocations($this->gameID) as $location) {
110
				if (Request::has('loc' . $location->getTypeID())) {
111
					$numLoc = Request::getInt('loc' . $location->getTypeID());
112
					for ($i = 0; $i < $numLoc; $i++) {
113
						//4 per sector max locs and no locations inside fed
114
						$randSector = findValidSector(
115
							$galSectors,
116
							fn(SmrSector $sector): bool => checkSectorAllowedForLoc($sector, $location)
117
						);
118
						addLocationToSector($location, $randSector);
119
					}
120
				}
121
			}
122
			$message = '<span class="green">Success</span> : Succesfully added locations.';
123
		} elseif ($submit == 'Create Warps') {
124
			//get all warp info from all gals, some need to be removed, some need to be added
125
			$galaxy = SmrGalaxy::getGalaxy($this->gameID, $this->galaxyID);
126
			$galSectors = $galaxy->getSectors();
127
			//get totals
128
			foreach ($galSectors as $galSector) {
129
				if ($galSector->hasWarp()) {
130
					$galSector->removeWarp();
131
				}
132
			}
133
			//iterate over all the galaxies
134
			$galaxies = SmrGalaxy::getGameGalaxies($this->gameID);
135
			foreach ($galaxies as $eachGalaxy) {
136
				//do we have a warp to this gal?
137
				if (Request::has('warp' . $eachGalaxy->getGalaxyID())) {
138
					// Sanity check the number
139
					$numWarps = Request::getInt('warp' . $eachGalaxy->getGalaxyID());
140
					if ($numWarps > 10) {
141
						create_error('Specify no more than 10 warps between two galaxies!');
142
					}
143
					//iterate for each warp to this gal
144
					for ($i = 1; $i <= $numWarps; $i++) {
145
						//only 1 warp per sector
146
						$galSector = findValidSector(
147
							$galSectors,
148
							fn(SmrSector $sector): bool => !$sector->hasWarp() && !$sector->offersFederalProtection()
149
						);
150
						//get other side
151
						//make sure it does not go to itself
152
						$otherSector = findValidSector(
153
							$eachGalaxy->getSectors(),
154
							fn(SmrSector $sector): bool => !$sector->hasWarp() && !$sector->offersFederalProtection() && !$sector->equals($galSector)
155
						);
156
						$galSector->setWarp($otherSector);
157
					}
158
				}
159
			}
160
			SmrSector::saveSectors();
161
			$message = '<span class="green">Success</span> : Succesfully added warps.';
162
			(new CreateWarps($this->gameID, $this->galaxyID, $message))->go();
163
		} elseif ($submit == 'Create Planets') {
164
			$galaxy = SmrGalaxy::getGalaxy($this->gameID, $this->galaxyID);
165
			$galSectors = $galaxy->getSectors();
166
			foreach ($galSectors as $galSector) {
167
				if ($galSector->hasPlanet()) {
168
					$galSector->removePlanet();
169
				}
170
			}
171
172
			foreach (array_keys(PlanetType::PLANET_TYPES) as $planetTypeID) {
173
				$numberOfPlanets = Request::getInt('type' . $planetTypeID);
174
				for ($i = 1; $i <= $numberOfPlanets; $i++) {
175
					$galSector = findValidSector(
176
						$galSectors,
177
						fn(SmrSector $sector): bool => !$sector->hasPlanet() // 1 per sector
178
					);
179
					$galSector->createPlanet($planetTypeID);
180
				}
181
			}
182
			$message = '<span class="green">Success</span> : Succesfully added planets.';
183
		} elseif ($submit == 'Create Ports') {
184
			$numLevelPorts = [];
185
			$maxPortLevel = SmrPort::getMaxLevelByGame($this->gameID);
186
			for ($i = 1; $i <= $maxPortLevel; $i++) {
187
				$numLevelPorts[$i] = Request::getInt('port' . $i);
188
			}
189
			$totalPorts = array_sum($numLevelPorts);
190
191
			$totalRaceDist = 0;
192
			$numRacePorts = [];
193
			foreach (Race::getAllIDs() as $raceID) {
194
				$racePercent = Request::getInt('race' . $raceID);
195
				if (!empty($racePercent)) {
196
					$totalRaceDist += $racePercent;
197
					$numRacePorts[$raceID] = ceil($racePercent / 100 * $totalPorts);
198
				}
199
			}
200
			$assignedPorts = array_sum($numRacePorts);
201
			if ($totalRaceDist == 100 || $totalPorts == 0) {
202
				$galaxy = SmrGalaxy::getGalaxy($this->gameID, $this->galaxyID);
203
				$galSectors = $galaxy->getSectors();
204
				foreach ($galSectors as $galSector) {
205
					if ($galSector->hasPort()) {
206
						$galSector->removePort();
207
					}
208
				}
209
				//get race for all ports
210
				while ($totalPorts > $assignedPorts) {
211
					//this adds extra ports until we reach the requested #
212
					$numRacePorts[array_rand($numRacePorts)]++;
213
					$assignedPorts++;
214
				}
215
				//iterate through levels 1-9 port
216
				foreach ($numLevelPorts as $portLevel => $numLevel) {
217
					//iterate once for each port of this level
218
					for ($j = 0; $j < $numLevel; $j++) {
219
						//get a sector for this port
220
						$galSector = findValidSector(
221
							$galSectors,
222
							fn(SmrSector $sector): bool => !$sector->hasPort() && !$sector->offersFederalProtection()
223
						);
224
225
						$raceID = array_rand($numRacePorts);
226
						$numRacePorts[$raceID]--;
227
						if ($numRacePorts[$raceID] == 0) {
228
							unset($numRacePorts[$raceID]);
229
						}
230
						$port = $galSector->createPort();
231
						$port->setRaceID($raceID);
232
						$port->upgradeToLevel($portLevel);
233
						$port->setCreditsToDefault();
234
					}
235
				}
236
				SmrPort::savePorts();
237
				$message = '<span class="green">Success</span> : Succesfully added ports.';
238
			} else {
239
				$message = '<span class="red">Error: Your port race distribution must equal 100!</span>';
240
			}
241
		} else {
242
			throw new Exception('Unknown submit: ' . $submit);
243
		}
244
245
		(new EditGalaxy($this->gameID, $this->galaxyID, $message))->go();
246
	}
247
248
}
249