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

Passed
Pull Request — master (#1006)
by Dan
15:04
created

SmrForce::getTakeSDHREF()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php declare(strict_types=1);
2
3
class SmrForce {
4
	protected static $CACHE_FORCES = array();
5
	protected static $CACHE_SECTOR_FORCES = array();
6
	protected static $TIDIED_UP = array();
7
8
	const LOWEST_MAX_EXPIRE_SCOUTS_ONLY = 432000; // 5 days
9
	const TIME_PER_SCOUT_ONLY = 86400; // 1 = 1 day
10
	const TIME_PERCENT_PER_SCOUT = 0.02; // 1/50th
11
	const TIME_PERCENT_PER_COMBAT = 0.02; // 1/50th
12
	const TIME_PERCENT_PER_MINE = 0.02; // 1/50th
13
	const REFRESH_ALL_TIME_PER_STACK = 1; // 1 second
14
15
	protected static $refreshAllHREF;
16
17
	protected $db;
18
	protected $SQL;
19
20
	protected $ownerID;
21
	protected $sectorID;
22
	protected $gameID;
23
	protected $combatDrones = 0;
24
	protected $scoutDrones = 0;
25
	protected $mines = 0;
26
	protected $expire = 0;
27
28
	protected $isNew;
29
	protected $hasChanged = false;
30
31
	public function __sleep() {
32
		return ['ownerID', 'sectorID', 'gameID'];
33
	}
34
35
	public static function refreshCache() {
36
		foreach (self::$CACHE_FORCES as $gameID => &$gameForces) {
37
			foreach ($gameForces as $sectorID => &$gameSectorForces) {
38
				foreach ($gameSectorForces as $ownerID => &$forces) {
39
					$forces = self::getForce($gameID, $sectorID, $ownerID, true);
40
				}
41
			}
42
		}
43
	}
44
45
	public static function clearCache() {
46
		self::$CACHE_FORCES = array();
47
		self::$CACHE_SECTOR_FORCES = array();
48
	}
49
50
	public static function saveForces() {
51
		foreach (self::$CACHE_FORCES as $gameForces) {
52
			foreach ($gameForces as $gameSectorForces) {
53
				foreach ($gameSectorForces as $forces) {
54
					$forces->update();
55
				}
56
			}
57
		}
58
	}
59
60
	public static function getGalaxyForces($gameID, $galaxyID, $forceUpdate = false) {
61
		$db = MySqlDatabase::getInstance();
62
		$db->query('SELECT sector_has_forces.*, sector_id FROM sector LEFT JOIN sector_has_forces USING(game_id, sector_id) WHERE game_id = ' . $db->escapeNumber($gameID) . ' AND galaxy_id = ' . $db->escapeNumber($galaxyID));
63
		$galaxyForces = [];
64
		while ($db->nextRecord()) {
65
			$sectorID = $db->getInt('sector_id');
66
			if (!$db->hasField('owner_id')) {
67
				self::$CACHE_SECTOR_FORCES[$gameID][$sectorID] = [];
68
			} else {
69
				$ownerID = $db->getInt('owner_id');
70
				$force = self::getForce($gameID, $sectorID, $ownerID, $forceUpdate, $db);
71
				self::$CACHE_SECTOR_FORCES[$gameID][$sectorID][$ownerID] = $force;
72
				$galaxyForces[$sectorID][$ownerID] = $force;
73
			}
74
		}
75
		return $galaxyForces;
76
	}
77
78
	public static function getSectorForces($gameID, $sectorID, $forceUpdate = false) {
79
		if ($forceUpdate || !isset(self::$CACHE_SECTOR_FORCES[$gameID][$sectorID])) {
80
			self::tidyUpForces(SmrGalaxy::getGalaxyContaining($gameID, $sectorID));
81
			$db = MySqlDatabase::getInstance();
82
			$db->query('SELECT * FROM sector_has_forces WHERE sector_id = ' . $db->escapeNumber($sectorID) . ' AND game_id=' . $db->escapeNumber($gameID) . ' ORDER BY expire_time ASC');
83
			$forces = array();
84
			while ($db->nextRecord()) {
85
				$ownerID = $db->getInt('owner_id');
86
				$forces[$ownerID] = self::getForce($gameID, $sectorID, $ownerID, $forceUpdate, $db);
87
			}
88
			self::$CACHE_SECTOR_FORCES[$gameID][$sectorID] = $forces;
89
		}
90
		return self::$CACHE_SECTOR_FORCES[$gameID][$sectorID];
91
	}
92
93
	public static function getForce($gameID, $sectorID, $ownerID, $forceUpdate = false, $db = null) {
94
		if ($forceUpdate || !isset(self::$CACHE_FORCES[$gameID][$sectorID][$ownerID])) {
95
			self::tidyUpForces(SmrGalaxy::getGalaxyContaining($gameID, $sectorID));
96
			$p = new SmrForce($gameID, $sectorID, $ownerID, $db);
97
			self::$CACHE_FORCES[$gameID][$sectorID][$ownerID] = $p;
98
		}
99
		return self::$CACHE_FORCES[$gameID][$sectorID][$ownerID];
100
	}
101
102
	public static function tidyUpForces(SmrGalaxy $galaxyToTidy) {
103
		if (!isset(self::$TIDIED_UP[$galaxyToTidy->getGameID()][$galaxyToTidy->getGalaxyID()])) {
104
			self::$TIDIED_UP[$galaxyToTidy->getGameID()][$galaxyToTidy->getGalaxyID()] = true;
105
			$db = MySqlDatabase::getInstance();
106
			$db->query('UPDATE sector_has_forces
107
						SET refresher=0,
108
							expire_time = (refresh_at + if(combat_drones+mines=0,
109
															LEAST('.$db->escapeNumber(self::LOWEST_MAX_EXPIRE_SCOUTS_ONLY) . ', scout_drones*' . $db->escapeNumber(self::TIME_PER_SCOUT_ONLY) . '),
110
															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()) . ')
111
														))
112
						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(SmrSession::getTime()));
113
			$db->query('DELETE FROM sector_has_forces WHERE expire_time < ' . $db->escapeNumber(SmrSession::getTime()));
114
		}
115
	}
116
117
	protected function __construct($gameID, $sectorID, $ownerID, $db = null) {
118
		$this->db = MySqlDatabase::getInstance();
119
		$this->SQL = 'game_id = ' . $this->db->escapeNumber($gameID) . '
120
		              AND sector_id = '.$this->db->escapeNumber($sectorID) . '
121
		              AND owner_id = '.$this->db->escapeNumber($ownerID);
122
123
		if (isset($db)) {
124
			$this->isNew = false;
125
		} else {
126
			$db = $this->db;
127
			$this->db->query('SELECT * FROM sector_has_forces WHERE ' . $this->SQL);
128
			$this->isNew = !$db->nextRecord();
129
		}
130
131
		$this->gameID = $gameID;
132
		$this->ownerID = $ownerID;
133
		$this->sectorID = $sectorID;
134
		if (!$this->isNew) {
135
			$this->combatDrones = $db->getInt('combat_drones');
136
			$this->scoutDrones = $db->getInt('scout_drones');
137
			$this->mines = $db->getInt('mines');
138
			$this->expire = $db->getInt('expire_time');
139
		}
140
	}
141
142
	public function exists() {
143
		return ($this->hasCDs() || $this->hasSDs() || $this->hasMines()) && !$this->hasExpired();
144
	}
145
146
	public function canAcceptCDs() {
147
		return $this->getCDs() < 50;
148
	}
149
150
	public function canAcceptSDs() {
151
		return $this->getSDs() < 5;
152
	}
153
154
	public function canAcceptMines() {
155
		return $this->getMines() < 50;
156
	}
157
158
	public function hasCDs() {
159
		return $this->getCDs() > 0;
160
	}
161
162
	public function hasSDs() {
163
		return $this->getSDs() > 0;
164
	}
165
166
	public function hasMines() {
167
		return $this->getMines() > 0;
168
	}
169
170
	public function getCDs() {
171
		return $this->combatDrones;
172
	}
173
174
	public function getSDs() {
175
		return $this->scoutDrones;
176
	}
177
178
	public function getMines() {
179
		return $this->mines;
180
	}
181
182
	public function addMines($amount) {
183
		if ($amount < 0) {
184
			throw new Exception('Cannot add negative mines.');
185
		}
186
		$this->setMines($this->getMines() + $amount);
187
	}
188
189
	public function addCDs($amount) {
190
		if ($amount < 0) {
191
			throw new Exception('Cannot add negative CDs.');
192
		}
193
		$this->setCDs($this->getCDs() + $amount);
194
	}
195
196
	public function addSDs($amount) {
197
		if ($amount < 0) {
198
			throw new Exception('Cannot add negative SDs.');
199
		}
200
		$this->setSDs($this->getSDs() + $amount);
201
	}
202
203
	public function takeMines($amount) {
204
		if ($amount < 0) {
205
			throw new Exception('Cannot take negative mines.');
206
		}
207
		$this->setMines($this->getMines() - $amount);
208
	}
209
210
	public function takeCDs($amount) {
211
		if ($amount < 0) {
212
			throw new Exception('Cannot take negative CDs.');
213
		}
214
		$this->setCDs($this->getCDs() - $amount);
215
	}
216
217
	public function takeSDs($amount) {
218
		if ($amount < 0) {
219
			throw new Exception('Cannot take negative SDs.');
220
		}
221
		$this->setSDs($this->getSDs() - $amount);
222
	}
223
224
	public function setMines($amount) {
225
		if ($amount < 0) {
226
			throw new Exception('Cannot set negative mines.');
227
		}
228
		if ($amount == $this->getMines()) {
229
			return;
230
		}
231
		$this->hasChanged = true;
232
		$this->mines = $amount;
233
	}
234
235
	public function setCDs($amount) {
236
		if ($amount < 0) {
237
			throw new Exception('Cannot set negative CDs.');
238
		}
239
		if ($amount == $this->getCDs()) {
240
			return;
241
		}
242
		$this->hasChanged = true;
243
		$this->combatDrones = $amount;
244
	}
245
246
	public function setSDs($amount) {
247
		if ($amount < 0) {
248
			throw new Exception('Cannot set negative SDs.');
249
		}
250
		if ($amount == $this->getSDs()) {
251
			return;
252
		}
253
		$this->hasChanged = true;
254
		$this->scoutDrones = $amount;
255
	}
256
257
	public function hasExpired() {
258
		return $this->expire < SmrSession::getTime();
259
	}
260
261
	public function getExpire() {
262
		return $this->expire;
263
	}
264
265
	public function setExpire($time) {
266
		if ($time < 0) {
267
			throw new Exception('Cannot set negative expiry.');
268
		}
269
		if ($time == $this->getExpire()) {
270
			return;
271
		}
272
		if ($time > SmrSession::getTime() + $this->getMaxExpireTime()) {
273
			$time = SmrSession::getTime() + $this->getMaxExpireTime();
274
		}
275
		$this->hasChanged = true;
276
		$this->expire = $time;
277
		if (!$this->isNew) {
278
			$this->update();
279
		}
280
	}
281
282
	public function updateExpire() {
283
		// Changed (26/10/05) - scout drones count * 2
284
		if ($this->getCDs() == 0 && $this->getMines() == 0 && $this->getSDs() > 0) {
285
			$time = self::TIME_PER_SCOUT_ONLY * $this->getSDs();
286
		} else {
287
			$time = ($this->getCDs() * self::TIME_PERCENT_PER_COMBAT + $this->getSDs() * self::TIME_PERCENT_PER_SCOUT + $this->getMines() * self::TIME_PERCENT_PER_MINE) * $this->getMaxGalaxyExpireTime();
288
		}
289
		$this->setExpire(SmrSession::getTime() + $time);
290
	}
291
292
	public function getMaxExpireTime() {
293
		if ($this->hasCDs() || $this->hasMines()) {
294
			return $this->getMaxGalaxyExpireTime();
295
		}
296
		if (!$this->hasCDs() && !$this->hasMines() && $this->hasSDs()) {
297
			return max(self::LOWEST_MAX_EXPIRE_SCOUTS_ONLY, $this->getMaxGalaxyExpireTime());
298
		}
299
		return 0;
300
	}
301
302
	public function getMaxGalaxyExpireTime() {
303
		return $this->getGalaxy()->getMaxForceTime();
304
	}
305
306
	public function getBumpTurnCost(AbstractSmrShip $ship) {
307
		$mines = $this->getMines();
308
		if ($mines <= 1) {
309
			return 0;
310
		}
311
		if ($mines < 10) {
312
			$turns = 1;
313
		} elseif ($mines < 25) {
314
			$turns = 2;
315
		} else {
316
			$turns = 3;
317
		}
318
		if ($ship->isFederal() || $ship->hasDCS()) {
319
			$turns -= 1;
320
		}
321
		return $turns;
322
	}
323
324
	public function getAttackTurnCost(AbstractSmrShip $ship) {
325
		if ($ship->isFederal() || $ship->hasDCS()) {
326
			return 2;
327
		}
328
		return 3;
329
	}
330
331
	public function getOwnerID() {
332
		return $this->ownerID;
333
	}
334
335
	public function getGameID() {
336
		return $this->gameID;
337
	}
338
339
	public function getSector() {
340
		return SmrSector::getSector($this->getGameID(), $this->getSectorID());
341
	}
342
343
	public function getSectorID() {
344
		return $this->sectorID;
345
	}
346
347
	public function ping($pingMessage, AbstractSmrPlayer $playerPinging, $skipCheck = false) {
348
		if (!$this->hasSDs() && !$skipCheck) {
349
			return;
350
		}
351
		$owner = $this->getOwner();
352
		if (!$playerPinging->sameAlliance($owner)) {
353
			$playerPinging->sendMessage($owner->getAccountID(), MSG_SCOUT, $pingMessage, false);
354
		}
355
	}
356
357
	public function getGalaxy() {
358
		return SmrGalaxy::getGalaxyContaining($this->getGameID(), $this->getSectorID());
359
	}
360
361
	public function getOwner() {
362
		return SmrPlayer::getPlayer($this->getOwnerID(), $this->getGameID());
363
	}
364
365
	public function update() {
366
		if (!$this->isNew) {
367
			if (!$this->exists()) {
368
				$this->db->query('DELETE FROM sector_has_forces WHERE ' . $this->SQL);
369
				$this->isNew = true;
370
			} elseif ($this->hasChanged) {
371
				$this->db->query('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);
372
			}
373
		} elseif ($this->exists()) {
374
			$this->db->query('INSERT INTO sector_has_forces (game_id, sector_id, owner_id, combat_drones, scout_drones, mines, expire_time)
375
								VALUES('.$this->db->escapeNumber($this->gameID) . ', ' . $this->db->escapeNumber($this->sectorID) . ', ' . $this->db->escapeNumber($this->ownerID) . ', ' . $this->db->escapeNumber($this->combatDrones) . ', ' . $this->db->escapeNumber($this->scoutDrones) . ', ' . $this->db->escapeNumber($this->mines) . ', ' . $this->db->escapeNumber($this->expire) . ')');
376
			$this->isNew = false;
377
		}
378
		// This instance is now in sync with the database
379
		$this->hasChanged = false;
380
	}
381
382
	/**
383
	 * Update the table fields associated with using Refresh All
384
	 */
385
	public function updateRefreshAll(SmrPlayer $player, $refreshTime) {
386
		$this->db->query('UPDATE sector_has_forces SET refresh_at=' . $this->db->escapeNumber($refreshTime) . ', refresher=' . $this->db->escapeNumber($player->getAccountID()) . ' WHERE ' . $this->SQL);
387
	}
388
389
	public function getExamineDropForcesHREF() {
390
		$container = create_container('skeleton.php', 'forces_drop.php');
391
		$container['owner_id'] = $this->getOwnerID();
392
		return SmrSession::getNewHREF($container);
393
	}
394
395
	public function getAttackForcesHREF() {
396
		$container = create_container('forces_attack_processing.php');
397
		$container['action'] = 'attack';
398
		$container['owner_id'] = $this->getOwnerID();
399
		return SmrSession::getNewHREF($container);
400
	}
401
402
	public function getRefreshHREF() {
403
		$container = create_container('forces_refresh_processing.php');
404
		$container['owner_id'] = $this->getOwnerID();
405
		return SmrSession::getNewHREF($container);
406
	}
407
408
	protected function getDropContainer() {
409
		return array('url' => 'forces_drop_processing.php', 'owner_id' => $this->getOwnerID());
410
	}
411
412
	public function getDropSDHREF() {
413
		$container = $this->getDropContainer();
414
		$container['drop_scout_drones'] = 1;
415
		return SmrSession::getNewHREF($container);
416
	}
417
418
	public function getTakeSDHREF() {
419
		$container = $this->getDropContainer();
420
		$container['take_scout_drones'] = 1;
421
		return SmrSession::getNewHREF($container);
422
	}
423
424
	public function getDropCDHREF() {
425
		$container = $this->getDropContainer();
426
		$container['drop_combat_drones'] = 1;
427
		return SmrSession::getNewHREF($container);
428
	}
429
430
	public function getTakeCDHREF() {
431
		$container = $this->getDropContainer();
432
		$container['take_combat_drones'] = 1;
433
		return SmrSession::getNewHREF($container);
434
	}
435
436
	public function getDropMineHREF() {
437
		$container = $this->getDropContainer();
438
		$container['drop_mines'] = 1;
439
		return SmrSession::getNewHREF($container);
440
	}
441
442
	public function getTakeMineHREF() {
443
		$container = $this->getDropContainer();
444
		$container['take_mines'] = 1;
445
		return SmrSession::getNewHREF($container);
446
	}
447
448
	public static function getRefreshAllHREF() {
449
		$container = create_container('forces_mass_refresh.php');
450
		return SmrSession::getNewHREF($container);
451
	}
452
453
	public function shootPlayers(array $targetPlayers, $minesAreAttacker) {
454
		$results = array('TotalDamage' => 0);
455
		if (!$this->exists()) {
456
			$results['DeadBeforeShot'] = true;
457
			return $results;
458
		}
459
		$results['DeadBeforeShot'] = false;
460
461
		if ($this->hasMines()) {
462
			$thisMines = new SmrMines($this->getGameID(), $this->getMines());
463
			$results['Results']['Mines'] = $thisMines->shootPlayerAsForce($this, array_rand_value($targetPlayers), $minesAreAttacker);
464
			$results['TotalDamage'] += $results['Results']['Mines']['ActualDamage']['TotalDamage'];
465
		}
466
467
		if ($this->hasCDs()) {
468
			$thisCDs = new SmrCombatDrones($this->getGameID(), $this->getCDs());
469
			$results['Results']['Drones'] = $thisCDs->shootPlayerAsForce($this, array_rand_value($targetPlayers));
470
			$results['TotalDamage'] += $results['Results']['Drones']['ActualDamage']['TotalDamage'];
471
		}
472
473
		if (!$minesAreAttacker) {
474
			if ($this->hasSDs()) {
475
				$thisSDs = new SmrScoutDrones($this->getGameID(), $this->getSDs());
476
				$results['Results']['Scouts'] = $thisSDs->shootPlayerAsForce($this, array_rand_value($targetPlayers));
477
				$results['TotalDamage'] += $results['Results']['Scouts']['ActualDamage']['TotalDamage'];
478
			}
479
		}
480
481
		$results['ForcesDestroyed'] = !$this->exists();
482
		return $results;
483
	}
484
485
	public function doWeaponDamage(array $damage) {
486
		$alreadyDead = !$this->exists();
487
		$minesDamage = 0;
488
		$cdDamage = 0;
489
		$sdDamage = 0;
490
		if (!$alreadyDead) {
491
			$minesDamage = $this->doMinesDamage(min($damage['MaxDamage'], $damage['Armour']));
492
			$damage['Armour'] -= $minesDamage;
493
			$damage['MaxDamage'] -= $minesDamage;
494
			if (!$this->hasMines() && ($minesDamage == 0 || $damage['Rollover'])) {
495
				$cdDamage = $this->doCDDamage(min($damage['MaxDamage'], $damage['Armour']));
496
				$damage['Armour'] -= $cdDamage;
497
				$damage['MaxDamage'] -= $cdDamage;
498
				if (!$this->hasCDs() && ($cdDamage == 0 || $damage['Rollover'])) {
499
					$sdDamage = $this->doSDDamage(min($damage['MaxDamage'], $damage['Armour']));
500
				}
501
			}
502
		}
503
		$return = array(
504
						'KillingShot' => !$alreadyDead && !$this->exists(),
505
						'TargetAlreadyDead' => $alreadyDead,
506
						'Mines' => $minesDamage,
507
						'NumMines' => $minesDamage / MINE_ARMOUR,
508
						'HasMines' => $this->hasMines(),
509
						'CDs' => $cdDamage,
510
						'NumCDs' => $cdDamage / CD_ARMOUR,
511
						'HasCDs' => $this->hasCDs(),
512
						'SDs' => $sdDamage,
513
						'NumSDs' => $sdDamage / SD_ARMOUR,
514
						'HasSDs' => $this->hasSDs(),
515
						'TotalDamage' => $minesDamage + $cdDamage + $sdDamage
516
		);
517
		return $return;
518
	}
519
520
	protected function doMinesDamage($damage) {
521
		$actualDamage = min($this->getMines(), IFloor($damage / MINE_ARMOUR));
522
		$this->takeMines($actualDamage);
523
		return $actualDamage * MINE_ARMOUR;
524
	}
525
526
	protected function doCDDamage($damage) {
527
		$actualDamage = min($this->getCDs(), IFloor($damage / CD_ARMOUR));
528
		$this->takeCDs($actualDamage);
529
		return $actualDamage * CD_ARMOUR;
530
	}
531
532
	protected function doSDDamage($damage) {
533
		$actualDamage = min($this->getSDs(), IFloor($damage / SD_ARMOUR));
534
		$this->takeSDs($actualDamage);
535
		return $actualDamage * SD_ARMOUR;
536
	}
537
538
	public function killForcesByPlayer(AbstractSmrPlayer $killer) {
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

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

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...
539
		$return = array();
540
		return $return;
541
	}
542
}
543