Completed
Push — work-fleets ( 77ad6e...489db6 )
by SuperNova.WS
06:17
created

Fleet::fleetPage2Prepare()   B

Complexity

Conditions 9
Paths 13

Size

Total Lines 56
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 90

Importance

Changes 4
Bugs 0 Features 0
Metric Value
cc 9
eloc 20
c 4
b 0
f 0
nc 13
nop 1
dl 0
loc 56
rs 7.1584
ccs 0
cts 27
cp 0
crap 90

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
use Vector\Vector;
3
4
/**
5
 * Class Fleet
6
 *
7
 * @property int dbId
8
 * @property int playerOwnerId
9
 * @property int group_id
10
 * @property int mission_type
11
 * @property int target_owner_id
12
 * @property int is_returning
13
 *
14
 * @property int time_launch
15
 * @property int time_arrive_to_target
16
 * @property int time_mission_job_complete
17
 * @property int time_return_to_source
18
 *
19
 * @property int fleet_start_planet_id
20
 * @property int fleet_start_galaxy
21
 * @property int fleet_start_system
22
 * @property int fleet_start_planet
23
 * @property int fleet_start_type
24
 *
25
 * @property int fleet_end_planet_id
26
 * @property int fleet_end_galaxy
27
 * @property int fleet_end_system
28
 * @property int fleet_end_planet
29
 * @property int fleet_end_type
30
 *
31
 */
32
class Fleet extends UnitContainer {
33
34
  // DBRow inheritance *************************************************************************************************
35
36
  /**
37
   * Table name in DB
38
   *
39
   * @var string
40
   */
41
  protected static $_table = 'fleets';
42
  /**
43
   * Name of ID field in DB
44
   *
45
   * @var string
46
   */
47
  protected static $_dbIdFieldName = 'fleet_id';
48
  /**
49
   * DB_ROW to Class translation scheme
50
   *
51
   * @var array
52
   */
53
  protected $_properties = array(
54
    'dbId'          => array(
55
      P_DB_FIELD => 'fleet_id',
56
    ),
57
    'playerOwnerId' => array(
58
      P_METHOD_EXTRACT => 'ownerExtract',
59
      P_METHOD_INJECT  => 'ownerInject',
60
//      P_DB_FIELD => 'fleet_owner',
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% 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...
61
    ),
62
    'mission_type'  => array(
63
      P_DB_FIELD   => 'fleet_mission',
64
      P_FUNC_INPUT => 'intval',
65
    ),
66
67
    'target_owner_id' => array(
68
      P_DB_FIELD => 'fleet_target_owner',
69
    ),
70
    'group_id'        => array(
71
      P_DB_FIELD => 'fleet_group',
72
    ),
73
    'is_returning'    => array(
74
      P_DB_FIELD   => 'fleet_mess',
75
      P_FUNC_INPUT => 'intval',
76
    ),
77
78
    'shipCount' => array(
79
      P_DB_FIELD  => 'fleet_amount',
80
// TODO - CHECK !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
0 ignored issues
show
Unused Code Comprehensibility introduced by
80% 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...
81
//      P_FUNC_OUTPUT => 'get_ship_count',
82
//      P_DB_FIELDS_LINKED => array(
83
//        'fleet_amount',
84
//      ),
85
      P_READ_ONLY => true,
86
    ),
87
88
    'time_launch' => array(
89
      P_DB_FIELD => 'start_time',
90
    ),
91
92
    'time_arrive_to_target'     => array(
93
      P_DB_FIELD => 'fleet_start_time',
94
    ),
95
    'time_mission_job_complete' => array(
96
      P_DB_FIELD => 'fleet_end_stay',
97
    ),
98
    'time_return_to_source'     => array(
99
      P_DB_FIELD => 'fleet_end_time',
100
    ),
101
102
    'fleet_start_planet_id' => array(
103
      P_DB_FIELD   => 'fleet_start_planet_id',
104
      P_FUNC_INPUT => 'nullIfEmpty',
105
    ),
106
107
    'fleet_start_galaxy' => array(
108
      P_DB_FIELD => 'fleet_start_galaxy',
109
    ),
110
    'fleet_start_system' => array(
111
      P_DB_FIELD => 'fleet_start_system',
112
    ),
113
    'fleet_start_planet' => array(
114
      P_DB_FIELD => 'fleet_start_planet',
115
    ),
116
    'fleet_start_type'   => array(
117
      P_DB_FIELD => 'fleet_start_type',
118
    ),
119
120
    'fleet_end_planet_id' => array(
121
      P_DB_FIELD   => 'fleet_end_planet_id',
122
      P_FUNC_INPUT => 'nullIfEmpty',
123
    ),
124
    'fleet_end_galaxy'    => array(
125
      P_DB_FIELD => 'fleet_end_galaxy',
126
    ),
127
    'fleet_end_system'    => array(
128
      P_DB_FIELD => 'fleet_end_system',
129
    ),
130
    'fleet_end_planet'    => array(
131
      P_DB_FIELD => 'fleet_end_planet',
132
    ),
133
    'fleet_end_type'      => array(
134
      P_DB_FIELD => 'fleet_end_type',
135
    ),
136
137
    'resource_list' => array(
138
      P_METHOD_EXTRACT   => 'resourcesExtract',
139
      P_METHOD_INJECT    => 'resourcesInject',
140
      P_DB_FIELDS_LINKED => array(
141
        'fleet_resource_metal',
142
        'fleet_resource_crystal',
143
        'fleet_resource_deuterium',
144
      ),
145
    ),
146
  );
147
148
149
  // UnitContainer inheritance *****************************************************************************************
150
  /**
151
   * Type of this location
152
   *
153
   * @var int $locationType
154
   */
155
  protected static $locationType = LOC_FLEET;
156
157
158
  // New properties ****************************************************************************************************
159
  public static $snGroupFleet = array();
160
  public static $snGroupFleetAndMissiles = array();
161
  public static $snGroupRecyclers = array();
162
163
  /**
164
   * `fleet_owner`
165
   *
166
   * @var int
167
   */
168
  protected $_playerOwnerId = 0;
169
  /**
170
   * `fleet_group`
171
   *
172
   * @var int
173
   */
174
  protected $_group_id = 0;
175
  public $acs = array();
176
177
  /**
178
   * `fleet_mission`
179
   *
180
   * @var int
181
   */
182
  protected $_mission_type = 0;
183
184
  /**
185
   * `fleet_target_owner`
186
   *
187
   * @var int
188
   */
189
  protected $_target_owner_id = null;
190
191
  /**
192
   * @var array
193
   */
194
  public $resource_list = array(
195
    RES_METAL     => 0,
196
    RES_CRYSTAL   => 0,
197
    RES_DEUTERIUM => 0,
198
  );
199
200
201
  /**
202
   * `fleet__mess` - Флаг возвращающегося флота
203
   *
204
   * @var int
205
   */
206
  protected $_is_returning = 0;
207
  /**
208
   * `start_time` - Время отправления - таймштамп взлёта флота из точки отправления
209
   *
210
   * @var int $_time_launch
211
   */
212
  protected $_time_launch = 0; // `start_time` = SN_TIME_NOW
213
  /**
214
   * `fleet_start_time` - Время прибытия в точку миссии/время начала выполнения миссии
215
   *
216
   * @var int $_time_arrive_to_target
217
   */
218
  protected $_time_arrive_to_target = 0; // `fleet_start_time` = SN_TIME_NOW + $time_travel
219
  /**
220
   * `fleet_end_stay` - Время окончания миссии в точке назначения
221
   *
222
   * @var int $_time_mission_job_complete
223
   */
224
  protected $_time_mission_job_complete = 0; // `fleet_end_stay`
225
  /**
226
   * `fleet_end_time` - Время возвращения флота после окончания миссии
227
   *
228
   * @var int $_time_return_to_source
229
   */
230
  protected $_time_return_to_source = 0; // `fleet_end_time`
231
232
233
  protected $_fleet_start_planet_id = null;
234
  protected $_fleet_start_galaxy = 0;
235
  protected $_fleet_start_system = 0;
236
  protected $_fleet_start_planet = 0;
237
  protected $_fleet_start_type = PT_ALL;
238
239
  protected $_fleet_end_planet_id = null;
240
  protected $_fleet_end_galaxy = 0;
241
  protected $_fleet_end_system = 0;
242
  protected $_fleet_end_planet = 0;
243
  protected $_fleet_end_type = PT_ALL;
244
245
  // Missile properties
246
  public $missile_target = 0;
247
248
  // Fleet event properties
249
  public $fleet_start_name = '';
250
  public $fleet_end_name = '';
251
  public $ov_label = '';
252
  public $ov_this_planet = '';
253
  public $event_time = 0;
254
255
  protected $resource_delta = array();
256
  protected $resource_replace = array();
257
258
259
//
260
261
262
  /**
263
   * @var array $allowed_missions
264
   */
265
  public $allowed_missions = array();
266
  /**
267
   * @var array $exists_missions
268
   */
269
  public $exists_missions = array();
270
  public $allowed_planet_types = array(
271
    // PT_NONE => PT_NONE,
272
    PT_PLANET => PT_PLANET,
273
    PT_MOON   => PT_MOON,
274
    PT_DEBRIS => PT_DEBRIS
275
  );
276
277
  // TODO - Move to Player
278
  public $dbOwnerRow = array();
279
  public $dbSourcePlanetRow = array();
280
281
  /**
282
   * GSPT coordinates of target
283
   *
284
   * @var Vector
285
   */
286
  public $targetVector = array();
287
  /**
288
   * Target planet row
289
   *
290
   * @var array
291
   */
292
  public $dbTargetRow = array();
293
  public $dbTargetOwnerRow = array();
294
295
  /**
296
   * Fleet speed - old in 1/10 of 100%
297
   *
298
   * @var int
299
   */
300
  public $oldSpeedInTens = 0;
301
302
  public $tempPlayerMaxFleets = 0;
303
  public $travelData = array();
304
305
  public $isRealFlight = false;
306
307
  /**
308
   * @var int $targetedUnitId
309
   */
310
  public $targetedUnitId = 0;
311
312
  /**
313
   * @var array $captain
314
   */
315
  public $captain = array();
316
  /**
317
   * @var int $captainId
318
   */
319
  public $captainId = 0;
320
321
  /**
322
   * @var FleetValidator $validator
323
   */
324
  public $validator;
325
326
  /**
327
   * Fleet constructor.
328
   */
329
  public function __construct() {
330
    parent::__construct();
331
    $this->exists_missions = sn_get_groups('missions');
332
    $this->validator = new FleetValidator($this);
333
  }
334
335
  /**
336
   * @param array $template_result
337
   * @param array $playerRow
338
   * @param array $planetRow
339
   */
340
  // TODO - redo to unit/unitlist renderer
341
  public function renderAvailableShips(&$template_result, $playerRow, $planetRow) {
342
    $record_index = 0;
343
    $ship_list = array();
344
    foreach (Fleet::$snGroupFleet as $n => $unit_id) {
345
      $unit_level = mrc_get_level($playerRow, $planetRow, $unit_id, false, true);
346
      if ($unit_level <= 0) {
347
        continue;
348
      }
349
      $ship_data = get_ship_data($unit_id, $playerRow);
350
      $ship_list[$unit_id] = array(
351
        '__INDEX'          => $record_index++,
352
        'ID'               => $unit_id,
353
        'NAME'             => classLocale::$lang['tech'][$unit_id],
354
        'AMOUNT'           => $unit_level,
355
        'AMOUNT_TEXT'      => pretty_number($unit_level),
356
        'CONSUMPTION'      => $ship_data['consumption'],
357
        'CONSUMPTION_TEXT' => pretty_number($ship_data['consumption']),
358
        'SPEED'            => $ship_data['speed'],
359
        'SPEED_TEXT'       => pretty_number($ship_data['speed']),
360
        'CAPACITY'         => $ship_data['capacity'],
361
        'CAPACITY_TEXT'    => pretty_number($ship_data['capacity']),
362
      );
363
    }
364
365
    sortUnitRenderedList($ship_list, classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_SORT], classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_SORT_INVERSE]);
