Completed
Push — trunk ( 4322e5...58ab44 )
by SuperNova.WS
04:18
created

Fleet   C

Complexity

Total Complexity 56

Size/Duplication

Total Lines 394
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 394
rs 5.5555
ccs 0
cts 153
cp 0
wmc 56

26 Methods

Rating   Name   Duplication   Size   Complexity  
A _getContainer() 0 2 1
A getShipCapacity() 0 6 2
A getUnitInfo() 0 6 2
B returnForce() 0 21 6
A getCostInMetal() 0 2 1
A getShipCostInMetal() 0 2 1
A __construct() 0 2 1
A getShipsBasicCosts() 0 7 2
A getFleetOwnerRecord() 0 7 4
B setUnits() 0 16 6
A save() 0 2 1
A getTravelData() 0 10 1
A getShipListArray() 0 2 1
A calcShipLossByMultiplier() 0 9 2
B setSourceFromPlanetRecord() 0 13 5
A calcTravelTimes() 0 10 3
A getCapacityActual() 0 11 2
A setSpeedPercentInTenth() 0 4 1
A getResourceList() 0 2 1
A changeResource() 0 2 1
A changeShipCount() 0 2 1
B setDestinationFromPlanetRecord() 0 11 6
A setMission() 0 5 1
A setFleetOwnerRecord() 0 5 2
A getShipCount() 0 2 1
A isEmpty() 0 2 1

How to fix   Complexity   

Complex Class

Complex classes like Fleet often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Fleet, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * Created by Gorlum 18.04.2018 16:30
4
 */
5
6
namespace Fleet;
7
8
9
use Core\EntityDb;
10
use SN;
11
12
/**
13
 * Class Fleet
14
 * @package Fleet
15
 *
16
 * @property int|string $id                       - bigint     -
17
 * @property int|string $ownerId                  - bigint     - Fleet player owner ID
18
 * @property int        $fleet_mission            - int        -
19
 * @property int|string $fleet_amount             - bigint     -
20
 * @property string     $fleet_array              - mediumtext -
21
 * @property int        $timeLaunch               - int        - Fleet launched from source planet (unix)
22
 * @property int        $timeArrive               - int        - Time fleet arrive to destination (unix)
23
 * @property int        $timeEndStay              - int        - Time when fleet operation on destination complete (if any) (unix)
24
 * @property int        $timeReturn               - int        - Time fleet would return to source planet (unix)
25
 * @property int|string $fleet_start_planet_id    - bigint     -
26
 * @property int        $fleet_start_galaxy       - int        -
27
 * @property int        $fleet_start_system       - int        -
28
 * @property int        $fleet_start_planet       - int        -
29
 * @property int        $fleet_start_type         - int        -
30
 * @property int|string $fleet_end_planet_id      - bigint     -
31
 * @property int        $fleet_end_galaxy         - int        -
32
 * @property int        $fleet_end_system         - int        -
33
 * @property int        $fleet_end_planet         - int        -
34
 * @property int        $fleet_end_type           - int        -
35
 * @property int|string $fleet_resource_metal     - decimal    -
36
 * @property int|string $fleet_resource_crystal   - decimal    -
37
 * @property int|string $fleet_resource_deuterium - decimal    -
38
 * @property int|string $fleet_target_owner       - int        -
39
 * @property int|string $fleet_group              - varchar    -
40
 * @property int        $status                   - int        - Current fleet status: flying to destination; returning
41
 */
