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 (#928)
by Dan
04:27
created

getDurationRemainingPercent()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 2
rs 10
1
<?php declare(strict_types=1);
2
3
/**
4
 * Defines enhanced weapon sale events for weapon shops.
5
 */
6
class SmrEnhancedWeaponEvent {
7
8
	const GRACE_PERIOD = 3600; // 1 hour
9
	const DURATION = 21600; // 6 hours
10
11
	protected int $gameID;
12
	protected int $sectorID;
13
	protected int $locationTypeID;
14
	protected int $expires;
15
	protected SmrWeapon $weapon;
16
17
	/**
18
	 * Return all the valid events for the given location in a sector.
19
	 */
20
	public static function getShopEvents(int $gameID, int $sectorID, int $locationID) : array {
21
		$events = [];
22
		$db = new SmrMySqlDatabase();
23
		$db->query('SELECT * FROM location_sells_special WHERE sector_id = ' . $db->escapeNumber($sectorID) . ' AND location_type_id = ' . $db->escapeNumber($locationID) . ' AND game_id = ' . $db->escapeNumber($gameID) . ' AND expires > ' . $db->escapeNumber(TIME));
24
		while ($db->nextRecord()) {
25
			$events[] = self::getEventFromDatabase($db);
26
		}
27
		return $events;
28
	}
29
30
	/**
31
	 * Get the most recent event.
32
	 *
33
	 * This function also does the work of cleaning up expired events and
34
	 * creating new ones when necessary.
35
	 */
36
	public static function getLatestEvent(int $gameID) : SmrEnhancedWeaponEvent {
37
		// First, remove any expired events from the database
38
		$db = new SmrMySqlDatabase();
39
		$db->query('DELETE FROM location_sells_special WHERE expires < ' . $db->escapeNumber(TIME));
40
41
		// Next, check if an existing event can be advertised
42
		$db = new SmrMySqlDatabase();
43
		$db->query('SELECT * FROM location_sells_special WHERE game_id = ' . $db->escapeNumber($gameID) . ' ORDER BY expires DESC LIMIT 1');
44
		if ($db->nextRecord()) {
45
			$event = self::getEventFromDatabase($db);
46
			// Don't advertise if the event expires within one GRACE_PERIOD
47
			if (TIME < $event->getExpireTime() - self::GRACE_PERIOD) {
48
				return $event;
49
			}
50
		}
51
52
		// Otherwise, create a new event
53
		return self::createEvent($gameID);
54
	}
55
56
	/**
57
	 * Create a new event.
58
	 *
59
	 * Events are generated randomly across all weapon types available in the
60
	 * game, and then randomly across locations that offer that weapon type.
61
	 */
62
	private static function createEvent(int $gameID) : SmrEnhancedWeaponEvent {
63
		// First, randomly select a weapon type to enhance
64
		$weaponTypeID = array_rand(SmrWeaponType::getAllSoldWeaponTypes($gameID));
65
66
		$db = new SmrMySqlDatabase();
67
		$db->query('SELECT location_type_id, sector_id FROM location JOIN location_sells_weapons USING (location_type_id) WHERE game_id = ' . $db->escapeNumber($gameID) . ' AND weapon_type_id = ' . $db->escapeNumber($weaponTypeID) . ' ORDER BY RAND() LIMIT 1');
68
		$db->requireRecord();
69
		$locationTypeID = $db->getInt('location_type_id');
70
		$sectorID = $db->getInt('sector_id');
71
72
		$expires = TIME + self::DURATION;
73
74
		// Determine which bonuses the weapon should have
75
		$random = rand(1, 100);
76
		if ($random <= 40) {
77
			$bonusAccuracy = false;
78
			$bonusDamage = true;
79
		} elseif ($random <= 80) {
80
			$bonusAccuracy = true;
81
			$bonusDamage = false;
82
		} else {
83
			$bonusAccuracy = true;
84
			$bonusDamage = true;
85
		}
86
87
		$db->query('INSERT INTO location_sells_special (game_id, sector_id, location_type_id, weapon_type_id, expires, bonus_accuracy, bonus_damage) VALUES (' . $db->escapeNumber($gameID) . ',' . $db->escapeNumber($sectorID) . ',' . $db->escapeNumber($locationTypeID) . ',' . $db->escapeNumber($weaponTypeID) . ',' . $db->escapeNumber($expires) . ',' . $db->escapeBoolean($bonusAccuracy) . ',' . $db->escapeBoolean($bonusDamage) . ')');
88
89
		return new SmrEnhancedWeaponEvent($gameID, $weaponTypeID, $locationTypeID, $sectorID, $expires, $bonusAccuracy, $bonusDamage);
90
	}
91
92
	/**
93
	 * Convenience function to instantiate an event from a query result.
94
	 */
95
	private static function getEventFromDatabase(SmrMySqlDatabase $db) : SmrEnhancedWeaponEvent {
96
		return new SmrEnhancedWeaponEvent($db->getInt('game_id'), $db->getInt('weapon_type_id'), $db->getInt('location_type_id'), $db->getInt('sector_id'), $db->getInt('expires'), $db->getBoolean('bonus_accuracy'), $db->getBoolean('bonus_damage'));
97
	}
98
99
	protected function __construct(int $gameID, int $weaponTypeID, int $locationTypeID, int $sectorID, int $expires, bool $bonusAccuracy, bool $bonusDamage) {
100
		$this->gameID = $gameID;
101
		$this->locationTypeID = $locationTypeID;
102
		$this->sectorID = $sectorID;
103
		$this->expires = $expires;
104
105
		$this->weapon = SmrWeapon::getWeapon($weaponTypeID);
106
		$this->weapon->setBonusDamage($bonusDamage);
107
		$this->weapon->setBonusAccuracy($bonusAccuracy);
108
	}
109
110
	public function getSectorID() : int {
111
		return $this->sectorID;
112
	}
113
114
	public function getExpireTime() : int {
115
		return $this->expires;
116
	}
117
118
	public function getWeapon() : SmrWeapon {
119
		return $this->weapon;
120
	}
121
122
	/**
123
	 * Returns the amount of time left in the event as a percent of the
124
	 * total duration of the event.
125
	 */
126
	public function getDurationRemainingPercent() : float {
127
		return max(0, min(100, ($this->expires - TIME) / self::DURATION * 100));
128
	}
129
130
}
131