366
367
    foreach ($ship_list as $ship_data) {
368
      $template_result['.']['ships'][] = $ship_data;
369
    }
370
  }
371
372
  public function isEmpty() {
373
    return !$this->resourcesGetTotal() && !$this->shipsGetTotal();
374
  }
375
376
//  public function getPlayerOwnerId() {
0 ignored issues
show
Unused Code Comprehensibility introduced by
48% 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...
377
//    return $this->playerOwnerId;
378
//  }
379
380
  /**
381
   * Initializes Fleet from user params and posts it to DB
382
   */
383
  public function dbInsert() {
384
    // WARNING! MISSION TIMES MUST BE SET WITH set_times() method!
385
    // TODO - more checks!
386
    if (empty($this->_time_launch)) {
387
      die('Fleet time not set!');
388
    }
389
390
    parent::dbInsert();
391
  }
392
393
394
  /* FLEET DB ACCESS =================================================================================================*/
395
396
  /**
397
   * LOCK - Lock all records which can be used with mission
398
   *
399
   * @param $mission_data
400
   *
401
   * @return array|bool|mysqli_result|null
402
   */
403
  public function dbLockFlying(&$mission_data) {
404
    // Тупо лочим всех юзеров, чьи флоты летят или улетают с координат отбытия/прибытия $fleet_row
405
    // Что бы делать это умно - надо учитывать fleet__mess во $fleet_row и в таблице fleets
406
407
    $fleet_id_safe = idval($this->_dbId);
408
409
    return classSupernova::$db->doSelect(
410
    // Блокировка самого флота
411
      "SELECT 1 FROM {{fleets}} AS f " .
412
413
      // Блокировка всех юнитов, принадлежащих этому флоту
414
      "LEFT JOIN {{unit}} as unit ON unit.unit_location_type = " . static::$locationType . " AND unit.unit_location_id = f.fleet_id " .
415
416
      // Блокировка всех прилетающих и улетающих флотов, если нужно
417
      // TODO - lock fleets by COORDINATES
418
      ($mission_data['dst_fleets'] ? "LEFT JOIN {{fleets}} AS fd ON fd.fleet_end_planet_id = f.fleet_end_planet_id OR fd.fleet_start_planet_id = f.fleet_end_planet_id " : '') .
419
      // Блокировка всех юнитов, принадлежащих прилетающим и улетающим флотам - ufd = unit_fleet_destination
420
      ($mission_data['dst_fleets'] ? "LEFT JOIN {{unit}} AS ufd ON ufd.unit_location_type = " . static::$locationType . " AND ufd.unit_location_id = fd.fleet_id " : '') .
421
422
      ($mission_data['dst_user'] || $mission_data['dst_planet'] ? "LEFT JOIN {{users}} AS ud ON ud.id = f.fleet_target_owner " : '') .
423
      // Блокировка всех юнитов, принадлежащих владельцу планеты-цели
424
      ($mission_data['dst_user'] || $mission_data['dst_planet'] ? "LEFT JOIN {{unit}} AS unit_player_dest ON unit_player_dest.unit_player_id = ud.id " : '') .
425
      // Блокировка планеты-цели
426
      ($mission_data['dst_planet'] ? "LEFT JOIN {{planets}} AS pd ON pd.id = f.fleet_end_planet_id " : '') .
427
      // Блокировка всех юнитов, принадлежащих планете-цели - НЕ НУЖНО. Уже залочили ранее, как принадлежащие игроку-цели
428
//      ($mission_data['dst_planet'] ? "LEFT JOIN {{unit}} AS upd ON upd.unit_location_type = " . LOC_PLANET . " AND upd.unit_location_id = pd.id " : '') .
429
430
431
      ($mission_data['src_user'] || $mission_data['src_planet'] ? "LEFT JOIN {{users}} AS us ON us.id = f.fleet_owner " : '') .
432
      // Блокировка всех юнитов, принадлежащих владельцу флота
433
      ($mission_data['src_user'] || $mission_data['src_planet'] ? "LEFT JOIN {{unit}} AS unit_player_src ON unit_player_src.unit_player_id = us.id " : '') .
434
      // Блокировка планеты отправления
435
      ($mission_data['src_planet'] ? "LEFT JOIN {{planets}} AS ps ON ps.id = f.fleet_start_planet_id " : '') .
436
      // Блокировка всех юнитов, принадлежащих планете с которой юниты были отправлены - НЕ НУЖНО. Уже залочили ранее, как принадлежащие владельцу флота
437
//      ($mission_data['src_planet'] ? "LEFT JOIN {{unit}} AS ups ON ups.unit_location_type = " . LOC_PLANET . " AND ups.unit_location_id = ps.id " : '') .
438
439
      "WHERE f.fleet_id = {$fleet_id_safe} GROUP BY 1 FOR UPDATE"
440
    );
441
  }
442
443
  /**
444
   * Lock all fields that belongs to operation
445
   *
446
   * @param $dbId
447
   */
448
  // TODO = make static
449
  public function dbGetLockById($dbId) {
450
    classSupernova::$db->doSelect(
451
    // Блокировка самого флота
452
      "SELECT 1 FROM {{fleets}} AS FLEET0 " .
453
      // Lock fleet owner
454
      "LEFT JOIN {{users}} as USER0 on USER0.id = FLEET0.fleet_owner " .
455
      // Блокировка всех юнитов, принадлежащих этому флоту
456
      "LEFT JOIN {{unit}} as UNIT0 ON UNIT0.unit_location_type = " . LOC_FLEET . " AND UNIT0.unit_location_id = FLEET0.fleet_id " .
457
458
      // Без предварительной выборки неизвестно - куда летит этот флот.
459
      // Поэтому надо выбирать флоты, чьи координаты прибытия ИЛИ отбытия совпадают с координатами прибытия ИЛИ отбытия текущего флота.
460
      // Получаем матрицу 2х2 - т.е. 4 подзапроса.
461
      // При блокировке всегда нужно выбирать И лпанету, И луну - поскольку при бое на орбите луны обломки падают на орбиту планеты.
462
      // Поэтому тип планеты не указывается
463
464
      // Lock fleet heading to destination planet. Only if FLEET0.fleet_mess == 0
465
      "LEFT JOIN {{fleets}} AS FLEET1 ON
466
        FLEET1.fleet_mess = 0 AND FLEET0.fleet_mess = 0 AND
467
        FLEET1.fleet_end_galaxy = FLEET0.fleet_end_galaxy AND
468
        FLEET1.fleet_end_system = FLEET0.fleet_end_system AND
469
        FLEET1.fleet_end_planet = FLEET0.fleet_end_planet
470
      " .
471
      // Блокировка всех юнитов, принадлежащих этим флотам
472
      "LEFT JOIN {{unit}} as UNIT1 ON UNIT1.unit_location_type = " . LOC_FLEET . " AND UNIT1.unit_location_id = FLEET1.fleet_id " .
473
      // Lock fleet owner
474
      "LEFT JOIN {{users}} as USER1 on USER1.id = FLEET1.fleet_owner " .
475
476
      "LEFT JOIN {{fleets}} AS FLEET2 ON
477
        FLEET2.fleet_mess = 1   AND FLEET0.fleet_mess = 0 AND
478
        FLEET2.fleet_start_galaxy = FLEET0.fleet_end_galaxy AND
479
        FLEET2.fleet_start_system = FLEET0.fleet_end_system AND
480
        FLEET2.fleet_start_planet = FLEET0.fleet_end_planet
481
      " .
482
      // Блокировка всех юнитов, принадлежащих этим флотам
483
      "LEFT JOIN {{unit}} as UNIT2 ON
484
        UNIT2.unit_location_type = " . LOC_FLEET . " AND
485
        UNIT2.unit_location_id = FLEET2.fleet_id
486
      " .
487
      // Lock fleet owner
488
      "LEFT JOIN {{users}} as USER2 on
489
        USER2.id = FLEET2.fleet_owner
490
      " .
491
492
      // Lock fleet heading to source planet. Only if FLEET0.fleet_mess == 1
493
      "LEFT JOIN {{fleets}} AS FLEET3 ON
494
        FLEET3.fleet_mess = 0 AND FLEET0.fleet_mess = 1 AND
495
        FLEET3.fleet_end_galaxy = FLEET0.fleet_start_galaxy AND
496
        FLEET3.fleet_end_system = FLEET0.fleet_start_system AND
497
        FLEET3.fleet_end_planet = FLEET0.fleet_start_planet
498
      " .
499
      // Блокировка всех юнитов, принадлежащих этим флотам
500
      "LEFT JOIN {{unit}} as UNIT3 ON
501
        UNIT3.unit_location_type = " . LOC_FLEET . " AND
502
        UNIT3.unit_location_id = FLEET3.fleet_id
503
      " .
504
      // Lock fleet owner
505
      "LEFT JOIN {{users}} as USER3 on USER3.id = FLEET3.fleet_owner " .
506
507
      "LEFT JOIN {{fleets}} AS FLEET4 ON
508
        FLEET4.fleet_mess = 1   AND FLEET0.fleet_mess = 1 AND
509
        FLEET4.fleet_start_galaxy = FLEET0.fleet_start_galaxy AND
510
        FLEET4.fleet_start_system = FLEET0.fleet_start_system AND
511
        FLEET4.fleet_start_planet = FLEET0.fleet_start_planet
512
      " .
513
      // Блокировка всех юнитов, принадлежащих этим флотам
514
      "LEFT JOIN {{unit}} as UNIT4 ON
515
        UNIT4.unit_location_type = " . LOC_FLEET . " AND
516
        UNIT4.unit_location_id = FLEET4.fleet_id
517
      " .
518
      // Lock fleet owner
519
      "LEFT JOIN {{users}} as USER4 on
520
        USER4.id = FLEET4.fleet_owner
521
      " .
522
523
524
      // Locking start planet
525
      "LEFT JOIN {{planets}} AS PLANETS5 ON
526
        FLEET0.fleet_mess = 1 AND
527
        PLANETS5.galaxy = FLEET0.fleet_start_galaxy AND
528
        PLANETS5.system = FLEET0.fleet_start_system AND
529
        PLANETS5.planet = FLEET0.fleet_start_planet
530
      " .
531
      // Lock planet owner
532
      "LEFT JOIN {{users}} as USER5 on
533
        USER5.id = PLANETS5.id_owner
534
      " .
535
      // Блокировка всех юнитов, принадлежащих этой планете
536
      "LEFT JOIN {{unit}} as UNIT5 ON
537
        UNIT5.unit_location_type = " . LOC_PLANET . " AND
538
        UNIT5.unit_location_id = PLANETS5.id
539
      " .
540
541
542
      // Locking destination planet
543
      "LEFT JOIN {{planets}} AS PLANETS6 ON
544
        FLEET0.fleet_mess = 0 AND
545
        PLANETS6.galaxy = FLEET0.fleet_end_galaxy AND
546
        PLANETS6.system = FLEET0.fleet_end_system AND
547
        PLANETS6.planet = FLEET0.fleet_end_planet
548
      " .
549
      // Lock planet owner
550
      "LEFT JOIN {{users}} as USER6 on
551
        USER6.id = PLANETS6.id_owner
552
      " .
553
      // Блокировка всех юнитов, принадлежащих этой планете
554
      "LEFT JOIN {{unit}} as UNIT6 ON
555
        UNIT6.unit_location_type = " . LOC_PLANET . " AND
556
        UNIT6.unit_location_id = PLANETS6.id
557
      " .
558
      "WHERE FLEET0.fleet_id = {$dbId} GROUP BY 1 FOR UPDATE"
559
    );
560
  }