42
class Fleet extends EntityDb {
43
44
  /**
45
   * @var string $_activeClass
46
   */
47
  protected $_activeClass = '\\Fleet\\RecordFleet';
48
49
  /**
50
   * @var RecordFleet $_container
51
   */
52
  protected $_container;
53
54
  protected $_containerTranslateNames = [
55
    'ownerId' => 'fleet_owner',
56
57
    'timeLaunch'  => 'start_time',
58
    'timeArrive'  => 'fleet_start_time',
59
    'timeEndStay' => 'fleet_end_stay',
60
    'timeReturn'  => 'fleet_end_time',
61
62
    'status' => 'fleet_mess',
63
  ];
64
65
  /**
66
   * Information about ships
67
   *
68
   * @var array[] $shipInfo
69
   */
70
  protected static $shipInfo = [];
71
72
  protected $speedPercentTenth = 10;
73
74
  /**
75
   * @var null|array $ownerRecord
76
   */
77
  protected $ownerRecord = null;
78
  /**
79
   * @var null|array $sourcePlanet
80
   */
81
  protected $sourcePlanet = null;
82
83
84
  /**
85
   * Fleet constructor.
86
   *
87
   * @throws \Exception
88
   */
89
  public function __construct() {
90
    parent::__construct();
91
  }
92
93
  // Real fleet actions ------------------------------------------------------------------------------------------------
94
95
  /**
96
   * Forced return fleet to source planet
97
   *
98
   * @param int|string $byPlayerId
99
   *
100
   * @return bool
101
   */
102
  public function returnForce($byPlayerId) {
103
    if ($this->ownerId != $byPlayerId) {
104
      return false;
105
    }
106
107
    if ($this->status == FLEET_STATUS_RETURNING) {
108
      return true;
109
    }
110
111
//    $ReturnFlyingTime = ($this->timeEndStay != 0 && $this->timeArrive < SN_TIME_NOW ? $this->timeArrive : SN_TIME_NOW) - $this->timeLaunch + SN_TIME_NOW + 1;
0 ignored issues
show
Unused Code Comprehensibility introduced by
36% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
112
    $timeToReturn = SN_TIME_NOW - $this->timeLaunch + 1;
113
    $ReturnFlyingTime = (!empty($this->timeEndStay) && $this->timeArrive < SN_TIME_NOW ? $this->timeArrive : SN_TIME_NOW) + $timeToReturn;
114
115
    // TODO - Those two lines should be removed - fleet times should be filtered on interface side
116
    $this->timeArrive = SN_TIME_NOW;
117
    !empty($this->timeEndStay) ? $this->timeEndStay = SN_TIME_NOW : false;
118
119
    $this->timeReturn = $ReturnFlyingTime;
120
    $this->status = FLEET_STATUS_RETURNING;
121
122
    return $this->dbUpdate();
123
  }
124
125
  // Service functions  -----------------------------------------------------------------------------------------------
126
127
  /**
128
   * @return RecordFleet
129
   */
130
  public function _getContainer() {
131
    return $this->_container;
132
  }
133
134
  /**
135
   * @param int $shipId
136
   *
137
   * @return array
138
   */
139
  protected static function getUnitInfo($shipId) {
140
    if (!isset(static::$shipInfo[$shipId])) {
141
      static::$shipInfo[$shipId] = get_unit_param($shipId);
142
    }
143
144
    return static::$shipInfo[$shipId];
145
  }
146
147
  /**
148
   * @param int $resourceId
149
   *
150
   * @return float[] - [(int)$shipId => (float)costInMetal]
151
   */
152
  public function getShipsBasicCosts($resourceId = RES_METAL) {
153
    $result = [];
154
    foreach ($this->getShipListArray() as $shipId => $shipAmount) {
155
      $result[$shipId] = getStackableUnitsCost([$shipId => 1], $resourceId);
156
    }
157
158
    return $result;
159
  }
160
161
  /**
162
   * Get cost of single ship in metal
163
   *
164
   * @param int $shipId
165
   *
166
   * @return int|float
167
   */
168
  public function getShipCostInMetal($shipId) {
169
    return getStackableUnitsCost([$shipId => 1], RES_METAL);
170
//
0 ignored issues
show
Unused Code Comprehensibility introduced by
65% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
171
//    if(!isset(static::getUnitInfo($shipId)[P_COST_METAL])) {
172
//      static::$shipInfo[$shipId][P_COST_METAL] = get_unit_cost_in(static::getUnitInfo($shipId)[P_COST], RES_METAL);
173
//    }
174
//
175
//    return static::getUnitInfo($shipId)[P_COST_METAL];
176
  }
177
178
  /**
179
   * Get fleet cost in metal
180
   *
181
   * @return float|int
182
   */
183
  public function getCostInMetal() {
184
    return getStackableUnitsCost($this->getShipListArray(), RES_METAL);
185
//
0 ignored issues
show
Unused Code Comprehensibility introduced by
49% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
186
//    $result = 0;
187
//    foreach($this->getShipList() as $shipId => $amount) {
188
//      $result += $amount * $this->getShipCostInMetal($shipId);
189
//    }
190
//
191
//    return $result;
192
  }
193
194
  /**
195
   * Get single ship basic capacity
196
   *
197
   * @param int $shipId
198
   *
199
   * @return int|mixed
200
   */
201
  public function getShipCapacity($shipId) {
202
    if (!isset(static::getUnitInfo($shipId)[P_CAPACITY])) {
203
      static::$shipInfo[$shipId][P_CAPACITY] = 0;
204
    }
205
206
    return static::getUnitInfo($shipId)[P_CAPACITY];
207
  }
208
209
  /**
210
   * Get current fleet capacity counting loaded resources and fuel
211
   *
212
   * @return float|int
213
   */
214
  public function getCapacityActual() {
215
    $result = 0;
216
    foreach ($this->getShipListArray() as $shipId => $amount) {
217
      $result += $amount * $this->getShipCapacity($shipId);
218
    }
219
220
    $travelData = $this->getTravelData();
221
222
    $result = max(0, $result - array_sum($this->getResourceList()) - $travelData['consumption']);
223
224
    return $result;
225
  }
226
227
  public function isEmpty() {
228
    return $this->getShipCount() < 1;
229
  }
230
231
  // Using RecordFleet functions ---------------------------------------------------------------------------------------
232
233
  /**
234
   * @param int   $shipSnId
235
   * @param float $shipCount
236
   *
237
   * @throws \Exception
238
   */
239
  public function changeShipCount($shipSnId, $shipCount) {
240
    $this->_getContainer()->changeShipCount($shipSnId, $shipCount);
241
  }
242
243
  /**
244
   * @param int   $resourceId
245
   * @param float $resourceCount
246
   *
247
   * @throws \Exception
248
   */
249
  public function changeResource($resourceId, $resourceCount) {
250
    $this->_getContainer()->changeResource($resourceId, $resourceCount);
251
  }
252
253
  /**
254
   * @return float[] - [shipSnId => $shipAmount]
255
   */
256
  public function getShipListArray() {
257
    return $this->_getContainer()->getShipList();
258
  }
259
260
  /**
261
   * @return float[] - [$resourceSnId => $resourceAmount]
262
   */
263
  public function getResourceList() {
264
    return $this->_getContainer()->getResourceList();
265
  }
266
267
  /**
268
   * @return float|int
269
   */
270
  public function getShipCount() {
271
    return array_sum($this->getShipListArray());
272
  }
273
274
  /**
275
   * @param float $multiplier
276
   *
277
   * @return int[]|float[]
278
   */
279
  public function calcShipLossByMultiplier($multiplier) {
280
    $result = [];
281
282
    foreach ($this->getShipListArray() as $unit_id => $unit_amount) {
283
      $shipsLost = ceil($unit_amount * $multiplier);
284
      $result[$unit_id] += $shipsLost;
285
    }
286
287
    return $result;
288
  }
289
290
  /**
291
   * @param int $missionId
292
   *
293
   * @return Fleet
294
   */
295
  public function setMission($missionId) {
296
    $this->fleet_mission = $missionId;
297
    $this->status = FLEET_STATUS_FLYING;
298
299
    return $this;
300
  }
301
302
  /**
303
   * @param array $playerRecord
304
   *
305
   * @return Fleet
306
   */
307
  public function setFleetOwnerRecord($playerRecord) {
308
    $this->ownerRecord = $playerRecord;
309
    !empty($this->ownerRecord['id']) ? $this->ownerId = $this->ownerRecord['id'] : false;
310
311
    return $this;
312
  }
313
314
  /**
315
   * @return array|false|null
316
   */
317
  public function getFleetOwnerRecord() {
318
    if (!isset($this->ownerRecord['id']) && !empty($this->ownerId)) {
319
      // Trying to get owner record by id
320
      empty($this->ownerRecord = db_user_by_id($this->ownerId)) ? $this->ownerRecord = null : false;
0 ignored issues
show
Documentation Bug introduced by
It seems like db_user_by_id($this->ownerId) of type false is incompatible with the declared type null|array of property $ownerRecord.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
Bug introduced by
It seems like $this->ownerId can also be of type string; however, parameter $user_id_unsafe of db_user_by_id() does only seem to accept integer|array, 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

320
      empty($this->ownerRecord = db_user_by_id(/** @scrutinizer ignore-type */ $this->ownerId)) ? $this->ownerRecord = null : false;
Loading history...
Deprecated Code introduced by
The function db_user_by_id() has been deprecated. ( Ignorable by Annotation )

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

320
      empty($this->ownerRecord = /** @scrutinizer ignore-deprecated */ db_user_by_id($this->ownerId)) ? $this->ownerRecord = null : false;
Loading history...
321
    }
322
323
    return $this->ownerRecord;
324
  }
325
326
  /**
327
   * @param array $from
328
   *
329
   * @return Fleet
330
   */
331
  public function setSourceFromPlanetRecord($from) {
332
    empty($this->ownerId) && !empty($from['id_owner']) ? $this->ownerId = $from['id_owner'] : false;
333
334
    $this->fleet_start_planet_id = !empty($from['id']) && intval($from['id']) ? $from['id'] : null;
335
336
    $this->fleet_start_galaxy = $from['galaxy'];
337
    $this->fleet_start_system = $from['system'];
338
    $this->fleet_start_planet = $from['planet'];
339
    $this->fleet_start_type = $from['planet_type'];
340
341
    $this->sourcePlanet = $from;
342
343
    return $this;
344
  }
345
346
347
  /**
348
   * @param $to
349
   *
350
   * @return Fleet
351
   */
352
  public function setDestinationFromPlanetRecord($to) {
353
    empty($this->fleet_target_owner) ? $this->fleet_target_owner = !empty($to['id_owner']) && intval($to['id_owner']) ? $to['id_owner'] : 0 : false;
354
355
    $this->fleet_end_planet_id = !empty($to['id']) && intval($to['id']) ? $to['id'] : null;
356
357
    $this->fleet_end_galaxy = $to['galaxy'];
358
    $this->fleet_end_system = $to['system'];
359
    $this->fleet_end_planet = $to['planet'];
360
    $this->fleet_end_type = $to['planet_type'];
361
362
    return $this;
363
  }
364
365
  /**
366
   * @param array $fleet - list of units [(int)unitId => (float)unitAmount]
367
   *
368
   * @return Fleet
369
   * @throws \Exception
370
   */
371
  public function setUnits($fleet) {
372
    foreach ($fleet as $unit_id => $amount) {
373
      if (!$amount || !$unit_id) {
374
        continue;
375
      }
376
377
      if (in_array($unit_id, sn_get_groups('fleet'))) {
378
        /** @noinspection PhpUnhandledExceptionInspection */
379
        $this->changeShipCount($unit_id, $amount);
380
      } elseif (in_array($unit_id, sn_get_groups('resources_loot'))) {
381
        /** @noinspection PhpUnhandledExceptionInspection */
382
        $this->changeResource($unit_id, $amount);
383
      }
384
    }
385
386
    return $this;
387
  }
388
389
  /**
390
   * @param int $speedPercentTenth - fleet speed percent in 10% from 1..10 - i.e. 1 = 10%, 10 = 100%
391
   *
392
   * @return Fleet
393
   */
394
  public function setSpeedPercentInTenth($speedPercentTenth) {
395
    $this->speedPercentTenth = max(0, min(10, intval($speedPercentTenth)));
396
397
    return $this;
398
  }
399
400
  /**
401
   * @param int $launchTime   - unix timestamp when fleet leave source planet
402
   * @param int $stayDuration - seconds how long fleet should stay executing mission task (i.e. HOLD or EXPLORE)
403
   *
404
   * @return array
405
   */
406
  public function calcTravelTimes($launchTime = SN_TIME_NOW, $stayDuration = 0) {
407
    $this->timeLaunch = $launchTime;
408
409
    $travel_data = $this->getTravelData();
410
411
    $this->timeArrive = $this->timeLaunch + $travel_data['duration'];
412
    $this->timeEndStay = $this->fleet_mission == MT_EXPLORE || $this->fleet_mission == MT_HOLD ? $this->timeArrive + $stayDuration : 0;
413
    $this->timeReturn = $this->timeArrive + $stayDuration + $travel_data['duration'];
414
415
    return $travel_data;
416
  }
417
418
419
  public function save() {
420
    return parent::save(); // TODO: Change the autogenerated stub
421
  }
422
423
  /**
424
   * @return array
425
   */
426
  protected function getTravelData() {
427
    $travel_data = flt_travel_data(
428
      $this->getFleetOwnerRecord(),
429
      ['galaxy' => $this->fleet_start_galaxy, 'system' => $this->fleet_start_system, 'planet' => $this->fleet_start_planet,],
430
      ['galaxy' => $this->fleet_end_galaxy, 'system' => $this->fleet_end_system, 'planet' => $this->fleet_end_planet,],
431
      $this->getShipListArray(),
432
      $this->speedPercentTenth
433
    );
434
435
    return $travel_data;
436
  }
437
438
}
439