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

SmrWeapon::shootPlanet()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 7
dl 0
loc 8
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 3
1
<?php declare(strict_types=1);
2
3
/**
4
 * Defines a concrete realization of a weapon type for ships/planets.
5
 */
6
class SmrWeapon extends AbstractSmrCombatWeapon {
7
	use Traits\RaceID;
8
9
	const BONUS_DAMAGE = 15; // additive bonus
10
	const BONUS_ACCURACY = 4; // additive bonus
11
12
	const HIGHEST_POWER_LEVEL = 5; // must track the highest power level in db
13
14
	protected int $weaponTypeID;
15
	protected SmrWeaponType $weaponType;
16
	protected bool $bonusAccuracy = false; // default
17
	protected bool $bonusDamage = false; // default
18
	protected $damageRollover = false; // fixed for all SmrWeapons
19
20
	public static function getWeapon(int $weaponTypeID, SmrMySqlDatabase $db = null) : SmrWeapon {
21
		return new SmrWeapon($weaponTypeID, $db);
22
	}
23
24
	protected function __construct(int $weaponTypeID, SmrMySqlDatabase $db = null) {
25
		$this->weaponType = SmrWeaponType::getWeaponType($weaponTypeID, $db);
26
		$this->weaponTypeID = $weaponTypeID;
27
		$this->name = $this->weaponType->getName();
28
		$this->raceID = $this->weaponType->getRaceID();
29
	}
30
31
	public function hasBonusAccuracy() : bool {
32
		return $this->bonusAccuracy;
33
	}
34
35
	public function setBonusAccuracy(bool $bonusAccuracy) {
36
		$this->bonusAccuracy = $bonusAccuracy;
37
	}
38
39
	public function hasBonusDamage() : bool {
40
		return $this->bonusDamage;
41
	}
42
43
	public function setBonusDamage(bool $bonusDamage) {
44
		$this->bonusDamage = $bonusDamage;
45
	}
46
47
	private function hasEnhancements() : bool {
48
		return $this->getNumberOfEnhancements() > 0;
49
	}
50
51
	private function getNumberOfEnhancements() : int {
52
		return (int)$this->bonusAccuracy + (int)$this->bonusDamage;
53
	}
54
55
	/**
56
	 * (Override) Return weapon name suitable for HTML display.
57
	 * The name is displayed in green with pluses if enhancements are present.
58
	 */
59
	public function getName() : string {
60
		if ($this->hasEnhancements()) {
61
			return '<span class="green">' . $this->name . str_repeat('+', $this->getNumberOfEnhancements()) . '</span>';
62
		}
63
		return $this->name;
64
	}
65
66
	/**
67
	 * (Override) Return the weapon base accuracy.
68
	 */
69
	public function getBaseAccuracy() : int {
70
		$baseAccuracy = $this->weaponType->getAccuracy();
71
		if ($this->bonusAccuracy) {
72
			$baseAccuracy += self::BONUS_ACCURACY;
73
		}
74
		return $baseAccuracy;
75
	}
76
77
	/**
78
	 * (Override) Return the weapon shield damage.
79
	 */
80
	public function getShieldDamage() : int {
81
		$shieldDamage = $this->weaponType->getShieldDamage();
82
		if ($this->bonusDamage && $shieldDamage > 0) {
83
			$shieldDamage += self::BONUS_DAMAGE;
84
		}
85
		return $shieldDamage;
86
	}
87
88
	/**
89
	 * (Override) Return the weapon armour damage.
90
	 */
91
	public function getArmourDamage() : int {
92
		$armourDamage = $this->weaponType->getArmourDamage();
93
		if ($this->bonusDamage && $armourDamage > 0) {
94
			$armourDamage += self::BONUS_DAMAGE;
95
		}
96
		return $armourDamage;
97
	}
98
99
	/**
100
	 * (Override) Return the max weapon damage possible in a single round.
101
	 */
102
	public function getMaxDamage() : int {
103
		return max($this->getShieldDamage(), $this->getArmourDamage());
104
	}
105
106
	public function getBuyHREF(SmrLocation $location) {
107
		$container = create_container('shop_weapon_processing.php');
108
		$container['LocationID'] = $location->getTypeID();
109
		$container['Weapon'] = $this;
110
		return SmrSession::getNewHREF($container);
111
	}
112
113
	public function getSellHREF(SmrLocation $location, $orderID) {
114
		$container = create_container('shop_weapon_processing.php');
115
		$container['LocationID'] = $location->getTypeID();
116
		$container['Weapon'] = $this;
117
		$container['OrderID'] = $orderID;
118
		return SmrSession::getNewHREF($container);
119
	}
120
	
121
	public function getWeaponTypeID() {
122
		return $this->weaponTypeID;
123
	}
124
125
	/**
126
	 * Weapon cost is increased by 100% for each enhancement present
127
	 */
128
	public function getCost() {
129
		return $this->weaponType->getCost() * (1 + $this->getNumberOfEnhancements());
130
	}
131
	
132
	public function getPowerLevel() {
133
		return $this->weaponType->getPowerLevel();
134
	}
135
	
136
	public function getBuyerRestriction() {
137
		return $this->weaponType->getBuyerRestriction();
138
	}
139
140
	/**
141
	 * Ships are only allowed to equip one of each type of Unique weapon
142
	 */
143
	public function isUniqueType() : bool {
144
		return $this->getPowerLevel() === self::HIGHEST_POWER_LEVEL;
145
	}
146
147
	protected function getWeightedRandomForPlayer(AbstractSmrPlayer $player) {
148
		return WeightedRandom::getWeightedRandomForPlayer($player, 'Weapon', $this->getWeaponTypeID());
149
	}
150
151
	/**
152
	 * Given $weaponAccuracy as a percent, decide if the weapon hits.
153
	 */
154
	protected function checkHit(AbstractSmrPlayer $player, $weaponAccuracy) : bool {
155
		// Skip weighting factor for absolute hits/misses.
156
		if ($weaponAccuracy >= 100) {
157
			return true;
158
		} elseif ($weaponAccuracy <= 0) {
159
			return false;
160
		}
161
		return $this->getWeightedRandomForPlayer($player)->flipWeightedCoin($weaponAccuracy);
162
	}
163
	
164
	public static function getPlayerLevelAccuracyMod(AbstractSmrPlayer $player) {
165
		return ($player->getLevelID() * $player->getLevelID() / 60 + $player->getLevelID() / 2 + 2) / 100;
166
	}
167
	
168
	public function getModifiedAccuracy(AbstractSmrPlayer $weaponPlayer) {
169
		$modifiedAccuracy = $this->getBaseAccuracy();
170
		$modifiedAccuracy += $this->getBaseAccuracy() * self::getPlayerLevelAccuracyMod($weaponPlayer);
171
		return $modifiedAccuracy;
172
	}
173
	
174
	public function getModifiedAccuracyAgainstForces(AbstractSmrPlayer $weaponPlayer, SmrForce $forces) {
0 ignored issues
show
Unused Code introduced by
The parameter $forces 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

174
	public function getModifiedAccuracyAgainstForces(AbstractSmrPlayer $weaponPlayer, /** @scrutinizer ignore-unused */ SmrForce $forces) {

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...
175
		$modifiedAccuracy = $this->getModifiedAccuracy($weaponPlayer);
176
		return $modifiedAccuracy;
177
	}
178
	
179
	public function getModifiedAccuracyAgainstPort(AbstractSmrPlayer $weaponPlayer, SmrPort $port) {
180
		$modifiedAccuracy = $this->getModifiedAccuracy($weaponPlayer);
181
		$modifiedAccuracy -= $this->getBaseAccuracy() * $port->getLevel() / 50;
182
		return $modifiedAccuracy;
183
	}
184
	
185
	public function getModifiedAccuracyAgainstPlanet(AbstractSmrPlayer $weaponPlayer, SmrPlanet $planet) {
186
		$modifiedAccuracy = $this->getModifiedAccuracy($weaponPlayer);
187
		$modifiedAccuracy -= $this->getBaseAccuracy() * $planet->getLevel() / 350;
188
		return $modifiedAccuracy;
189
	}
190
	
191
	public function getModifiedAccuracyAgainstPlayer(AbstractSmrPlayer $weaponPlayer, AbstractSmrPlayer $targetPlayer) {
192
		$modifiedAccuracy = $this->getModifiedAccuracy($weaponPlayer);
193
		$modifiedAccuracy -= $this->getBaseAccuracy() * self::getPlayerLevelAccuracyMod($targetPlayer) / 2;
194
		
195
		$weaponShip = $weaponPlayer->getShip();
196
		$targetShip = $targetPlayer->getShip();
197
		$mrDiff = $targetShip->getMR() - $weaponShip->getMR();
198
		if ($mrDiff > 0) {
199
			$modifiedAccuracy -= $this->getBaseAccuracy() * ($mrDiff / MR_FACTOR) / 100;
200
		}
201
	
202
		return $modifiedAccuracy;
203
	}
204
	
205
	public function getModifiedPortAccuracy(SmrPort $port) {
0 ignored issues
show
Unused Code introduced by
The parameter $port 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

205
	public function getModifiedPortAccuracy(/** @scrutinizer ignore-unused */ SmrPort $port) {

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...
206
		$modifiedAccuracy = $this->getBaseAccuracy();
207
		return $modifiedAccuracy;
208
	}
209
	
210
	public function getModifiedPortAccuracyAgainstPlayer(SmrPort $port, AbstractSmrPlayer $targetPlayer) {
211
		$modifiedAccuracy = $this->getModifiedPortAccuracy($port);
212
		$modifiedAccuracy -= $this->getBaseAccuracy() * self::getPlayerLevelAccuracyMod($targetPlayer);
213
		return $modifiedAccuracy;
214
	}
215
	
216
	public function getModifiedPlanetAccuracy(SmrPlanet $planet) {
217
		$modifiedAccuracy = $this->getBaseAccuracy();
218
		if ($this->getWeaponTypeID() == WEAPON_PLANET_TURRET) {
219
			$modifiedAccuracy += $planet->getLevel() / 2;
220
		} else {
221
			$modifiedAccuracy += $planet->getAccuracyBonus();
222
		}
223
		return $modifiedAccuracy;
224
	}
225
	
226
	public function getModifiedPlanetAccuracyAgainstPlayer(SmrPlanet $planet, AbstractSmrPlayer $targetPlayer) {
227
		$modifiedAccuracy = $this->getModifiedPlanetAccuracy($planet);
228
		$modifiedAccuracy -= $this->getBaseAccuracy() * self::getPlayerLevelAccuracyMod($targetPlayer);
229
		return $modifiedAccuracy;
230
	}
231
	
232
	public function &getModifiedDamage() {
233
		$damage = $this->getDamage();
234
		return $damage;
235
	}
236
	
237
	public function &getModifiedDamageAgainstForces(AbstractSmrPlayer $weaponPlayer, SmrForce $forces) {
238
		if (!$this->canShootForces()) {
239
			// If we can't shoot forces then just return a damageless array and don't waste resources calculated any damage mods.
240
			return array('MaxDamage' => 0, 'Shield' => 0, 'Armour' => 0, 'Rollover' => $this->isDamageRollover());
241
		}
242
		$damage =& $this->getModifiedDamage();
243
		return $damage;
244
	}
245
	
246
	public function &getModifiedDamageAgainstPort(AbstractSmrPlayer $weaponPlayer, SmrPort $port) {
247
		if (!$this->canShootPorts()) {
248
			// If we can't shoot forces then just return a damageless array and don't waste resources calculated any damage mods.
249
			return array('MaxDamage' => 0, 'Shield' => 0, 'Armour' => 0, 'Rollover' => $this->isDamageRollover());
250
		}
251
		$damage =& $this->getModifiedDamage();
252
		return $damage;
253
	}
254
	
255
	public function &getModifiedDamageAgainstPlanet(AbstractSmrPlayer $weaponPlayer, SmrPlanet $planet) {
256
		if (!$this->canShootPlanets()) {
257
			// If we can't shoot forces then just return a damageless array and don't waste resources calculated any damage mods.
258
			return array('MaxDamage' => 0, 'Shield' => 0, 'Armour' => 0, 'Rollover' => $this->isDamageRollover());
259
		}
260
		$damage =& $this->getModifiedDamage();
261
		
262
		$planetMod = self::PLANET_DAMAGE_MOD;
263
		$damage['MaxDamage'] = ICeil($damage['MaxDamage'] * $planetMod);
264
		$damage['Shield'] = ICeil($damage['Shield'] * $planetMod);
265
		$damage['Armour'] = ICeil($damage['Armour'] * $planetMod);
266
		
267
		return $damage;
268
	}
269
	
270
	public function &getModifiedForceDamageAgainstPlayer(SmrForce $forces, AbstractSmrPlayer $targetPlayer) {
271
		$return = array('MaxDamage' => 0, 'Shield' => 0, 'Armour' => 0, 'Rollover' => $this->isDamageRollover());
272
		return $return;
273
	}
274
	
275
	public function &getModifiedDamageAgainstPlayer(AbstractSmrPlayer $weaponPlayer, AbstractSmrPlayer $targetPlayer) {
276
		if (!$this->canShootTraders()) { // If we can't shoot traders then just return a damageless array and don't waste resources calculating any damage mods.
277
			$return = array('MaxDamage' => 0, 'Shield' => 0, 'Armour' => 0, 'Rollover' => $this->isDamageRollover());
278
			return $return;
279
		}
280
		$damage =& $this->getModifiedDamage();
281
		return $damage;
282
	}
283
	
284
	public function &getModifiedPortDamageAgainstPlayer(SmrPort $port, AbstractSmrPlayer $targetPlayer) {
285
		if (!$this->canShootTraders()) { // If we can't shoot traders then just return a damageless array and don't waste resources calculating any damage mods.
286
			$return = array('MaxDamage' => 0, 'Shield' => 0, 'Armour' => 0, 'Rollover' => $this->isDamageRollover());
287
			return $return;
288
		}
289
		$damage = $this->getDamage();
290
		return $damage;
291
	}
292
	
293
	public function &getModifiedPlanetDamageAgainstPlayer(SmrPlanet $planet, AbstractSmrPlayer $targetPlayer) {
0 ignored issues
show
Unused Code introduced by
The parameter $planet 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

293
	public function &getModifiedPlanetDamageAgainstPlayer(/** @scrutinizer ignore-unused */ SmrPlanet $planet, AbstractSmrPlayer $targetPlayer) {

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...
Unused Code introduced by
The parameter $targetPlayer 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

293
	public function &getModifiedPlanetDamageAgainstPlayer(SmrPlanet $planet, /** @scrutinizer ignore-unused */ AbstractSmrPlayer $targetPlayer) {

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...
294
		if (!$this->canShootTraders()) { // If we can't shoot traders then just return a damageless array and don't waste resources calculating any damage mods.
295
			$return = array('MaxDamage' => 0, 'Shield' => 0, 'Armour' => 0, 'Rollover' => $this->isDamageRollover());
296
			return $return;
297
		}
298
		$damage = $this->getDamage();
299
		return $damage;
300
	}
301
	
302
	public function &shootForces(AbstractSmrPlayer $weaponPlayer, SmrForce $forces) {
303
		$return = array('Weapon' => $this, 'TargetForces' => $forces, 'Hit' => false);
304
		$modifiedAccuracy = $this->getModifiedAccuracyAgainstForces($weaponPlayer, $forces);
305
		if ($this->checkHit($weaponPlayer, $modifiedAccuracy)) {
306
			$return['Hit'] = true;
307
			return $this->doPlayerDamageToForce($return, $weaponPlayer, $forces);
308
		}
309
		return $return;
310
	}
311
	
312
	public function &shootPort(AbstractSmrPlayer $weaponPlayer, SmrPort $port) {
313
		$return = array('Weapon' => $this, 'TargetPort' => $port, 'Hit' => false);
314
		$modifiedAccuracy = $this->getModifiedAccuracyAgainstPort($weaponPlayer, $port);
315
		if ($this->checkHit($weaponPlayer, $modifiedAccuracy)) {
316
			$return['Hit'] = true;
317
			return $this->doPlayerDamageToPort($return, $weaponPlayer, $port);
318
		}
319
		return $return;
320
	}
321
	
322
	public function &shootPlanet(AbstractSmrPlayer $weaponPlayer, SmrPlanet $planet, $delayed) {
323
		$return = array('Weapon' => $this, 'TargetPlanet' => $planet, 'Hit' => false);
324
		$modifiedAccuracy = $this->getModifiedAccuracyAgainstPlanet($weaponPlayer, $planet);
325
		if ($this->checkHit($weaponPlayer, $modifiedAccuracy)) {
326
			$return['Hit'] = true;
327
			return $this->doPlayerDamageToPlanet($return, $weaponPlayer, $planet, $delayed);
328
		}
329
		return $return;
330
	}
331
	
332
	public function &shootPlayer(AbstractSmrPlayer $weaponPlayer, AbstractSmrPlayer $targetPlayer) {
333
		$return = array('Weapon' => $this, 'TargetPlayer' => $targetPlayer, 'Hit' => false);
334
		$modifiedAccuracy = $this->getModifiedAccuracyAgainstPlayer($weaponPlayer, $targetPlayer);
335
		if ($this->checkHit($weaponPlayer, $modifiedAccuracy)) {
336
			$return['Hit'] = true;
337
			return $this->doPlayerDamageToPlayer($return, $weaponPlayer, $targetPlayer);
338
		}
339
		return $return;
340
	}
341
	
342
	public function &shootPlayerAsForce(SmrForce $forces, AbstractSmrPlayer $targetPlayer) {
343
		$return = array('Weapon' => $this, 'TargetPlayer' => $targetPlayer, 'Hit' => false);
344
		return $return;
345
	}
346
	
347
	public function &shootPlayerAsPort(SmrPort $port, AbstractSmrPlayer $targetPlayer) {
348
		$return = array('Weapon' => $this, 'TargetPlayer' => $targetPlayer, 'Hit' => false);
349
		$modifiedAccuracy = $this->getModifiedPortAccuracyAgainstPlayer($port, $targetPlayer);
350
		if ($this->checkHit($targetPlayer, $modifiedAccuracy)) {
351
			$return['Hit'] = true;
352
			return $this->doPortDamageToPlayer($return, $port, $targetPlayer);
353
		}
354
		return $return;
355
	}
356
	
357
	public function &shootPlayerAsPlanet(SmrPlanet $planet, AbstractSmrPlayer $targetPlayer) {
358
		$return = array('Weapon' => $this, 'TargetPlayer' => $targetPlayer, 'Hit' => false);
359
		$modifiedAccuracy = $this->getModifiedPlanetAccuracyAgainstPlayer($planet, $targetPlayer);
360
		if ($this->checkHit($targetPlayer, $modifiedAccuracy)) {
361
			$return['Hit'] = true;
362
			return $this->doPlanetDamageToPlayer($return, $planet, $targetPlayer);
363
		}
364
		return $return;
365
	}
366
	
367
}
368