561
562
563
  public function dbRowParse($db_row) {
564
    parent::dbRowParse($db_row); // TODO: Change the autogenerated stub
565
    $player = new Player();
566
    $player->dbLoad($db_row['fleet_owner']);
567
    $this->setLocatedAt($player);
568
  }
569
570
  /* FLEET HELPERS =====================================================================================================*/
571
  /**
572
   * Forcibly returns fleet before time outs
573
   */
574
  public function commandReturn() {
575
    $ReturnFlyingTime = ($this->_time_mission_job_complete != 0 && $this->_time_arrive_to_target < SN_TIME_NOW ? $this->_time_arrive_to_target : SN_TIME_NOW) - $this->_time_launch + SN_TIME_NOW + 1;
576
577
    $this->markReturned();
578
579
    // Считаем, что флот уже долетел TODO
580
    $this->time_arrive_to_target = SN_TIME_NOW;
581
    // Убираем флот из группы
582
    $this->group_id = 0;
583
    // Отменяем работу в точке назначения
584
    $this->time_mission_job_complete = 0;
585
    // TODO - правильно вычслять время возвращения - по проделанному пути, а не по старому времени возвращения
586
    $this->time_return_to_source = $ReturnFlyingTime;
587
588
    // Записываем изменения в БД
589
    $this->dbSave();
590
591
    if ($this->_group_id) {
592
      // TODO: Make here to delete only one AKS - by adding aks_fleet_count to AKS table
593
      DBStaticFleetACS::db_fleet_aks_purge();
594
    }
595
  }
596
597
598
  /**
599
   * @return array
600
   */
601
  public function target_coordinates_without_type() {
602
    return array(
603
      'galaxy' => $this->_fleet_end_galaxy,
604
      'system' => $this->_fleet_end_system,
605
      'planet' => $this->_fleet_end_planet,
606
    );
607
  }
608
609
  /**
610
   * @return array
611
   */
612
  public function target_coordinates_typed() {
613
    return array(
614
      'galaxy' => $this->_fleet_end_galaxy,
615
      'system' => $this->_fleet_end_system,
616
      'planet' => $this->_fleet_end_planet,
617
      'type'   => $this->_fleet_end_type,
618
    );
619
  }
620
621
  /**
622
   * @return array
623
   */
624
  public function launch_coordinates_typed() {
625
    return array(
626
      'galaxy' => $this->_fleet_start_galaxy,
627
      'system' => $this->_fleet_start_system,
628
      'planet' => $this->_fleet_start_planet,
629
      'type'   => $this->_fleet_start_type,
630
    );
631
  }
632
633
634
  /**
635
   * Sets object fields for fleet return
636
   */
637
  public function markReturned() {
638
    // TODO - Проверка - а не возвращается ли уже флот?
639
    $this->is_returning = 1;
640
  }
641
642
  public function isReturning() {
643
    return 1 == $this->_is_returning;
644
  }
645
646
  public function markReturnedAndSave() {
647
    $this->markReturned();
648
    $this->dbSave();
649
  }
650
651
  /**
652
   * Parses extended unit_array which can include not only ships but resources, captains etc
653
   *
654
   * @param $unit_array
655
   *
656
   * @throws Exception
657
   */
658
  // TODO - separate shipList and unitList
659
  public function unitsSetFromArray($unit_array) {
660
    if (empty($unit_array) || !is_array($unit_array)) {
661
      return;
662
    }
663
    foreach ($unit_array as $unit_id => $unit_count) {
664
      $unit_count = floatval($unit_count);
665
      if (!$unit_count) {
666
        continue;
667
      }
668
669
      if ($this->isShip($unit_id) || $this->isMissile($unit_id)) {
670
        $this->unitList->unitSetCount($unit_id, $unit_count);
671
      } elseif ($this->isResource($unit_id)) {
672
        $this->resource_list[$unit_id] = $unit_count;
673
      } else {
674
        throw new Exception('Trying to pass to fleet non-resource and non-ship ' . var_export($unit_array, true), FLIGHT_SHIPS_UNIT_WRONG);
675
      }
676
    }
677
  }
678
679
680
  /**
681
   * Sets fleet timers based on flight duration, time on mission (HOLD/EXPLORE) and fleet departure time.
682
   *
683
   * @param int $time_to_travel - flight duration in seconds
684
   * @param int $time_on_mission - time on mission in seconds
685
   * @param int $flight_departure - fleet departure from source planet timestamp. Allows to send fleet in future or in past
686
   */
687
  public function set_times($time_to_travel, $time_on_mission = 0, $flight_departure = SN_TIME_NOW) {
688
    $this->_time_launch = $flight_departure;
689
690
    $this->_time_arrive_to_target = $this->_time_launch + $time_to_travel;
691
    $this->_time_mission_job_complete = $time_on_mission ? $this->_time_arrive_to_target + $time_on_mission : 0;
692
    $this->_time_return_to_source = ($this->_time_mission_job_complete ? $this->_time_mission_job_complete : $this->_time_arrive_to_target) + $time_to_travel;
693
  }
694
695
696
  public function parse_missile_db_row($missile_db_row) {
697
//    $this->_reset();
0 ignored issues
show
Unused Code Comprehensibility introduced by
72% 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...
698
699
    if (empty($missile_db_row) || !is_array($missile_db_row)) {
700
      return;
701
    }
702
703
//      $planet_start = db_planet_by_vector($irak_original, 'fleet_start_', false, 'name');
0 ignored issues
show
Unused Code Comprehensibility introduced by
61% 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...
704
//      $irak_original['fleet_start_name'] = $planet_start['name'];
705
    $this->missile_target = $missile_db_row['primaer'];
706
707
    $this->_dbId = -$missile_db_row['id'];
708
    $this->_playerOwnerId = $missile_db_row['fleet_owner'];
709
    $this->_mission_type = MT_MISSILE;
710
711
    $this->_target_owner_id = $missile_db_row['fleet_target_owner'];
712
713
    $this->_group_id = 0;
714
    $this->_is_returning = 0;
715
716
    $this->_time_launch = 0; // $irak['start_time'];
0 ignored issues
show
Unused Code Comprehensibility introduced by
84% 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...
717
    $this->_time_arrive_to_target = 0; // $irak['fleet_start_time'];
0 ignored issues
show
Unused Code Comprehensibility introduced by
84% 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...
718
    $this->_time_mission_job_complete = 0; // $irak['fleet_end_stay'];
0 ignored issues
show
Unused Code Comprehensibility introduced by
84% 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...
719
    $this->_time_return_to_source = $missile_db_row['fleet_end_time'];
720
721
    $this->_fleet_start_planet_id = !empty($missile_db_row['fleet_start_planet_id']) ? $missile_db_row['fleet_start_planet_id'] : null;
722
    $this->_fleet_start_galaxy = $missile_db_row['fleet_start_galaxy'];
723
    $this->_fleet_start_system = $missile_db_row['fleet_start_system'];
724
    $this->_fleet_start_planet = $missile_db_row['fleet_start_planet'];
725
    $this->_fleet_start_type = $missile_db_row['fleet_start_type'];
726
727
    $this->_fleet_end_planet_id = !empty($missile_db_row['fleet_end_planet_id']) ? $missile_db_row['fleet_end_planet_id'] : null;
728
    $this->_fleet_end_galaxy = $missile_db_row['fleet_end_galaxy'];
729
    $this->_fleet_end_system = $missile_db_row['fleet_end_system'];
730
    $this->_fleet_end_planet = $missile_db_row['fleet_end_planet'];
731
    $this->_fleet_end_type = $missile_db_row['fleet_end_type'];
732
733
    $this->unitList->unitSetCount(UNIT_DEF_MISSILE_INTERPLANET, $missile_db_row['fleet_amount']);
734
  }
735
736
737
  /**
738
   * @param $from
739
   */
740
  public function set_start_planet($from) {
741
    $this->fleet_start_planet_id = intval($from['id']) ? $from['id'] : null;
742
    $this->fleet_start_galaxy = $from['galaxy'];
743
    $this->fleet_start_system = $from['system'];
744
    $this->fleet_start_planet = $from['planet'];
745
    $this->fleet_start_type = $from['planet_type'];
746
  }
747
748
  /**
749
   * @param $to
750
   */
751
  public function set_end_planet($to) {
752
    $this->target_owner_id = intval($to['id_owner']) ? $to['id_owner'] : 0;
753
    $this->fleet_end_planet_id = intval($to['id']) ? $to['id'] : null;
754
    $this->fleet_end_galaxy = $to['galaxy'];
755
    $this->fleet_end_system = $to['system'];
756
    $this->fleet_end_planet = $to['planet'];
757
    $this->fleet_end_type = $to['planet_type'];
758
  }
759
760
  /**
761
   * @param Vector $to
762
   */
763
  public function setTargetFromVectorObject($to) {
764
    $this->_fleet_end_galaxy = $to->galaxy;
765
    $this->_fleet_end_system = $to->system;
766
    $this->_fleet_end_planet = $to->planet;
767
    $this->_fleet_end_type = $to->type;
768
  }
