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

SmrForce::getDropContainer()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0

1 Method

Rating   Name   Duplication   Size   Complexity  
A SmrForce::getDropSDHREF() 0 3 1
1
<?php declare(strict_types=1);
2
3
use Smr\Database;
4
use Smr\DatabaseRecord;
5
use Smr\Epoch;
6
use Smr\Pages\Player\AttackForcesProcessor;
7
use Smr\Pages\Player\ForcesDrop;
8
use Smr\Pages\Player\ForcesDropProcessor;
9
use Smr\Pages\Player\ForcesRefreshAllProcessor;
10
use Smr\Pages\Player\ForcesRefreshProcessor;
11
12
class SmrForce {
13
14
	/** @var array<int, array<int, array<int, self>>> */
15
	protected static array $CACHE_FORCES = [];
16
	/** @var array<int, array<int, array<int, self>>> */
17
	protected static array $CACHE_SECTOR_FORCES = [];
18
	/** @var array<int, array<int, bool>> */
19
	protected static array $TIDIED_UP = [];
20
21
	public const LOWEST_MAX_EXPIRE_SCOUTS_ONLY = 432000; // 5 days
22
	protected const TIME_PER_SCOUT_ONLY = 86400; // 1 = 1 day
23
	protected const TIME_PERCENT_PER_SCOUT = 0.02; // 1/50th
24
	protected const TIME_PERCENT_PER_COMBAT = 0.02; // 1/50th
25
	protected const TIME_PERCENT_PER_MINE = 0.02; // 1/50th
26
	public const REFRESH_ALL_TIME_PER_STACK = 1; // 1 second
27
28
	public const MAX_MINES = 50;
29
	public const MAX_CDS = 50;
30
	public const MAX_SDS = 5;
31
32
	protected Database $db;
33
	protected readonly string $SQL;
34
35
	protected int $combatDrones = 0;
36
	protected int $scoutDrones = 0;
37
	protected int $mines = 0;
38
	protected int $expire = 0;
39
40
	protected bool $isNew;
41
	protected bool $hasChanged = false;
42
43
	public function __sleep() {
44
		return ['ownerID', 'sectorID', 'gameID'];
45
	}
46
47
	public static function clearCache(): void {
48
		self::$CACHE_FORCES = [];
49
		self::$CACHE_SECTOR_FORCES = [];
50
	}
51
52
	public static function saveForces(): void {
53
		foreach (self::$CACHE_FORCES as $gameForces) {
54
			foreach ($gameForces as $gameSectorForces) {
55
				foreach ($gameSectorForces as $forces) {
56
					$forces->update();
57
				}
58
			}
59
		}
60
	}
61
62
	/**
63
	 * @return array<int, array<int, self>>
64
	 */
65
	public static function getGalaxyForces(int $gameID, int $galaxyID, bool $forceUpdate = false): array {
66
		$db = Database::getInstance();
67
		$dbResult = $db->read('SELECT sector_has_forces.* FROM sector_has_forces LEFT JOIN sector USING(game_id, sector_id) WHERE game_id = ' . $db->escapeNumber($gameID) . ' AND galaxy_id = ' . $db->escapeNumber($galaxyID));
68
		$galaxyForces = [];
69
		foreach ($dbResult->records() as $dbRecord) {
70
			$sectorID = $dbRecord->getInt('sector_id');
71
			$ownerID = $dbRecord->getInt('owner_id');
72
			$force = self::getForce($gameID, $sectorID, $ownerID, $forceUpdate, $dbRecord);
73
			self::$CACHE_SECTOR_FORCES[$gameID][$sectorID][$ownerID] = $force;
74
			$galaxyForces[$sectorID][$ownerID] = $force;
75
		}
76
		return $galaxyForces;
77
	}
78
79
	/**
80
	 * @return array<int, self>
81
	 */
82
	public static function getSectorForces(int $gameID, int $sectorID, bool $forceUpdate = false): array {
83
		if ($forceUpdate || !isset(self::$CACHE_SECTOR_FORCES[$gameID][$sectorID])) {
84
			self::tidyUpForces(SmrGalaxy::getGalaxyContaining($gameID, $sectorID));
85
			$db = Database::getInstance();
86
			$dbResult = $db->read('SELECT * FROM sector_has_forces WHERE sector_id = ' . $db->escapeNumber($sectorID) . ' AND game_id=' . $db->escapeNumber($gameID) . ' ORDER BY expire_time ASC');
87
			$forces = [];
88
			foreach ($dbResult->records() as $dbRecord) {
89
				$ownerID = $dbRecord->getInt('owner_id');
90
				$forces[$ownerID] = self::getForce($gameID, $sectorID, $ownerID, $forceUpdate, $dbRecord);
91
			}
92
			self::$CACHE_SECTOR_FORCES[$gameID][$sectorID] = $forces;
93
		}
94
		return self::$CACHE_SECTOR_FORCES[$gameID][$sectorID];
95
	}
96
97
	public static function getForce(int $gameID, int $sectorID, int $ownerID, bool $forceUpdate = false, DatabaseRecord $dbRecord = null): self {
98
		if ($forceUpdate || !isset(self::$CACHE_FORCES[$gameID][$sectorID][$ownerID])) {
99
			self::tidyUpForces(SmrGalaxy::getGalaxyContaining($gameID, $sectorID));
100
			$p = new self($gameID, $sectorID, $ownerID, $dbRecord);
101
			self::$CACHE_FORCES[$gameID][$sectorID][$ownerID] = $p;
102
		}
103
		return self::$CACHE_FORCES[$gameID][$sectorID][$ownerID];
104
	}
105
106
	public static function tidyUpForces(SmrGalaxy $galaxyToTidy): void {
107
		if (!isset(self::$TIDIED_UP[$galaxyToTidy->getGameID()][$galaxyToTidy->getGalaxyID()])) {
108
			self::$TIDIED_UP[$galaxyToTidy->getGameID()][$galaxyToTidy->getGalaxyID()] = true;
109
			$db = Database::getInstance();
110
			$db->write('UPDATE sector_has_forces
111
						SET refresher=0,
112
							expire_time = (refresh_at + if(combat_drones+mines=0,
113
															LEAST(' . $db->escapeNumber(self::LOWEST_MAX_EXPIRE_SCOUTS_ONLY) . ', scout_drones*' . $db->escapeNumber(self::TIME_PER_SCOUT_ONLY) . '),
114
															LEAST(' . $db->escapeNumber($galaxyToTidy->getMaxForceTime()) . ', (combat_drones*' . $db->escapeNumber(self::TIME_PERCENT_PER_COMBAT) . '+scout_drones*' . $db->escapeNumber(self::TIME_PERCENT_PER_SCOUT) . '+mines*' . $db->escapeNumber(self::TIME_PERCENT_PER_MINE) . ')*' . $db->escapeNumber($galaxyToTidy->getMaxForceTime()) . ')
115
														))
116
						WHERE game_id = ' . $db->escapeNumber($galaxyToTidy->getGameID()) . ' AND sector_id >= ' . $db->escapeNumber($galaxyToTidy->getStartSector()) . ' AND sector_id <= ' . $db->escapeNumber($galaxyToTidy->getEndSector()) . ' AND refresher != 0 AND refresh_at <= ' . $db->escapeNumber(Epoch::time()));
117
			$db->write('DELETE FROM sector_has_forces WHERE expire_time < ' . $db->escapeNumber(Epoch::time()));
118
		}
119
	}
120
121
	protected function __construct(
122
		protected readonly int $gameID,
123
		protected readonly int $sectorID,
124
		protected readonly int $ownerID,
125
		DatabaseRecord $dbRecord = null
126
	) {
127
		$this->db = Database::getInstance();
128
		$this->SQL = 'game_id = ' . $this->db->escapeNumber($gameID) . '
0 ignored issues
show
Bug introduced by
The property SQL is declared read-only in SmrForce.
Loading history...
129
		              AND sector_id = ' . $this->db->escapeNumber($sectorID) . '
130
		              AND owner_id = ' . $this->db->escapeNumber($ownerID);
131
132
		if ($dbRecord === null) {
133
			$dbResult = $this->db->read('SELECT * FROM sector_has_forces WHERE ' . $this->SQL);
134
			if ($dbResult->hasRecord()) {
135
				$dbRecord = $dbResult->record();
136
			}
137
		}
138
		$this->isNew = $dbRecord === null;
139
140
		if (!$this->isNew) {
141
			$this->combatDrones = $dbRecord->getInt('combat_drones');
142
			$this->scoutDrones = $dbRecord->getInt('scout_drones');
143
			$this->mines = $dbRecord->getInt('mines');
144
			$this->expire = $dbRecord->getInt('expire_time');
145
		}
146
	}
147
148
	public function exists(): bool {
149
		return ($this->hasCDs() || $this->hasSDs() || $this->hasMines()) && !$this->hasExpired();
150
	}
151
152
	public function hasMaxCDs(): bool {
153
		return $this->getCDs() >= self::MAX_CDS;
154
	}
155
156
	public function hasMaxSDs(): bool {
157
		return $this->getSDs() >= self::MAX_SDS;
158
	}
159
160
	public function hasMaxMines(): bool {
161
		return $this->getMines() >= self::MAX_MINES;
162
	}
163
164
	public function hasCDs(): bool {
165
		return $this->getCDs() > 0;
166
	}
167
168
	public function hasSDs(): bool {
169
		return $this->getSDs() > 0;
170
	}
171
172
	public function hasMines(): bool {
173
		return $this->getMines() > 0;
174
	}
175
176
	public function getCDs(): int {
177
		return $this->combatDrones;
178
	}
179
180
	public function getSDs(): int {
181
		return $this->scoutDrones;
182
	}
183
184
	public function getMines(): int {
185
		return $this->mines;
186
	}
187
188
	public function addMines(int $amount): void {
189
		if ($amount < 0) {
190
			throw new Exception('Cannot add negative mines.');
191
		}
192
		$this->setMines($this->getMines() + $amount);
193
	}
194
195
	public function addCDs(int $amount): void {
196
		if ($amount < 0) {
197
			throw new Exception('Cannot add negative CDs.');
198
		}
199
		$this->setCDs($this->getCDs() + $amount);
200
	}
201
202
	public function addSDs(int $amount): void {
203
		if ($amount < 0) {
204
			throw new Exception('Cannot add negative SDs.');
205
		}
206
		$this->setSDs($this->getSDs() + $amount);
207
	}
208
209
	public function takeMines(int $amount): void {
210
		if ($amount < 0) {
211
			throw new Exception('Cannot take negative mines.');
212
		}
213
		$this->setMines($this->getMines() - $amount);
214
	}
215
216
	public function takeCDs(int $amount): void {
217
		if ($amount < 0) {
218
			throw new Exception('Cannot take negative CDs.');
219
		}
220
		$this->setCDs($this->getCDs() - $amount);
221
	}
222
223
	public function takeSDs(int $amount): void {
224
		if ($amount < 0) {
225
			throw new Exception('Cannot take negative SDs.');
226
		}
227
		$this->setSDs($this->getSDs() - $amount);
228
	}
229
230
	public function setMines(int $amount): void {
231
		if ($amount < 0) {
232
			throw new Exception('Cannot set negative mines.');
233
		}
234
		if ($amount == $this->getMines()) {
235
			return;
236
		}
237
		$this->hasChanged = true;
238
		$this->mines = $amount;
239
	}
240
241
	public function setCDs(int $amount): void {
242
		if ($amount < 0) {
243
			throw new Exception('Cannot set negative CDs.');
244
		}
245
		if ($amount == $this->getCDs()) {
246
			return;
247
		}
248
		$this->hasChanged = true;
249
		$this->combatDrones = $amount;
250
	}
251
252
	public function setSDs(int $amount): void {
253
		if ($amount < 0) {
254
			throw new Exception('Cannot set negative SDs.');
255
		}
256
		if ($amount == $this->getSDs()) {
257
			return;
258
		}
259
		$this->hasChanged = true;
260
		$this->scoutDrones = $amount;
261
	}
262
263
	public function hasExpired(): bool {
264
		return $this->expire < Epoch::time();
265
	}
266
267
	public function getExpire(): int {
268
		return $this->expire;
269
	}
270
271
	public function setExpire(int $time): void {
272
		if ($time < 0) {
273
			throw new Exception('Cannot set negative expiry.');
274
		}
275
		if ($time == $this->getExpire()) {
276
			return;
277
		}
278
		if ($time > Epoch::time() + $this->getMaxExpireTime()) {
279
			$time = Epoch::time() + $this->getMaxExpireTime();
280
		}
281
		$this->hasChanged = true;
282
		$this->expire = $time;
283
		if (!$this->isNew) {
284
			$this->update();
285
		}
286
	}
287
288
	public function updateExpire(): void {
289
		// Changed (26/10/05) - scout drones count * 2
290
		if ($this->getCDs() == 0 && $this->getMines() == 0 && $this->getSDs() > 0) {
291
			$time = self::TIME_PER_SCOUT_ONLY * $this->getSDs();
292
		} else {
293
			$time = ($this->getCDs() * self::TIME_PERCENT_PER_COMBAT + $this->getSDs() * self::TIME_PERCENT_PER_SCOUT + $this->getMines() * self::TIME_PERCENT_PER_MINE) * $this->getMaxGalaxyExpireTime();
294
		}
295
		$this->setExpire(Epoch::time() + IFloor($time));
0 ignored issues
show
Bug introduced by
The function IFloor was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

295
		$this->setExpire(Epoch::time() + /** @scrutinizer ignore-call */ IFloor($time));
Loading history...
296
	}
297
298
	public function getMaxExpireTime(): int {
299
		if ($this->hasCDs() || $this->hasMines()) {
300
			return $this->getMaxGalaxyExpireTime();
301
		}
302
		if ($this->hasSDs()) {
303
			return max(self::LOWEST_MAX_EXPIRE_SCOUTS_ONLY, $this->getMaxGalaxyExpireTime());
304
		}
305
		return 0;
306
	}
307
308
	public function getMaxGalaxyExpireTime(): int {
309
		return $this->getGalaxy()->getMaxForceTime();
310
	}
311
312
	public function getBumpTurnCost(AbstractSmrShip $ship): int {
313
		$mines = $this->getMines();
314
		if ($mines <= 1) {
315
			return 0;
316
		}
317
		if ($mines < 10) {
318
			$turns = 1;
319
		} elseif ($mines < 25) {
320
			$turns = 2;
321
		} else {
322
			$turns = 3;
323
		}
324
		if ($ship->isFederal() || $ship->hasDCS()) {
325
			$turns -= 1;
326
		}
327
		return $turns;
328
	}
329
330
	public function getAttackTurnCost(AbstractSmrShip $ship): int {
331
		if ($ship->isFederal() || $ship->hasDCS()) {
332
			return 2;
333
		}
334
		return 3;
335
	}
336
337
	public function getOwnerID(): int {
338
		return $this->ownerID;
339
	}
340
341
	public function getGameID(): int {
342
		return $this->gameID;
343
	}
344
345
	public function getSector(): SmrSector {
346
		return SmrSector::getSector($this->getGameID(), $this->getSectorID());
347
	}
348
349
	public function getSectorID(): int {
350
		return $this->sectorID;
351
	}
352
353
	public function ping(string $pingMessage, AbstractSmrPlayer $playerPinging, bool $skipCheck = false): void {
354
		if (!$this->hasSDs() && !$skipCheck) {
355
			return;
356
		}
357
		$owner = $this->getOwner();
358
		if (!$playerPinging->sameAlliance($owner)) {
359
			$playerPinging->sendMessage($owner->getAccountID(), MSG_SCOUT, $pingMessage, false);
360
		}
361
	}
362
363
	public function getGalaxy(): SmrGalaxy {
364
		return SmrGalaxy::getGalaxyContaining($this->getGameID(), $this->getSectorID());
365
	}
366
367
	public function getOwner(): AbstractSmrPlayer {
368
		return SmrPlayer::getPlayer($this->getOwnerID(), $this->getGameID());
369
	}
370
371
	public function update(): void {
372
		if (!$this->isNew) {
373
			if (!$this->exists()) {
374
				$this->db->write('DELETE FROM sector_has_forces WHERE ' . $this->SQL);
375
				$this->isNew = true;
376
			} elseif ($this->hasChanged) {
377
				$this->db->write('UPDATE sector_has_forces SET combat_drones = ' . $this->db->escapeNumber($this->combatDrones) . ', scout_drones = ' . $this->db->escapeNumber($this->scoutDrones) . ', mines = ' . $this->db->escapeNumber($this->mines) . ', expire_time = ' . $this->db->escapeNumber($this->expire) . ' WHERE ' . $this->SQL);
378
			}
379
		} elseif ($this->exists()) {
380
			$this->db->insert('sector_has_forces', [
381
				'game_id' => $this->db->escapeNumber($this->gameID),
382
				'sector_id' => $this->db->escapeNumber($this->sectorID),
383
				'owner_id' => $this->db->escapeNumber($this->ownerID),
384
				'combat_drones' => $this->db->escapeNumber($this->combatDrones),
385
				'scout_drones' => $this->db->escapeNumber($this->scoutDrones),
386
				'mines' => $this->db->escapeNumber($this->mines),
387
				'expire_time' => $this->db->escapeNumber($this->expire),
388
			]);
389
			$this->isNew = false;
390
		}
391
		// This instance is now in sync with the database
392
		$this->hasChanged = false;
393
	}
394
395
	/**
396
	 * Update the table fields associated with using Refresh All
397
	 */
398
	public function updateRefreshAll(AbstractSmrPlayer $player, int $refreshTime): void {
399
		$this->db->write('UPDATE sector_has_forces SET refresh_at=' . $this->db->escapeNumber($refreshTime) . ', refresher=' . $this->db->escapeNumber($player->getAccountID()) . ' WHERE ' . $this->SQL);
400
	}
401
402
	public function getExamineDropForcesHREF(): string {
403
		$container = new ForcesDrop($this->getOwnerID());
404
		return $container->href();
405
	}
406
407
	public function getAttackForcesHREF(): string {
408
		$container = new AttackForcesProcessor($this->getOwnerID());
409
		return $container->href();
410
	}
411
412
	public function getRefreshHREF(): string {
413
		$container = new ForcesRefreshProcessor($this->getOwnerID());
414
		return $container->href();
415
	}
416
417
	public function getDropSDHREF(): string {
418
		$container = new ForcesDropProcessor($this->getOwnerID(), dropSDs: 1);
419
		return $container->href();
420
	}
421
422
	public function getTakeSDHREF(): string {
423
		$container = new ForcesDropProcessor($this->getOwnerID(), takeSDs: 1);
424
		return $container->href();
425
	}
426
427
	public function getDropCDHREF(): string {
428
		$container = new ForcesDropProcessor($this->getOwnerID(), dropCDs: 1);
429
		return $container->href();
430
	}
431
432
	public function getTakeCDHREF(): string {
433
		$container = new ForcesDropProcessor($this->getOwnerID(), takeCDs: 1);
434
		return $container->href();
435
	}
436
437
	public function getDropMineHREF(): string {
438
		$container = new ForcesDropProcessor($this->getOwnerID(), dropMines: 1);
439
		return $container->href();
440
	}
441
442
	public function getTakeMineHREF(): string {
443
		$container = new ForcesDropProcessor($this->getOwnerID(), takeMines: 1);
444
		return $container->href();
445
	}
446
447
	public static function getRefreshAllHREF(): string {
448
		$container = new ForcesRefreshAllProcessor();
449
		return $container->href();
450
	}
451
452
	/**
453
	 * @param array<AbstractSmrPlayer> $targetPlayers
454
	 * @return array<string, mixed>
455
	 */
456
	public function shootPlayers(array $targetPlayers, bool $minesAreAttacker): array {
457
		$results = ['TotalDamage' => 0];
458
		if (!$this->exists()) {
459
			$results['DeadBeforeShot'] = true;
460
			return $results;
461
		}
462
		$results['DeadBeforeShot'] = false;
463
464
		if ($this->hasMines()) {
465
			$thisMines = new SmrMines($this->getMines());
466
			$results['Results']['Mines'] = $thisMines->shootPlayerAsForce($this, array_rand_value($targetPlayers), $minesAreAttacker);
0 ignored issues
show
Bug introduced by
The function array_rand_value was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

466
			$results['Results']['Mines'] = $thisMines->shootPlayerAsForce($this, /** @scrutinizer ignore-call */ array_rand_value($targetPlayers), $minesAreAttacker);
Loading history...
467
			$this->setMines($thisMines->getAmount()); // kamikaze
468
			$results['TotalDamage'] += $results['Results']['Mines']['ActualDamage']['TotalDamage'];
469
		}
470
471
		if ($this->hasCDs()) {
472
			$thisCDs = new SmrCombatDrones($this->getCDs());
473
			$results['Results']['Drones'] = $thisCDs->shootPlayerAsForce($this, array_rand_value($targetPlayers));
474
			$results['TotalDamage'] += $results['Results']['Drones']['ActualDamage']['TotalDamage'];
475
		}
476
477
		if (!$minesAreAttacker) {
478
			if ($this->hasSDs()) {
479
				$thisSDs = new SmrScoutDrones($this->getSDs());
480
				$results['Results']['Scouts'] = $thisSDs->shootPlayerAsForce($this, array_rand_value($targetPlayers));
481
				$this->setSDs($thisSDs->getAmount()); // kamikaze
482
				$results['TotalDamage'] += $results['Results']['Scouts']['ActualDamage']['TotalDamage'];
483
			}
484
		}
485
486
		$results['ForcesDestroyed'] = !$this->exists();
487
		return $results;
488
	}
489
490
	/**
491
	 * @param array<string, int|bool> $damage
492
	 * @return array<string, int|bool>
493
	 */
494
	public function takeDamage(array $damage): array {
495
		$alreadyDead = !$this->exists();
496
		$minesDamage = 0;
497
		$cdDamage = 0;
498
		$sdDamage = 0;
499
		if (!$alreadyDead) {
500
			$minesDamage = $this->takeDamageToMines($damage['Armour']);
0 ignored issues
show
Bug introduced by
It seems like $damage['Armour'] can also be of type boolean; however, parameter $damage of SmrForce::takeDamageToMines() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

500
			$minesDamage = $this->takeDamageToMines(/** @scrutinizer ignore-type */ $damage['Armour']);
Loading history...
501
			if (!$this->hasMines() && ($minesDamage == 0 || $damage['Rollover'])) {
502
				$cdMaxDamage = $damage['Armour'] - $minesDamage;
503
				$cdDamage = $this->takeDamageToCDs($cdMaxDamage);
504
				if (!$this->hasCDs() && ($cdDamage == 0 || $damage['Rollover'])) {
505
					$sdMaxDamage = $damage['Armour'] - $minesDamage - $cdDamage;
506
					$sdDamage = $this->takeDamageToSDs($sdMaxDamage);
507
				}
508
			}
509
		}
510
		$return = [
511
						'KillingShot' => !$alreadyDead && !$this->exists(),
512
						'TargetAlreadyDead' => $alreadyDead,
513
						'Mines' => $minesDamage,
514
						'NumMines' => $minesDamage / MINE_ARMOUR,
515
						'HasMines' => $this->hasMines(),
516
						'CDs' => $cdDamage,
517
						'NumCDs' => $cdDamage / CD_ARMOUR,
518
						'HasCDs' => $this->hasCDs(),
519
						'SDs' => $sdDamage,
520
						'NumSDs' => $sdDamage / SD_ARMOUR,
521
						'HasSDs' => $this->hasSDs(),
522
						'TotalDamage' => $minesDamage + $cdDamage + $sdDamage,
523
		];
524
		return $return;
525
	}
526
527
	protected function takeDamageToMines(int $damage): int {
528
		$actualDamage = min($this->getMines(), IFloor($damage / MINE_ARMOUR));
0 ignored issues
show
Bug introduced by
The function IFloor was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

528
		$actualDamage = min($this->getMines(), /** @scrutinizer ignore-call */ IFloor($damage / MINE_ARMOUR));
Loading history...
529
		$this->takeMines($actualDamage);
530
		return $actualDamage * MINE_ARMOUR;
531
	}
532
533
	protected function takeDamageToCDs(int $damage): int {
534
		$actualDamage = min($this->getCDs(), IFloor($damage / CD_ARMOUR));
0 ignored issues
show
Bug introduced by
The function IFloor was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

534
		$actualDamage = min($this->getCDs(), /** @scrutinizer ignore-call */ IFloor($damage / CD_ARMOUR));
Loading history...
535
		$this->takeCDs($actualDamage);
536
		return $actualDamage * CD_ARMOUR;
537
	}
538
539
	protected function takeDamageToSDs(int $damage): int {
540
		$actualDamage = min($this->getSDs(), IFloor($damage / SD_ARMOUR));
0 ignored issues
show
Bug introduced by
The function IFloor was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

540
		$actualDamage = min($this->getSDs(), /** @scrutinizer ignore-call */ IFloor($damage / SD_ARMOUR));
Loading history...
541
		$this->takeSDs($actualDamage);
542
		return $actualDamage * SD_ARMOUR;
543
	}
544
545
	/**
546
	 * @return array<string, mixed>
547
	 */
548
	public function killForcesByPlayer(AbstractSmrPlayer $killer): array {
0 ignored issues
show
Unused Code introduced by
The parameter $killer is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

548
	public function killForcesByPlayer(/** @scrutinizer ignore-unused */ AbstractSmrPlayer $killer): array {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
549
		return [];
550
	}
551
552
}
553