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

SmrWeapon::getModifiedDamageAgainstForces()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 5
c 1
b 0
f 0
nc 2
nop 2
dl 0
loc 7
rs 10
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, MySqlDatabase $db = null) : SmrWeapon {
21
		return new SmrWeapon($weaponTypeID, $db);
22
	}
23
24
	protected function __construct(int $weaponTypeID, MySqlDatabase $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 &getModifiedDamageAgainstForces(AbstractSmrPlayer $weaponPlayer, SmrForce $forces) {
233
		if (!$this->canShootForces()) {
234
			// If we can't shoot forces then just return a damageless array and don't waste resources calculated any damage mods.
235
			return array('MaxDamage' => 0, 'Shield' => 0, 'Armour' => 0, 'Rollover' => $this->isDamageRollover());
236
		}
237
		$damage = $this->getDamage();
238
		return $damage;
239
	}
240
241
	public function &getModifiedDamageAgainstPort(AbstractSmrPlayer $weaponPlayer, SmrPort $port) {
242
		if (!$this->canShootPorts()) {
243
			// If we can't shoot forces then just return a damageless array and don't waste resources calculated any damage mods.
244
			return array('MaxDamage' => 0, 'Shield' => 0, 'Armour' => 0, 'Rollover' => $this->isDamageRollover());
245
		}
246
		$damage = $this->getDamage();
247
		return $damage;
248
	}
249
250
	public function &getModifiedDamageAgainstPlanet(AbstractSmrPlayer $weaponPlayer, SmrPlanet $planet) {
251
		if (!$this->canShootPlanets()) {
252
			// If we can't shoot forces then just return a damageless array and don't waste resources calculated any damage mods.
253
			return array('MaxDamage' => 0, 'Shield' => 0, 'Armour' => 0, 'Rollover' => $this->isDamageRollover());
254
		}
255
		$damage = $this->getDamage();
256
257
		$planetMod = self::PLANET_DAMAGE_MOD;
258
		$damage['MaxDamage'] = ICeil($damage['MaxDamage'] * $planetMod);
259
		$damage['Shield'] = ICeil($damage['Shield'] * $planetMod);
260
		$damage['Armour'] = ICeil($damage['Armour'] * $planetMod);
261
262
		return $damage;
263
	}
264
265
	public function &getModifiedForceDamageAgainstPlayer(SmrForce $forces, AbstractSmrPlayer $targetPlayer) {
266
		$return = array('MaxDamage' => 0, 'Shield' => 0, 'Armour' => 0, 'Rollover' => $this->isDamageRollover());
267
		return $return;
268
	}
269
270
	public function &getModifiedDamageAgainstPlayer(AbstractSmrPlayer $weaponPlayer, AbstractSmrPlayer $targetPlayer) {
271
		if (!$this->canShootTraders()) { // If we can't shoot traders then just return a damageless array and don't waste resources calculating any damage mods.
272
			$return = array('MaxDamage' => 0, 'Shield' => 0, 'Armour' => 0, 'Rollover' => $this->isDamageRollover());
273
			return $return;
274
		}
275
		$damage = $this->getDamage();
276
		return $damage;
277
	}
278
279
	public function &getModifiedPortDamageAgainstPlayer(SmrPort $port, AbstractSmrPlayer $targetPlayer) {
280
		if (!$this->canShootTraders()) { // If we can't shoot traders then just return a damageless array and don't waste resources calculating any damage mods.
281
			$return = array('MaxDamage' => 0, 'Shield' => 0, 'Armour' => 0, 'Rollover' => $this->isDamageRollover());
282
			return $return;
283
		}
284
		$damage = $this->getDamage();
285
		return $damage;
286
	}
287
288
	public function &getModifiedPlanetDamageAgainstPlayer(SmrPlanet $planet, AbstractSmrPlayer $targetPlayer) {
289
		if (!$this->canShootTraders()) { // If we can't shoot traders then just return a damageless array and don't waste resources calculating any damage mods.
290
			$return = array('MaxDamage' => 0, 'Shield' => 0, 'Armour' => 0, 'Rollover' => $this->isDamageRollover());
291
			return $return;
292
		}
293
		$damage = $this->getDamage();
294
		return $damage;
295
	}
296
297
	public function &shootForces(AbstractSmrPlayer $weaponPlayer, SmrForce $forces) {
298
		$return = array('Weapon' => $this, 'TargetForces' => $forces, 'Hit' => false);
299
		$modifiedAccuracy = $this->getModifiedAccuracyAgainstForces($weaponPlayer, $forces);
300
		if ($this->checkHit($weaponPlayer, $modifiedAccuracy)) {
301
			$return['Hit'] = true;
302
			return $this->doPlayerDamageToForce($return, $weaponPlayer, $forces);
303
		}
304
		return $return;
305
	}
306
307
	public function &shootPort(AbstractSmrPlayer $weaponPlayer, SmrPort $port) {
308
		$return = array('Weapon' => $this, 'TargetPort' => $port, 'Hit' => false);
309
		$modifiedAccuracy = $this->getModifiedAccuracyAgainstPort($weaponPlayer, $port);
310
		if ($this->checkHit($weaponPlayer, $modifiedAccuracy)) {
311
			$return['Hit'] = true;
312
			return $this->doPlayerDamageToPort($return, $weaponPlayer, $port);
313
		}
314
		return $return;
315
	}
316
317
	public function &shootPlanet(AbstractSmrPlayer $weaponPlayer, SmrPlanet $planet, $delayed) {
318
		$return = array('Weapon' => $this, 'TargetPlanet' => $planet, 'Hit' => false);
319
		$modifiedAccuracy = $this->getModifiedAccuracyAgainstPlanet($weaponPlayer, $planet);
320
		if ($this->checkHit($weaponPlayer, $modifiedAccuracy)) {
321
			$return['Hit'] = true;
322
			return $this->doPlayerDamageToPlanet($return, $weaponPlayer, $planet, $delayed);
323
		}
324
		return $return;
325
	}
326
327
	public function &shootPlayer(AbstractSmrPlayer $weaponPlayer, AbstractSmrPlayer $targetPlayer) {
328
		$return = array('Weapon' => $this, 'TargetPlayer' => $targetPlayer, 'Hit' => false);
329
		$modifiedAccuracy = $this->getModifiedAccuracyAgainstPlayer($weaponPlayer, $targetPlayer);
330
		if ($this->checkHit($weaponPlayer, $modifiedAccuracy)) {
331
			$return['Hit'] = true;
332
			return $this->doPlayerDamageToPlayer($return, $weaponPlayer, $targetPlayer);
333
		}
334
		return $return;
335
	}
336
337
	public function &shootPlayerAsForce(SmrForce $forces, AbstractSmrPlayer $targetPlayer) {
338
		$return = array('Weapon' => $this, 'TargetPlayer' => $targetPlayer, 'Hit' => false);
339
		return $return;
340
	}
341
342
	public function &shootPlayerAsPort(SmrPort $port, AbstractSmrPlayer $targetPlayer) {
343
		$return = array('Weapon' => $this, 'TargetPlayer' => $targetPlayer, 'Hit' => false);
344
		$modifiedAccuracy = $this->getModifiedPortAccuracyAgainstPlayer($port, $targetPlayer);
345
		if ($this->checkHit($targetPlayer, $modifiedAccuracy)) {
346
			$return['Hit'] = true;
347
			return $this->doPortDamageToPlayer($return, $port, $targetPlayer);
348
		}
349
		return $return;
350
	}
351
352
	public function &shootPlayerAsPlanet(SmrPlanet $planet, AbstractSmrPlayer $targetPlayer) {
353
		$return = array('Weapon' => $this, 'TargetPlayer' => $targetPlayer, 'Hit' => false);
354
		$modifiedAccuracy = $this->getModifiedPlanetAccuracyAgainstPlayer($planet, $targetPlayer);
355
		if ($this->checkHit($targetPlayer, $modifiedAccuracy)) {
356
			$return['Hit'] = true;
357
			return $this->doPlanetDamageToPlayer($return, $planet, $targetPlayer);
358
		}
359
		return $return;
360
	}
361
362
}
363