769
770
  /**
771
   * @param array $db_row
772
   */
773
  protected function ownerExtract(array &$db_row) {
774
    $player = new Player();
775
    $player->dbLoad($db_row['fleet_owner']);
776
    $this->setLocatedAt($player);
777
  }
778
779
  /**
780
   * @param array $db_row
781
   */
782
  protected function ownerInject(array &$db_row) {
783
    $db_row['fleet_owner'] = $this->getPlayerOwnerId();
784
  }
785
786
787
788
789
  // UnitList/Ships access ***************************************************************************************************
790
791
  // TODO - перекрывать пожже - для миссайл-флотов и дефенс-флотов
792
  protected function isShip($unit_id) {
793
    return UnitShip::is_in_group($unit_id);
794
  }
795
796
  protected function isMissile($unit_id) {
797
    return isInGroup(GROUP_STR_MISSILES, $unit_id);
798
  }
799
800
  /**
801
   * Set unit count of $unit_id to $unit_count
802
   * If there is no $unit_id - it will be created and saved to DB on dbSave
803
   *
804
   * @param int $unit_id
805
   * @param int $unit_count
806
   */
807
  public function shipSetCount($unit_id, $unit_count = 0) {
808
    pdump(__CLASS__ . '->' . __FUNCTION__);
809
    $this->shipAdjustCount($unit_id, $unit_count, true);
810
  }
811
812
  /**
813
   * Adjust unit count of $unit_id by $unit_count - or just replace value
814
   * If there is no $unit_id - it will be created and saved to DB on dbSave
815
   *
816
   * @param int  $unit_id
817
   * @param int  $unit_count
818
   * @param bool $replace_value
819
   */
820
  public function shipAdjustCount($unit_id, $unit_count = 0, $replace_value = false) {
821
    $this->unitList->unitAdjustCount($unit_id, $unit_count, $replace_value);
822
  }
823
824
  public function shipGetCount($unit_id) {
825
    return $this->unitList->unitGetCount($unit_id);
826
  }
827
828
  public function shipsCountApplyLossMultiplier($ships_lost_multiplier) {
829
    $this->unitList->unitsCountApplyLossMultiplier($ships_lost_multiplier);
830
  }
831
832
  /**
833
   * Returns fleet ships cost in metal
834
   *
835
   * @param array $shipCostInMetalPerPiece
836
   *
837
   * @return float[]
838
   */
839
  public function shipsCostInMetal($shipCostInMetalPerPiece) {
840
    return $this->unitList->unitsCostInMetal($shipCostInMetalPerPiece);
841
  }
842
843
  /**
844
   * @return UnitIterator
845
   */
846
  public function shipsIterator() {
847
    return $this->unitList->getUnitIterator();
848
  }
849
850
  public function shipsGetTotal() {
851
    return $this->unitList->unitsCount();
852
  }
853
854
  public function shipsGetCapacity() {
855
    return $this->unitList->shipsCapacity();
856
  }
857
858
  public function shipsGetHoldFree() {
859
    return max(0, $this->shipsGetCapacity() - $this->resourcesGetTotal());
860
  }
861
862
  /**
863
   * Get count of ships with $ship_id
864
   *
865
   * @param int $ship_id
866
   *
867
   * @return int
868
   */
869
  public function shipsGetTotalById($ship_id) {
870
    return $this->unitList->unitsCountById($ship_id);
871
  }
872
873
  /**
874
   * Возвращает ёмкость переработчиков во флоте
875
   *
876
   * @param array $recycler_info
877
   *
878
   * @return int
879
   *
880
   */
881
  public function shipsGetCapacityRecyclers($recycler_info) {
882
    $recyclers_incoming_capacity = 0;
883
    foreach ($this->shipsIterator() as $unitId => $unit) {
884
      if (!empty(static::$snGroupRecyclers[$unitId]) && $unit->count >= 1) {
885
        $recyclers_incoming_capacity += $unit->count * $recycler_info[$unitId]['capacity'];
886
      }
887
    }
888
889
    return $recyclers_incoming_capacity;
890
  }
891
892
  /**
893
   * @return bool
894
   */
895
  // TODO - А если не на планете????
896
  public function shipsIsEnoughOnPlanet() {
897
    return $this->unitList->shipsIsEnoughOnPlanet($this->dbOwnerRow, $this->dbSourcePlanetRow);
898
  }
899
900
  /**
901
   * @return bool
902
   */
903
  public function shipsAllPositive() {
904
    return $this->unitList->unitsPositive();
905
  }
906
907
  /**
908
   * @return bool
909
   */
910
  public function shipsAllFlying() {
911
    return $this->unitList->unitsInGroup(static::$snGroupFleetAndMissiles);
912
  }
913
914
  /**
915
   * @return bool
916
   */
917
  public function shipsAllMovable() {
918
    return $this->unitList->unitsIsAllMovable($this->dbOwnerRow);
919
  }
920
921
  /**
922
   * Restores fleet or resources to planet
923
   *
924
   * @param bool $start
925
   * @param int  $result
926
   *
927
   * @return int
928
   */
929
  // TODO - split to functions
930
  public function shipsLand($start = true, &$result = CACHE_NOTHING) {
931
    sn_db_transaction_check(true);
932
933
    // Если флот уже обработан - не существует или возращается - тогда ничего не делаем
934
    if ($this->isEmpty()) {
935
      return $result;
936
    }
937
938
    $coordinates = $start ? $this->launch_coordinates_typed() : $this->target_coordinates_typed();
939
940
    // Поскольку эта функция может быть вызвана не из обработчика флотов - нам надо всё заблокировать вроде бы НЕ МОЖЕТ!!!
941
    // TODO Проверить от многократного срабатывания !!!
942
    // Тут не блокируем пока - сначала надо заблокировать пользователя, что бы не было дедлока
943
    // TODO поменять на владельца планеты - когда его будут возвращать всегда !!!
944
945
    // Узнаем ИД владельца планеты.
946
    // С блокировкой, поскольку эта функция может быть вызвана только из менеджера летящих флотов.
947
    // А там уже всё заблокировано как надо и повторная блокировка не вызовет дедлок.
948
    $planet_arrival = DBStaticPlanet::db_planet_by_vector($coordinates, '', true);
949
    // Блокируем пользователя
950
    // TODO - вообще-то нам уже известен пользователь в МЛФ - так что можно просто передать его сюда
951
    $user = DBStaticUser::db_user_by_id($planet_arrival['id_owner'], true);
952
953
    // TODO - Проверка, что планета всё еще существует на указанных координатах, а не телепортировалась, не удалена хозяином, не уничтожена врагом
954
    // Флот, который возвращается на захваченную планету, пропадает
955
    // Ship landing is possible only to fleet owner's planet
956
    if ($this->getPlayerOwnerId() == $planet_arrival['id_owner']) {
957
      // Adjusting ship amount on planet
958
      foreach ($this->shipsIterator() as $ship_id => $ship) {
959
        if ($ship->count) {
960
          DBStaticUnit::dbUpdateOrInsertUnit($ship_id, $ship->count, $user, $planet_arrival['id']);
961
        }
962
      }
963
964
      // Restoring resources to planet
965
      $this->resourcesUnload($start, $result);
966
    }
967
968
    $result = CACHE_FLEET | ($start ? CACHE_PLANET_SRC : CACHE_PLANET_DST);
969
970
    $result = RestoreFleetToPlanet($this, $start, $result);
971
972
    $this->dbDelete();
973
974
    return $result;
975
  }
976
977
978
  // Resources access ***************************************************************************************************
979
980
  /**
981
   * Extracts resources value from db_row
982
   *
983
   * @param array $db_row
984
   *
985
   * @internal param Fleet $that
986
   */
987
  protected function resourcesExtract(array &$db_row) {
988
    $this->resource_list = array(
989
      RES_METAL     => !empty($db_row['fleet_resource_metal']) ? floor($db_row['fleet_resource_metal']) : 0,
990
      RES_CRYSTAL   => !empty($db_row['fleet_resource_crystal']) ? floor($db_row['fleet_resource_crystal']) : 0,
991
      RES_DEUTERIUM => !empty($db_row['fleet_resource_deuterium']) ? floor($db_row['fleet_resource_deuterium']) : 0,
992
    );
993
  }
994
995
  protected function resourcesInject(array &$db_row) {
996
    $db_row['fleet_resource_metal'] = $this->resource_list[RES_METAL];
997
    $db_row['fleet_resource_crystal'] = $this->resource_list[RES_CRYSTAL];
998
    $db_row['fleet_resource_deuterium'] = $this->resource_list[RES_DEUTERIUM];
999
  }
1000
1001
  /**
1002
   * Set current resource list from array of units
1003
   *
1004
   * @param array $resource_list
1005
   */
1006
  public function resourcesSet($resource_list) {
1007
    if (!empty($this->propertiesAdjusted['resource_list'])) {
1008
      throw new PropertyAccessException('Property "resource_list" already was adjusted so no SET is possible until dbSave in ' . get_called_class() . '::unitSetResourceList', ERR_ERROR);
1009
    }
1010
    $this->resourcesAdjust($resource_list, true);
1011
  }
1012
1013
  /**
1014
   * Updates fleet resource list with deltas
1015
   *
1016
   * @param array $resource_delta_list
1017
   * @param bool  $replace_value
1018
   *
1019
   * @throws Exception
1020
   */
1021
  public function resourcesAdjust($resource_delta_list, $replace_value = false) {
1022
    !is_array($resource_delta_list) ? $resource_delta_list = array() : false;
1023
1024
    foreach ($resource_delta_list as $resource_id => $unit_delta) {
1025
      if (!UnitResourceLoot::is_in_group($resource_id) || !($unit_delta = floor($unit_delta))) {
1026
        // Not a resource or no resources - continuing
1027
        continue;
1028
      }
1029
1030
      if ($replace_value) {
1031
        $this->resource_list[$resource_id] = $unit_delta;
1032
      } else {
1033
        $this->resource_list[$resource_id] += $unit_delta;
1034
        // Preparing changes
1035
        $this->resource_delta[$resource_id] += $unit_delta;
1036
        $this->propertiesAdjusted['resource_list'] = 1;
1037
      }
1038
1039
      // Check for negative unit value
1040
      if ($this->resource_list[$resource_id] < 0) {
1041
        // TODO
1042
        throw new Exception('Resource ' . $resource_id . ' will become negative in ' . get_called_class() . '::unitAdjustResourceList', ERR_ERROR);
1043
      }
1044
    }
1045
  }
1046
1047
  public function resourcesGetTotal() {
1048
    return empty($this->resource_list) || !is_array($this->resource_list) ? 0 : array_sum($this->resource_list);
1049
  }
1050
1051
  /**
1052
   * @param array $rate
1053
   *
1054
   * @return float
1055
   */
1056
  public function resourcesGetTotalInMetal(array $rate) {
1057
    return
1058
      $this->resource_list[RES_METAL] * $rate[RES_METAL]
1059
      + $this->resource_list[RES_CRYSTAL] * $rate[RES_CRYSTAL] / $rate[RES_METAL]
1060
      + $this->resource_list[RES_DEUTERIUM] * $rate[RES_DEUTERIUM] / $rate[RES_METAL];
1061
  }
1062
1063
  /**
1064
   * Returns resource list in fleet
1065
   */
1066
  // TODO
1067
  public function resourcesGetList() {
1068
    return $this->resource_list;
1069
  }
1070
1071
  public function resourcesReset() {
1072
    $this->resourcesSet(array(
1073
      RES_METAL     => 0,
1074
      RES_CRYSTAL   => 0,
1075
      RES_DEUTERIUM => 0,
1076
    ));
1077
  }
1078
1079
  /**
1080
   * Restores fleet or resources to planet
1081
   *
1082
   * @param bool $start
1083
   * @param bool $only_resources
0 ignored issues
show
Bug introduced by
There is no parameter named $only_resources. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
1084
   * @param int  $result
1085
   *
1086
   * @return int
1087
   */
1088
  public function resourcesUnload($start = true, &$result = CACHE_NOTHING) {
1089
    sn_db_transaction_check(true);
1090
1091
    // Если флот уже обработан - не существует или возращается - тогда ничего не делаем
1092
    if (!$this->resourcesGetTotal()) {
1093
      return $result;
1094
    }
1095
1096
    $coordinates = $start ? $this->launch_coordinates_typed() : $this->target_coordinates_typed();
1097
1098
    // Поскольку эта функция может быть вызвана не из обработчика флотов - нам надо всё заблокировать вроде бы НЕ МОЖЕТ!!!
1099
    // TODO Проверить от многократного срабатывания !!!
1100
    // Тут не блокируем пока - сначала надо заблокировать пользователя, что бы не было дедлока
1101
    // TODO поменять на владельца планеты - когда его будут возвращать всегда !!!
1102
1103
1104
    // Узнаем ИД владельца планеты.
1105
    // С блокировкой, поскольку эта функция может быть вызвана только из менеджера летящих флотов.
1106
    // А там уже всё заблокировано как надо и повторная блокировка не вызовет дедлок.
1107
    $planet_arrival = DBStaticPlanet::db_planet_by_vector($coordinates, '', true);
1108
1109
    // TODO - Проверка, что планета всё еще существует на указанных координатах, а не телепортировалась, не удалена хозяином, не уничтожена врагом
1110
1111
    // Restoring resources to planet
1112
    if ($this->resourcesGetTotal()) {
1113
      $fleet_resources = $this->resourcesGetList();
1114
      DBStaticPlanet::db_planet_update_set_by_id($planet_arrival['id'],
1115
        "`metal` = `metal` + '{$fleet_resources[RES_METAL]}', `crystal` = `crystal` + '{$fleet_resources[RES_CRYSTAL]}', `deuterium` = `deuterium` + '{$fleet_resources[RES_DEUTERIUM]}'");
1116
    }
1117
1118
    $this->resourcesReset();
1119
    $this->markReturned();
1120
1121
    $result = CACHE_FLEET | ($start ? CACHE_PLANET_SRC : CACHE_PLANET_DST);
1122
1123
    return $result;
1124
  }
1125
1126
1127
  protected function isResource($unit_id) {
1128
    return UnitResourceLoot::is_in_group($unit_id);
1129
  }
1130
1131
  /**
1132
   * @param int $speed_percent
1133
   *
1134
   * @return array
1135
   */
1136
  protected function flt_travel_data($speed_percent = 10) {
1137
    $distance = $this->targetVector->distanceFromCoordinates($this->dbSourcePlanetRow);
1138
1139
    return $this->unitList->travelData($speed_percent, $distance, $this->dbOwnerRow);
1140
  }
1141
1142
1143
  /**
1144
   * @param array  $dbPlayerRow
1145
   * @param array  $dbPlanetRow
1146
   * @param Vector $targetVector
1147
   *
1148
   */
1149
  public function initDefaults($dbPlayerRow, $dbPlanetRow, $targetVector, $mission, $ships, $fleet_group_mr, $oldSpeedInTens = 10, $targetedUnitId = 0, $captainId = 0, $resources = array()) {
0 ignored issues
show
Unused Code introduced by
The parameter $resources is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1150
    $objFleet5Player = new Player();
1151
    $objFleet5Player->dbRowParse($dbPlayerRow);
1152
    $this->setLocatedAt($objFleet5Player);
1153
1154
    $this->mission_type = $mission;
1155
1156
    $this->dbOwnerRow = $dbPlayerRow;
1157
1158
    $this->set_start_planet($dbPlanetRow);
1159
    $this->dbSourcePlanetRow = $dbPlanetRow;
1160
1161
    $this->setTargetFromVectorObject($targetVector);
1162
    $this->targetVector = $targetVector;
1163
1164
//    if ($this->mission_type != MT_NONE) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% 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...
1165
//      $this->restrictTargetTypeByMission();
1166
//
1167
//      // TODO - Нельзя тут просто менять тип планеты или координат!
1168
//      // If current planet type is not allowed on mission - switch planet type
1169
//      if (empty($this->allowed_planet_types[$this->targetVector->type])) {
1170
//        $targetPlanetCoords->type = reset($this->allowed_planet_types);
1171
//      }
1172
//    }
1173
1174
    $this->populateTargetPlanetAndOwner();
1175
1176
    $this->unitsSetFromArray($ships);
1177
1178
    $this->_group_id = intval($fleet_group_mr);
1179
1180
    $this->oldSpeedInTens = $oldSpeedInTens;
1181
1182
    $this->targetedUnitId = $targetedUnitId;
1183
1184
    $this->captainId = $captainId;
1185
1186
    $this->_time_launch = SN_TIME_NOW;
1187
1188
    $this->renderParamCoordinates();
1189
1190
  }
1191
1192
  protected function restrictTargetTypeByMission() {
1193
    if ($this->_mission_type == MT_MISSILE) {
1194
      $this->allowed_planet_types = array(PT_PLANET => PT_PLANET);
1195
    } elseif ($this->_mission_type == MT_COLONIZE || $this->_mission_type == MT_EXPLORE) {
1196
      // TODO - PT_NONE
1197
      $this->allowed_planet_types = array(PT_PLANET => PT_PLANET);
1198
    } elseif ($this->_mission_type == MT_RECYCLE) {
1199
      $this->allowed_planet_types = array(PT_DEBRIS => PT_DEBRIS);
1200
    } elseif ($this->_mission_type == MT_DESTROY) {
1201
      $this->allowed_planet_types = array(PT_MOON => PT_MOON);
1202
    } else {
1203
      $this->allowed_planet_types = array(PT_PLANET => PT_PLANET, PT_MOON => PT_MOON);
1204
    }
1205
  }
1206
1207
  protected function populateTargetPlanetAndOwner() {
1208
    // If vector points to no exact object OR debris - then getting planet on coordinates
1209
    $targetVector = clone $this->targetVector;
1210
    if ($targetVector->type == PT_DEBRIS || $targetVector == PT_NONE) {
1211
      $targetVector->type = PT_PLANET;
1212
    }
1213
1214
    $this->dbTargetRow = DBStaticPlanet::db_planet_by_vector_object($targetVector);
1215 View Code Duplication
    if (!empty($this->dbTargetRow['id_owner'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1216
      $this->dbTargetOwnerRow = DBStaticUser::db_user_by_id($this->dbTargetRow['id_owner'], true);
0 ignored issues
show
Documentation Bug introduced by
It seems like \DBStaticUser::db_user_b...tRow['id_owner'], true) can also be of type false. However, the property $dbTargetOwnerRow is declared as type array. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
1217
    }
1218
  }
1219
1220
1221
  protected function printErrorIfNoShips() {
1222
    if ($this->unitList->unitsCount() <= 0) {
1223
      message(classLocale::$lang['fl_err_no_ships'], classLocale::$lang['fl_error'], 'fleet' . DOT_PHP_EX, 5);
1224
    }
1225
  }
1226
1227
  /**
1228
   */
1229
  public function renderParamCoordinates() {
1230
    global $template_result;
1231
    $template_result += array(
1232
      'thisgalaxy'      => $this->dbSourcePlanetRow['galaxy'],
1233
      'thissystem'      => $this->dbSourcePlanetRow['system'],
1234
      'thisplanet'      => $this->dbSourcePlanetRow['planet'],
1235
      'thisplanet_type' => $this->dbSourcePlanetRow['planet_type'],
1236
1237
      'galaxy'         => $this->targetVector->galaxy,
1238
      'system'         => $this->targetVector->system,
1239
      'planet'         => $this->targetVector->planet,
1240
      'planet_type'    => $this->targetVector->type,
1241
      'target_mission' => $this->_mission_type,
1242
      'MISSION_NAME'   => $this->_mission_type ? classLocale::$lang['type_mission'][$this->_mission_type] : '',
1243
1244
      'MT_COLONIZE' => MT_COLONIZE,
1245
    );
1246
  }
1247
1248
1249
  protected function renderFleetCoordinates($missionStartTimeStamp = SN_TIME_NOW, $timeMissionJob = 0) {
1250
    $timeToReturn = $this->travelData['duration'] * 2 + $timeMissionJob;
1251
1252
    return array(
1253
      'ID'                 => 1,
1254
      'START_TYPE_TEXT_SH' => classLocale::$lang['sys_planet_type_sh'][$this->dbSourcePlanetRow['planet_type']],
1255
      'START_COORDS'       => uni_render_coordinates($this->dbSourcePlanetRow),
1256
      'START_NAME'         => $this->dbSourcePlanetRow['name'],
1257
      'START_TIME_TEXT'    => date(FMT_DATE_TIME, $missionStartTimeStamp + $timeToReturn + SN_CLIENT_TIME_DIFF),
1258
      'START_LEFT'         => floor($timeToReturn),
1259
      'END_TYPE_TEXT_SH'   =>
1260
        !empty($this->targetVector->type)
1261
          ? classLocale::$lang['sys_planet_type_sh'][$this->targetVector->type]
1262
          : '',
1263
      'END_COORDS'         => uniRenderVector($this->targetVector),
1264
      'END_NAME'           => !empty($this->dbTargetRow['name']) ? $this->dbTargetRow['name'] : '',
1265
      'END_TIME_TEXT'      => date(FMT_DATE_TIME, $missionStartTimeStamp + $this->travelData['duration'] + SN_CLIENT_TIME_DIFF),
1266
      'END_LEFT'           => floor($this->travelData['duration']),
1267
    );
1268
  }
1269
1270
  /**
1271
   * @param int $missionStartTimeStamp
1272
   * @param int $timeMissionJob
1273
   *
1274
   * @return array
1275
   *
1276
   * @throws Exception
1277
   */
1278
  protected function renderFleet($missionStartTimeStamp = SN_TIME_NOW, $timeMissionJob = 0) {
1279
    $this->printErrorIfNoShips();
1280
1281
    $result = $this->renderFleetCoordinates($missionStartTimeStamp, $timeMissionJob);
1282
    $result['.']['ships'] = $this->unitList->unitsRender();
1283
1284
    return $result;
1285
  }
1286
1287
  /**
1288
   * @return array
1289
   */
1290
  protected function renderAllowedMissions() {
1291
    $result = array();
1292
1293
    ksort($this->allowed_missions);
1294
    // If mission is not set - setting first mission from allowed
1295
    if (empty($this->_mission_type) && is_array($this->allowed_missions)) {
1296
      reset($this->allowed_missions);
1297
      $this->_mission_type = key($this->allowed_missions);
1298
    }
1299
    foreach ($this->allowed_missions as $key => $value) {
1300
      $result[] = array(
1301
        'ID'   => $key,
1302
        'NAME' => classLocale::$lang['type_mission'][$key],
1303
      );
1304
    };
1305
1306
    return $result;
1307
  }
1308
1309
  /**
1310
   * @param $max_duration
1311
   *
1312
   * @return array
1313
   */
1314
  protected function renderDuration($max_duration) {
1315
    $result = array();
1316
1317
    if (!$max_duration) {
1318
      return $result;
1319
    }
1320
1321
    $config_game_speed_expedition = ($this->_mission_type == MT_EXPLORE && classSupernova::$config->game_speed_expedition ? classSupernova::$config->game_speed_expedition : 1);
1322
    for ($i = 1; $i <= $max_duration; $i++) {
1323
      $result[] = array(
1324
        'ID'   => $i,
1325
        'TIME' => pretty_time(ceil($i * 3600 / $config_game_speed_expedition)),
1326
      );
1327
    }
1328
1329
    return $result;
1330
  }
1331
1332
  /**
1333
   * @param array $planetResources
1334
   *
1335
   * @return array
1336
   */
1337
  // TODO - REDO to resource_id
1338
  protected function renderPlanetResources(&$planetResources) {
1339
    $result = array();
1340
1341
    $i = 0;
1342
    foreach ($planetResources as $resource_id => $resource_amount) {
1343
      $result[] = array(
1344
        'ID'        => $i++, // $resource_id,
1345
        'ON_PLANET' => $resource_amount,
1346
        'TEXT'      => pretty_number($resource_amount),
1347
        'NAME'      => classLocale::$lang['tech'][$resource_id],
1348
      );
1349
    }
1350
1351
    return $result;
1352
  }
1353
1354
  /**
1355
   * @return array
1356
   */
1357
  protected function renderAllowedPlanetTypes() {
1358
    $result = array();
1359
1360
    foreach ($this->allowed_planet_types as $possible_planet_type_id) {
1361
      $result[] = array(
1362
        'ID'         => $possible_planet_type_id,
1363
        'NAME'       => classLocale::$lang['sys_planet_type'][$possible_planet_type_id],
1364
        'NAME_SHORT' => classLocale::$lang['sys_planet_type_sh'][$possible_planet_type_id],
1365
      );
1366
    }
1367
1368
    return $result;
1369
  }
1370
1371
1372
  protected function renderFleet1TargetSelect(&$shortcut) {
1373
    global $note_priority_classes;
1374
1375
    $name = !empty($shortcut['title']) ? $shortcut['title'] : $shortcut['name'];
1376
1377
    $result = array(
1378
      'NAME'       => $name,
1379
      'GALAXY'     => $shortcut['galaxy'],
1380
      'SYSTEM'     => $shortcut['system'],
1381
      'PLANET'     => $shortcut['planet'],
1382
      'TYPE'       => $shortcut['planet_type'],
1383
      'TYPE_PRINT' => classLocale::$lang['fl_shrtcup'][$shortcut['planet_type']],
1384
    );
1385
1386
    if (isset($shortcut['priority'])) {
1387
      $result += array(
1388
        'PRIORITY'       => $shortcut['priority'],
1389
        'PRIORITY_CLASS' => $note_priority_classes[$shortcut['priority']],
1390
      );
1391
    }
1392
1393
    if (isset($shortcut['id'])) {
1394
      $result += array(
1395
        'ID' => $shortcut['id'],
1396
      );
1397
    }
1398
1399
    return $result;
1400
  }
1401
1402
  /**
1403
   * @return array
1404
   */
1405
  protected function renderFleetShortcuts() {
1406
    $result = array();
1407
1408
    // Building list of shortcuts
1409
    $query = DBStaticNote::db_note_list_select_by_owner_and_planet($this->dbOwnerRow);
1410
    while ($row = db_fetch($query)) {
1411
      $result[] = $this->renderFleet1TargetSelect($row);
1412
    }
1413
1414
    return $result;
1415
  }
1416
1417
  /**
1418
   * Building list of own planets & moons
1419
   *
1420
   * @return array
1421
   */
1422
  protected function renderOwnPlanets() {
1423
    $result = array();
1424
1425
    $colonies = DBStaticPlanet::db_planet_list_sorted($this->dbOwnerRow);
1426
    if (count($colonies) <= 1) {
1427
      return $result;
1428
    }
1429
1430
    foreach ($colonies as $row) {
1431
      if ($row['id'] == $this->dbSourcePlanetRow['id']) {
1432
        continue;
1433
      }
1434
1435
      $result[] = $this->renderFleet1TargetSelect($row);
1436
    }
1437
1438
    return $result;
1439
  }
1440
1441
  /**
1442
   * @return array
1443
   */
1444
  protected function renderACSList() {
1445
    $result = array();
1446
1447
    $query = DBStaticFleetACS::db_acs_get_list();
1448
    while ($row = db_fetch($query)) {
1449
      $members = explode(',', $row['eingeladen']);
1450
      foreach ($members as $a => $b) {
1451
        if ($b == $this->dbOwnerRow['id']) {
1452
          $result[] = $this->renderFleet1TargetSelect($row);
1453
        }
1454
      }
1455
    }
1456
1457
    return $result;
1458
  }
1459
1460
1461
  /**
1462
   * @param $template_result
1463
   */
1464
  protected function renderShipSortOptions(&$template_result) {
1465
    foreach (classLocale::$lang['player_option_fleet_ship_sort'] as $sort_id => $sort_text) {
1466
      $template_result['.']['ship_sort_list'][] = array(
1467
        'VALUE' => $sort_id,
1468
        'TEXT'  => $sort_text,
1469
      );
1470
    }
1471
    $template_result += array(
1472
      'FLEET_SHIP_SORT'         => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_SORT],
1473
      'FLEET_SHIP_SORT_INVERSE' => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_SORT_INVERSE],
1474
    );
1475
  }
1476
1477
1478
  /**
1479
   *
1480
   */
1481
  public function fleetPage0() {
1482
    global $template_result;
1483
1484
    lng_include('overview');
1485
1486
    if (empty($this->dbSourcePlanetRow)) {
1487
      message(classLocale::$lang['fl_noplanetrow'], classLocale::$lang['fl_error']);
1488
    }
1489
1490
    // TODO - redo to unitlist render/unit render
1491
    $this->renderAvailableShips($template_result, $this->dbOwnerRow, $this->dbSourcePlanetRow);
1492
1493
    $this->renderShipSortOptions($template_result);
1494
1495
    /**
1496
     * @var Player $playerOwner
1497
     */
1498
    $playerOwner = $this->getLocatedAt();
1499
1500
    $template_result += array(
1501
      'FLYING_FLEETS'      => $playerOwner->fleetsFlying(),
1502
      'MAX_FLEETS'         => $playerOwner->fleetsMax(),
1503
      'FREE_FLEETS'        => $playerOwner->fleetsMax() - $playerOwner->fleetsFlying(),
1504
      'FLYING_EXPEDITIONS' => $playerOwner->expeditionsFlying(),
1505
      'MAX_EXPEDITIONS'    => $playerOwner->expeditionsMax(),
1506
      'FREE_EXPEDITIONS'   => $playerOwner->expeditionsMax() - $playerOwner->expeditionsFlying(),
1507
      'COLONIES_CURRENT'   => $playerOwner->coloniesCurrent(),
1508
      'COLONIES_MAX'       => $playerOwner->coloniesMax(),
1509
1510
      'TYPE_NAME' => classLocale::$lang['fl_planettype'][$this->targetVector->type],
1511
1512
      'speed_factor' => flt_server_flight_speed_multiplier(),
1513
1514
      'PLANET_RESOURCES' => pretty_number($this->dbSourcePlanetRow['metal'] + $this->dbSourcePlanetRow['crystal'] + $this->dbSourcePlanetRow['deuterium']),
1515
      'PLANET_DEUTERIUM' => pretty_number($this->dbSourcePlanetRow['deuterium']),
1516
1517
      'PLAYER_OPTION_FLEET_SHIP_SELECT_OLD'       => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_SELECT_OLD],
1518
      'PLAYER_OPTION_FLEET_SHIP_HIDE_SPEED'       => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_HIDE_SPEED],
1519
      'PLAYER_OPTION_FLEET_SHIP_HIDE_CAPACITY'    => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_HIDE_CAPACITY],
1520
      'PLAYER_OPTION_FLEET_SHIP_HIDE_CONSUMPTION' => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_HIDE_CONSUMPTION],
1521
    );
1522
1523
    $template = gettemplate('fleet0', true);
1524
    $template->assign_recursive($template_result);
1525
    display($template, classLocale::$lang['fl_title']);
1526
  }
1527
1528
  /**
1529
   *
1530
   */
1531
  public function fleetPage1() {
1532
    global $template_result;
1533
1534
    $template_result['.']['fleets'][] = $this->renderFleet(SN_TIME_NOW);
1535
    $template_result['.']['possible_planet_type_id'] = $this->renderAllowedPlanetTypes();
1536
    $template_result['.']['colonies'] = $this->renderOwnPlanets();
1537
    $template_result['.']['shortcut'] = $this->renderFleetShortcuts();
1538
    $template_result['.']['acss'] = $this->renderACSList();
1539
1540
    $template_result += array(
1541
      'speed_factor' => flt_server_flight_speed_multiplier(),
1542
1543
      'fleet_speed'    => $this->fleetSpeed(),
1544
      'fleet_capacity' => $this->shipsGetCapacity(),
1545
1546
      'PLANET_DEUTERIUM' => pretty_number($this->dbSourcePlanetRow['deuterium']),
1547
1548
      'PAGE_HINT' => classLocale::$lang['fl_page1_hint'],
1549
    );
1550
1551
    $template = gettemplate('fleet1', true);
1552
    $template->assign_recursive($template_result);
1553
    display($template, classLocale::$lang['fl_title']);
1554
  }
1555
1556
  public function fleetSpeed() {
1557
    $maxSpeed = array();
1558
    foreach ($this->shipsIterator() as $ship_id => $unit) {
1559
      if ($unit->count > 0 && !empty(static::$snGroupFleetAndMissiles[$ship_id])) {
1560
        $single_ship_data = get_ship_data($ship_id, $this->dbOwnerRow);
1561
        $maxSpeed[$ship_id] = $single_ship_data['speed'];
1562
      }
1563
    }
1564
1565
    return empty($maxSpeed) ? 0 : min($maxSpeed);
1566
  }
1567
1568
  /**
1569
   * @param array $planetResourcesWithoutConsumption
1570
   */
1571
  public function fleetPage2Prepare($planetResourcesWithoutConsumption) {
0 ignored issues
show
Unused Code introduced by
The parameter $planetResourcesWithoutConsumption is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1572
    $this->travelData = $this->flt_travel_data($this->oldSpeedInTens);
1573
1574
//    /**
1575
//     * @var array $allowed_missions
1576
//     */
1577
//    public $allowed_missions = array();
1578
//    /**
1579
//     * @var array $exists_missions
1580
//     */
1581
//    public $exists_missions = array();
1582
//    public $allowed_planet_types = array(
1583
//      // PT_NONE => PT_NONE,
1584
//      PT_PLANET => PT_PLANET,
1585
//      PT_MOON   => PT_MOON,
1586
//      PT_DEBRIS => PT_DEBRIS
1587
//    );
1588
1589
//    $this->exists_missions = array(
1590
////      MT_EXPLORE => MT_EXPLORE,
1591
////      MT_MISSILE => MT_MISSILE,
1592
//      MT_COLONIZE => MT_COLONIZE,
1593
//    );  // TODO
1594
    $this->allowed_missions = array();
1595
1596
    if ($this->mission_type != MT_NONE && empty($this->exists_missions[$this->mission_type])) {
1597
      throw new ExceptionFleetInvalid(FLIGHT_MISSION_UNKNOWN, FLIGHT_MISSION_UNKNOWN);
1598
    }
1599
1600
    $this->validator->validateGlobals();
1601
1602
    $validateResult = array();
1603
    foreach ($this->exists_missions as $missionType => $missionData) {
1604
//print('qwe');
1605
      $mission = \Mission\MissionFactory::build($missionType, $this);
1606
//print('wer');
1607
      $validateResult[$missionType] = $mission->validate();
1608
      if (FLIGHT_ALLOWED == $validateResult[$missionType]) {
1609
        $this->allowed_missions[$missionType] = $mission;
1610
      } else {
1611
        if($missionType == $this->mission_type) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
1612
        }
1613
        unset($this->allowed_missions[$missionType]);
1614
      }
1615
    }
1616
1617
    if(empty($this->allowed_missions)) {
1618
      if($this->mission_type != MT_NONE && isset($validateResult[$this->mission_type])) {
1619
        throw new ExceptionFleetInvalid($validateResult[$this->mission_type], $validateResult[$this->mission_type]);
1620
      } else {
1621
        throw new ExceptionFleetInvalid(FLIGHT_MISSION_IMPOSSIBLE, FLIGHT_MISSION_IMPOSSIBLE);
1622
      }
1623
    }
1624
1625
//    $this->validator->validate();
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% 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...
1626
  }
1627
1628
  /**
1629
   * @param array $planetResourcesWithoutConsumption
1630
   */
1631
  public function fleetPage3Prepare($planetResourcesWithoutConsumption) {
0 ignored issues
show
Unused Code introduced by
The parameter $planetResourcesWithoutConsumption is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1632
    $this->travelData = $this->flt_travel_data($this->oldSpeedInTens);
1633
1634
    if (empty($this->exists_missions[$this->mission_type])) {
1635
      throw new ExceptionFleetInvalid(FLIGHT_MISSION_UNKNOWN, FLIGHT_MISSION_UNKNOWN);
1636
    }
1637
1638
    $this->validator->validateGlobals();
1639
1640
    $mission = \Mission\MissionFactory::build($this->mission_type, $this);
1641
    $result = $mission->validate();
1642
    if (FLIGHT_ALLOWED != $result) {
1643
      throw new ExceptionFleetInvalid($result, $result);
1644
    }
1645
1646
  }
1647
1648
  /**
1649
   *
1650
   */
1651
  public function fleetPage2() {
1652
    global $template_result;
1653
1654
    $planetResourcesTotal = DBStaticPlanet::getResources($this->dbOwnerRow, $this->dbSourcePlanetRow);
1655
    $planetResourcesWithoutConsumption = $this->resourcesSubstractConsumption($planetResourcesTotal);
1656
1657
    try {
1658
      $this->fleetPage2Prepare($planetResourcesWithoutConsumption);
1659
    } catch (Exception $e) {
1660
      // TODO - MESSAGE BOX
1661 View Code Duplication
      if ($e instanceof ExceptionFleetInvalid) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1662
        sn_db_transaction_rollback();
1663
        pdie(classLocale::$lang['fl_attack_error'][$e->getCode()]);
1664
      } else {
1665
        throw $e;
1666
      }
1667
    }
1668
1669
    // Flight allowed here
1670
    pdump('FLIGHT_ALLOWED', FLIGHT_ALLOWED);
1671
//    pdump('// TODO - Сделать flletvalidator DI - внутре контейнер для методов, а методы - анонимные функции, вызывающие другие методы же', FLIGHT_ALLOWED);
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% 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...
1672
1673
    $template_result['.']['missions'] = $this->renderAllowedMissions();
1674
1675
    $template_result['.']['fleets'][] = $this->renderFleet(SN_TIME_NOW);
1676
1677
    $max_duration =
1678
      $this->_mission_type == MT_EXPLORE
1679
        ? get_player_max_expedition_duration($this->dbOwnerRow)
1680
        : (isset($this->allowed_missions[MT_HOLD]) ? 12 : 0);
1681
    $template_result['.']['duration'] = $this->renderDuration($max_duration);
1682
1683
    $this->captainGet();
1684
    $template_result += $this->renderCaptain();
1685
1686
    $template_result['.']['resources'] = $this->renderPlanetResources($planetResourcesWithoutConsumption);
1687
1688
    $template_result += array(
1689
      'planet_metal'     => $planetResourcesWithoutConsumption[RES_METAL],
1690
      'planet_crystal'   => $planetResourcesWithoutConsumption[RES_CRYSTAL],
1691
      'planet_deuterium' => $planetResourcesWithoutConsumption[RES_DEUTERIUM],
1692
1693
      'fleet_capacity' => $this->shipsGetCapacity() - $this->travelData['consumption'],
1694
      'speed'          => $this->oldSpeedInTens,
1695
      'fleet_group'    => $this->_group_id,
1696
1697
      'MAX_DURATION'          => $max_duration,
1698
1699
      // TODO - remove
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% 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...
1700
//      'IS_TRANSPORT_MISSIONS' => !empty($this->allowed_missions[$this->_mission_type]['transport']),
1701
      'IS_TRANSPORT_MISSIONS' => true,
1702
1703
      'PLAYER_COLONIES_CURRENT' => get_player_current_colonies($this->dbOwnerRow),
1704
      'PLAYER_COLONIES_MAX'     => get_player_max_colonies($this->dbOwnerRow),
1705
    );
1706
1707
    $template = gettemplate('fleet2', true);
1708
    $template->assign_recursive($template_result);
1709
    display($template, classLocale::$lang['fl_title']);
1710
  }
1711
1712
  /**
1713
   *
1714
   */
1715
  public function fleetPage3() {
1716
    global $template_result;
1717
1718
    $this->isRealFlight = true;
1719
1720
    sn_db_transaction_start();
1721
1722
    DBStaticUser::db_user_lock_with_target_owner_and_acs($this->dbOwnerRow, $this->dbTargetRow);
1723
1724
    // Checking for group
1725
    $this->groupCheck();
1726
1727
    $this->dbOwnerRow = DBStaticUser::db_user_by_id($this->dbOwnerRow['id'], true);
0 ignored issues
show
Documentation Bug introduced by
It seems like \DBStaticUser::db_user_b...dbOwnerRow['id'], true) can also be of type false. However, the property $dbOwnerRow is declared as type array. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
1728
    $this->dbSourcePlanetRow = DBStaticPlanet::db_planet_by_id($this->dbSourcePlanetRow['id'], true);
0 ignored issues
show
Documentation Bug introduced by
It seems like \DBStaticPlanet::db_plan...ePlanetRow['id'], true) can be null. However, the property $dbSourcePlanetRow is declared as array. Maybe change the type of the property to array|null or add a type check?

Our type inference engine has found an assignment of a scalar value (like a string, an integer or null) to a property which is an array.

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

To type hint that a parameter can be either an array or null, you can set a type hint of array and a default value of null. The PHP interpreter will then accept both an array or null for that parameter.

function aContainsB(array $needle = null, array  $haystack) {
    if (!$needle) {
        return false;
    }

    return array_intersect($haystack, $needle) == $haystack;
}

The function can be called with either null or an array for the parameter $needle but will only accept an array as $haystack.

Loading history...
1729
    if (!empty($this->dbTargetRow['id'])) {
1730
      $this->dbTargetRow = DBStaticPlanet::db_planet_by_id($this->dbTargetRow['id'], true);
0 ignored issues
show
Documentation Bug introduced by
It seems like \DBStaticPlanet::db_plan...bTargetRow['id'], true) can be null. However, the property $dbTargetRow is declared as array. Maybe change the type of the property to array|null or add a type check?

Our type inference engine has found an assignment of a scalar value (like a string, an integer or null) to a property which is an array.

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

To type hint that a parameter can be either an array or null, you can set a type hint of array and a default value of null. The PHP interpreter will then accept both an array or null for that parameter.

function aContainsB(array $needle = null, array  $haystack) {
    if (!$needle) {
        return false;
    }

    return array_intersect($haystack, $needle) == $haystack;
}

The function can be called with either null or an array for the parameter $needle but will only accept an array as $haystack.

Loading history...
1731
    }
1732
    // TODO - deprecated! Filled in populateTargetPlanetAndOwner
1733 View Code Duplication
    if (!empty($this->dbTargetRow['id_owner'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1734
      $this->dbTargetOwnerRow = DBStaticUser::db_user_by_id($this->dbTargetRow['id_owner'], true);
0 ignored issues
show
Documentation Bug introduced by
It seems like \DBStaticUser::db_user_b...tRow['id_owner'], true) can also be of type false. However, the property $dbTargetOwnerRow is declared as type array. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
1735
    }
1736
1737
    $this->resource_list = array(
1738
      RES_METAL     => max(0, floor(sys_get_param_float('resource0'))),
1739
      RES_CRYSTAL   => max(0, floor(sys_get_param_float('resource1'))),
1740
      RES_DEUTERIUM => max(0, floor(sys_get_param_float('resource2'))),
1741
    );
1742
1743
    $this->captainGet();
1744
1745
    $this->travelData = $this->flt_travel_data($this->oldSpeedInTens);
1746
1747
    $planetResourcesTotal = DBStaticPlanet::getResources($this->dbOwnerRow, $this->dbSourcePlanetRow);
0 ignored issues
show
Security Bug introduced by
It seems like $this->dbOwnerRow can also be of type false; however, DBStaticPlanet::getResources() does only seem to accept array, did you maybe forget to handle an error condition?
Loading history...
Bug introduced by
It seems like $this->dbSourcePlanetRow can also be of type null; however, DBStaticPlanet::getResources() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
1748
    $planetResourcesWithoutConsumption = $this->resourcesSubstractConsumption($planetResourcesTotal);
1749
1750
    try {
1751
      $this->fleetPage3Prepare($planetResourcesWithoutConsumption);
1752
    } catch (Exception $e) {
1753
      // TODO - MESSAGE BOX
1754 View Code Duplication
      if ($e instanceof ExceptionFleetInvalid) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1755
        sn_db_transaction_rollback();
1756
        pdie(classLocale::$lang['fl_attack_error'][$e->getCode()]);
1757
      } else {
1758
        throw $e;
1759
      }
1760
    }
1761
1762
//    try {
0 ignored issues
show
Unused Code Comprehensibility introduced by
53% 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...
1763
//      $validator = new FleetValidator($this);
1764
//      $validator->validate();
1765
//    } catch (Exception $e) {
1766
//      // TODO - MESSAGE BOX
1767
//      if($e instanceof ExceptionFleetInvalid) {
1768
//        sn_db_transaction_rollback();
1769
//        pdie(classLocale::$lang['fl_attack_error'][$e->getCode()]);
1770
//      } else {
1771
//        throw $e;
1772
//      }
1773
//    }
1774
1775
    // TODO - check if mission is not 0 and in ALLOWED_MISSIONS
1776
1777
    // Flight allowed here
1778
    pdump('FLIGHT_ALLOWED', FLIGHT_ALLOWED);
1779
//    pdump('// TODO - Сделать flletvalidator DI - внутре контейнер для методов, а методы - анонимные функции, вызывающие другие методы же', FLIGHT_ALLOWED);
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% 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...
1780
1781
1782
    $timeMissionJob = 0;
1783
    // TODO check for empty mission AKA mission allowed
1784
    /*
1785
        if ($this->_mission_type == MT_ACS && $aks) {
1786
          $acsTimeToArrive = $aks['ankunft'] - SN_TIME_NOW;
1787
          if ($acsTimeToArrive < $this->travelData['duration']) {
1788
            message(classLocale::$lang['fl_aks_too_slow'] . 'Fleet arrival: ' . date(FMT_DATE_TIME, SN_TIME_NOW + $this->travelData['duration']) . " AKS arrival: " . date(FMT_DATE_TIME, $aks['ankunft']), classLocale::$lang['fl_error']);
1789
          }
1790
          // Set time to travel to ACS' TTT
1791
          $this->travelData['duration'] = $acsTimeToArrive;
1792
    */
1793
    if ($this->_mission_type != MT_ACS) {
1794
      if ($this->_mission_type == MT_EXPLORE || $this->_mission_type == MT_HOLD) {
1795
        $max_duration = $this->_mission_type == MT_EXPLORE ? get_player_max_expedition_duration($this->dbOwnerRow) : ($this->_mission_type == MT_HOLD ? 12 : 0);
1796
        if ($max_duration) {
1797
          $mission_time_in_hours = sys_get_param_id('missiontime');
1798
          if ($mission_time_in_hours > $max_duration || $mission_time_in_hours < 1) {
1799
            classSupernova::$debug->warning('Supplying wrong mission time', 'Hack attempt', 302, array('base_dump' => true));
0 ignored issues
show
Documentation introduced by
array('base_dump' => true) is of type array<string,boolean,{"base_dump":"boolean"}>, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1800
            die();
1801
          }
1802
          $timeMissionJob = ceil($mission_time_in_hours * 3600 / ($this->_mission_type == MT_EXPLORE && classSupernova::$config->game_speed_expedition ? classSupernova::$config->game_speed_expedition : 1));
1803
        }
1804
      }
1805
    }
1806
1807
    //
1808
    //
1809
    //
1810
    //
1811
    //
1812
    //
1813
    //
1814
    //
1815
    // ---------------- END OF CHECKS ------------------------------------------------------
1816
1817
    $this->set_times($this->travelData['duration'], $timeMissionJob);
1818
    $this->dbInsert();
1819
    $this->unitList->dbSubstractUnitsFromPlanet($this->dbOwnerRow, $this->dbSourcePlanetRow['id']);
1820
1821
    DBStaticPlanet::db_planet_update_set_by_id($this->dbSourcePlanetRow['id'],
1822
      "`metal` = `metal` - {$this->resource_list[RES_METAL]},
1823
      `crystal` = `crystal` - {$this->resource_list[RES_CRYSTAL]},
1824
      `deuterium` = `deuterium` - {$this->resource_list[RES_DEUTERIUM]} - {$this->travelData['consumption']}"
1825
    );
1826
1827
    if (!empty($this->captain['unit_id'])) {
1828
      DBStaticUnit::db_unit_set_by_id($this->captain['unit_id'], "`unit_location_type` = " . LOC_FLEET . ", `unit_location_id` = {$this->_dbId}");
1829
    }
1830
1831
//    return $this->fleet->acs['ankunft'] - $this->fleet->time_launch >= $this->fleet->travelData['duration'];
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% 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...
1832
//
1833
//    // Set time to travel to ACS' TTT
1834
//    $this->fleet->travelData['duration'] = $acsTimeToArrive;
1835
1836
1837
    $template_result['.']['fleets'][] = $this->renderFleet(SN_TIME_NOW, $timeMissionJob);
1838
1839
    $template_result += array(
1840
      'mission'         => classLocale::$lang['type_mission'][$this->_mission_type] . ($this->_mission_type == MT_EXPLORE || $this->_mission_type == MT_HOLD ? ' ' . pretty_time($timeMissionJob) : ''),
1841
      'dist'            => pretty_number($this->travelData['distance']),
1842
      'speed'           => pretty_number($this->travelData['fleet_speed']),
1843
      'deute_need'      => pretty_number($this->travelData['consumption']),
1844
      'from'            => "{$this->dbSourcePlanetRow['galaxy']}:{$this->dbSourcePlanetRow['system']}:{$this->dbSourcePlanetRow['planet']}",
1845
      'time_go'         => date(FMT_DATE_TIME, $this->_time_arrive_to_target),
1846
      'time_go_local'   => date(FMT_DATE_TIME, $this->_time_arrive_to_target + SN_CLIENT_TIME_DIFF),
1847
      'time_back'       => date(FMT_DATE_TIME, $this->_time_return_to_source),
1848
      'time_back_local' => date(FMT_DATE_TIME, $this->_time_return_to_source + SN_CLIENT_TIME_DIFF),
1849
    );
1850
1851
    $this->dbSourcePlanetRow = DBStaticPlanet::db_planet_by_id($this->dbSourcePlanetRow['id']);
0 ignored issues
show
Documentation Bug introduced by
It seems like \DBStaticPlanet::db_plan...bSourcePlanetRow['id']) can be null. However, the property $dbSourcePlanetRow is declared as array. Maybe change the type of the property to array|null or add a type check?

Our type inference engine has found an assignment of a scalar value (like a string, an integer or null) to a property which is an array.

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

To type hint that a parameter can be either an array or null, you can set a type hint of array and a default value of null. The PHP interpreter will then accept both an array or null for that parameter.

function aContainsB(array $needle = null, array  $haystack) {
    if (!$needle) {
        return false;
    }

    return array_intersect($haystack, $needle) == $haystack;
}

The function can be called with either null or an array for the parameter $needle but will only accept an array as $haystack.

Loading history...
1852
1853
    pdie('Stop for debug');
1854
1855
    sn_db_transaction_commit();
1856
1857
    $template = gettemplate('fleet3', true);
1858
    $template->assign_recursive($template_result);
1859
    display($template, classLocale::$lang['fl_title']);
1860
  }
1861
1862
  protected function groupCheck() {
1863
    if (empty($this->_group_id)) {
1864
      return;
1865
    }
1866
1867
    // ACS attack must exist (if acs fleet has arrived this will also return false (2 checks in 1!!!)
1868
    $this->acs = DBStaticFleetACS::db_acs_get_by_group_id($this->_group_id);
1869
    if (empty($this->acs)) {
1870
      $this->_group_id = 0;
1871
    } else {
1872
      $this->targetVector->convertToVector($this->acs);
1873
    }
1874
  }
1875
1876
  /**
1877
   * @param array $planetResources
1878
   *
1879
   * @return array
1880
   */
1881
  protected function resourcesSubstractConsumption($planetResources) {
1882
    !isset($planetResources[RES_DEUTERIUM]) ? $planetResources[RES_DEUTERIUM] = 0 : false;
1883
1884
    if ($this->travelData['consumption'] >= 0) {
1885
      $planetResources[RES_DEUTERIUM] -= ceil($this->travelData['consumption']);
1886
    }
1887
1888
    return $planetResources;
1889
  }
1890
1891
  /**
1892
   */
1893
  public function captainGet() {
1894
    $this->captain = array();
1895
1896
    /**
1897
     * @var unit_captain $moduleCaptain
1898
     */
1899
    if (sn_module::isModuleActive('unit_captain')) {
1900
      $moduleCaptain = sn_module::getModule('unit_captain');
1901
      $this->captain = $moduleCaptain->unit_captain_get($this->dbSourcePlanetRow['id']);
0 ignored issues
show
Bug introduced by
The method unit_captain_get() does not seem to exist on object<sn_module>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1902
    }
1903
  }
1904
1905
  /**
1906
   * @return array
1907
   */
1908
  protected function renderCaptain() {
1909
    $result = array();
1910
1911
    if (!empty($this->captain['unit_id']) && $this->captain['unit_location_type'] == LOC_PLANET) {
1912
      $result = array(
1913
        'CAPTAIN_ID'     => $this->captain['unit_id'],
1914
        'CAPTAIN_LEVEL'  => $this->captain['captain_level'],
1915
        'CAPTAIN_SHIELD' => $this->captain['captain_shield'],
1916
        'CAPTAIN_ARMOR'  => $this->captain['captain_armor'],
1917
        'CAPTAIN_ATTACK' => $this->captain['captain_attack'],
1918
      );
1919
    }
1920
1921
    return $result;
1922
  }
1923
1924
}
1925
1926
if (empty(Fleet::$snGroupFleet)) {
1927
  Fleet::$snGroupFleet = sn_get_groups('fleet');
1928
  Fleet::$snGroupFleetAndMissiles = sn_get_groups(array('fleet', GROUP_STR_MISSILES));
1929
  Fleet::$snGroupRecyclers = sn_get_groups('flt_recyclers');
1930
}
1931