Completed
Push — work-fleets ( 33857b...22a48f )
by SuperNova.WS
05:55
created

Fleet::fleetPage2Prepare()   C

Complexity

Conditions 9
Paths 13

Size

Total Lines 58
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 90

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 9
eloc 20
c 3
b 0
f 0
nc 13
nop 1
dl 0
loc 58
rs 6.9928
ccs 0
cts 34
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 static $_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->allowed_missions = $this->exists_missions;
0 ignored issues
show
Unused Code Comprehensibility introduced by
46% 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...
333
    if (empty(static::$snGroupFleet)) {
334
      static::$snGroupFleet = sn_get_groups('fleet');
335
      static::$snGroupFleetAndMissiles = sn_get_groups(array('fleet', GROUP_STR_MISSILES));
336
      static::$snGroupRecyclers = sn_get_groups('flt_recyclers');
337
    }
338
    $this->validator = new FleetValidator($this);
339
  }
340
341
  /**
342
   * @param array $template_result
343
   * @param array $playerRow
344
   * @param array $planetRow
345
   */
346
  // TODO - redo to unit/unitlist renderer
347
  public function renderAvailableShips(&$template_result, $playerRow, $planetRow) {
348
    $record_index = 0;
349
    $ship_list = array();
350
    foreach (Fleet::$snGroupFleet as $n => $unit_id) {
351
      $unit_level = mrc_get_level($playerRow, $planetRow, $unit_id, false, true);
352
      if ($unit_level <= 0) {
353
        continue;
354
      }
355
      $ship_data = get_ship_data($unit_id, $playerRow);
356
      $ship_list[$unit_id] = array(
357
        '__INDEX'          => $record_index++,
358
        'ID'               => $unit_id,
359
        'NAME'             => classLocale::$lang['tech'][$unit_id],
360
        'AMOUNT'           => $unit_level,
361
        'AMOUNT_TEXT'      => pretty_number($unit_level),
362
        'CONSUMPTION'      => $ship_data['consumption'],
363
        'CONSUMPTION_TEXT' => pretty_number($ship_data['consumption']),
364
        'SPEED'            => $ship_data['speed'],
365
        'SPEED_TEXT'       => pretty_number($ship_data['speed']),
366
        'CAPACITY'         => $ship_data['capacity'],
367
        'CAPACITY_TEXT'    => pretty_number($ship_data['capacity']),
368
      );
369
    }
370
371
    sortUnitRenderedList($ship_list, classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_SORT], classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_SORT_INVERSE]);
372
373
    foreach ($ship_list as $ship_data) {
374
      $template_result['.']['ships'][] = $ship_data;
375
    }
376
  }
377
378
  public function isEmpty() {
379
    return !$this->resourcesGetTotal() && !$this->shipsGetTotal();
380
  }
381
382
//  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...
383
//    return $this->playerOwnerId;
384
//  }
385
386
  /**
387
   * Initializes Fleet from user params and posts it to DB
388
   */
389
  public function dbInsert() {
390
    // WARNING! MISSION TIMES MUST BE SET WITH set_times() method!
391
    // TODO - more checks!
392
    if (empty($this->_time_launch)) {
393
      die('Fleet time not set!');
394
    }
395
396
    parent::dbInsert();
397
  }
398
399
400
  /* FLEET DB ACCESS =================================================================================================*/
401
402
  /**
403
   * LOCK - Lock all records which can be used with mission
404
   *
405
   * @param $mission_data
406
   *
407
   * @return array|bool|mysqli_result|null
408
   */
409
  public function dbLockFlying(&$mission_data) {
410
    // Тупо лочим всех юзеров, чьи флоты летят или улетают с координат отбытия/прибытия $fleet_row
411
    // Что бы делать это умно - надо учитывать fleet__mess во $fleet_row и в таблице fleets
412
413
    $fleet_id_safe = idval($this->_dbId);
414
415
    return doquery(
416
    // Блокировка самого флота
417
      "SELECT 1 FROM {{fleets}} AS f " .
418
419
      // Блокировка всех юнитов, принадлежащих этому флоту
420
      "LEFT JOIN {{unit}} as unit ON unit.unit_location_type = " . static::$locationType . " AND unit.unit_location_id = f.fleet_id " .
421
422
      // Блокировка всех прилетающих и улетающих флотов, если нужно
423
      // TODO - lock fleets by COORDINATES
424
      ($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 " : '') .
425
      // Блокировка всех юнитов, принадлежащих прилетающим и улетающим флотам - ufd = unit_fleet_destination
426
      ($mission_data['dst_fleets'] ? "LEFT JOIN {{unit}} AS ufd ON ufd.unit_location_type = " . static::$locationType . " AND ufd.unit_location_id = fd.fleet_id " : '') .
427
428
      ($mission_data['dst_user'] || $mission_data['dst_planet'] ? "LEFT JOIN {{users}} AS ud ON ud.id = f.fleet_target_owner " : '') .
429
      // Блокировка всех юнитов, принадлежащих владельцу планеты-цели
430
      ($mission_data['dst_user'] || $mission_data['dst_planet'] ? "LEFT JOIN {{unit}} AS unit_player_dest ON unit_player_dest.unit_player_id = ud.id " : '') .
431
      // Блокировка планеты-цели
432
      ($mission_data['dst_planet'] ? "LEFT JOIN {{planets}} AS pd ON pd.id = f.fleet_end_planet_id " : '') .
433
      // Блокировка всех юнитов, принадлежащих планете-цели - НЕ НУЖНО. Уже залочили ранее, как принадлежащие игроку-цели
434
//      ($mission_data['dst_planet'] ? "LEFT JOIN {{unit}} AS upd ON upd.unit_location_type = " . LOC_PLANET . " AND upd.unit_location_id = pd.id " : '') .
435
436
437
      ($mission_data['src_user'] || $mission_data['src_planet'] ? "LEFT JOIN {{users}} AS us ON us.id = f.fleet_owner " : '') .
438
      // Блокировка всех юнитов, принадлежащих владельцу флота
439
      ($mission_data['src_user'] || $mission_data['src_planet'] ? "LEFT JOIN {{unit}} AS unit_player_src ON unit_player_src.unit_player_id = us.id " : '') .
440
      // Блокировка планеты отправления
441
      ($mission_data['src_planet'] ? "LEFT JOIN {{planets}} AS ps ON ps.id = f.fleet_start_planet_id " : '') .
442
      // Блокировка всех юнитов, принадлежащих планете с которой юниты были отправлены - НЕ НУЖНО. Уже залочили ранее, как принадлежащие владельцу флота
443
//      ($mission_data['src_planet'] ? "LEFT JOIN {{unit}} AS ups ON ups.unit_location_type = " . LOC_PLANET . " AND ups.unit_location_id = ps.id " : '') .
444
445
      "WHERE f.fleet_id = {$fleet_id_safe} GROUP BY 1 FOR UPDATE"
446
    );
447
  }
448
449
  /**
450
   * Lock all fields that belongs to operation
451
   *
452
   * @param $dbId
453
   */
454
  // TODO = make static
455
  public function dbGetLockById($dbId) {
456
    doquery(
457
    // Блокировка самого флота
458
      "SELECT 1 FROM {{fleets}} AS FLEET0 " .
459
      // Lock fleet owner
460
      "LEFT JOIN {{users}} as USER0 on USER0.id = FLEET0.fleet_owner " .
461
      // Блокировка всех юнитов, принадлежащих этому флоту
462
      "LEFT JOIN {{unit}} as UNIT0 ON UNIT0.unit_location_type = " . LOC_FLEET . " AND UNIT0.unit_location_id = FLEET0.fleet_id " .
463
464
      // Без предварительной выборки неизвестно - куда летит этот флот.
465
      // Поэтому надо выбирать флоты, чьи координаты прибытия ИЛИ отбытия совпадают с координатами прибытия ИЛИ отбытия текущего флота.
466
      // Получаем матрицу 2х2 - т.е. 4 подзапроса.
467
      // При блокировке всегда нужно выбирать И лпанету, И луну - поскольку при бое на орбите луны обломки падают на орбиту планеты.
468
      // Поэтому тип планеты не указывается
469
470
      // Lock fleet heading to destination planet. Only if FLEET0.fleet_mess == 0
471
      "LEFT JOIN {{fleets}} AS FLEET1 ON
472
        FLEET1.fleet_mess = 0 AND FLEET0.fleet_mess = 0 AND
473
        FLEET1.fleet_end_galaxy = FLEET0.fleet_end_galaxy AND
474
        FLEET1.fleet_end_system = FLEET0.fleet_end_system AND
475
        FLEET1.fleet_end_planet = FLEET0.fleet_end_planet
476
      " .
477
      // Блокировка всех юнитов, принадлежащих этим флотам
478
      "LEFT JOIN {{unit}} as UNIT1 ON UNIT1.unit_location_type = " . LOC_FLEET . " AND UNIT1.unit_location_id = FLEET1.fleet_id " .
479
      // Lock fleet owner
480
      "LEFT JOIN {{users}} as USER1 on USER1.id = FLEET1.fleet_owner " .
481
482
      "LEFT JOIN {{fleets}} AS FLEET2 ON
483
        FLEET2.fleet_mess = 1   AND FLEET0.fleet_mess = 0 AND
484
        FLEET2.fleet_start_galaxy = FLEET0.fleet_end_galaxy AND
485
        FLEET2.fleet_start_system = FLEET0.fleet_end_system AND
486
        FLEET2.fleet_start_planet = FLEET0.fleet_end_planet
487
      " .
488
      // Блокировка всех юнитов, принадлежащих этим флотам
489
      "LEFT JOIN {{unit}} as UNIT2 ON
490
        UNIT2.unit_location_type = " . LOC_FLEET . " AND
491
        UNIT2.unit_location_id = FLEET2.fleet_id
492
      " .
493
      // Lock fleet owner
494
      "LEFT JOIN {{users}} as USER2 on
495
        USER2.id = FLEET2.fleet_owner
496
      " .
497
498
      // Lock fleet heading to source planet. Only if FLEET0.fleet_mess == 1
499
      "LEFT JOIN {{fleets}} AS FLEET3 ON
500
        FLEET3.fleet_mess = 0 AND FLEET0.fleet_mess = 1 AND
501
        FLEET3.fleet_end_galaxy = FLEET0.fleet_start_galaxy AND
502
        FLEET3.fleet_end_system = FLEET0.fleet_start_system AND
503
        FLEET3.fleet_end_planet = FLEET0.fleet_start_planet
504
      " .
505
      // Блокировка всех юнитов, принадлежащих этим флотам
506
      "LEFT JOIN {{unit}} as UNIT3 ON
507
        UNIT3.unit_location_type = " . LOC_FLEET . " AND
508
        UNIT3.unit_location_id = FLEET3.fleet_id
509
      " .
510
      // Lock fleet owner
511
      "LEFT JOIN {{users}} as USER3 on USER3.id = FLEET3.fleet_owner " .
512
513
      "LEFT JOIN {{fleets}} AS FLEET4 ON
514
        FLEET4.fleet_mess = 1   AND FLEET0.fleet_mess = 1 AND
515
        FLEET4.fleet_start_galaxy = FLEET0.fleet_start_galaxy AND
516
        FLEET4.fleet_start_system = FLEET0.fleet_start_system AND
517
        FLEET4.fleet_start_planet = FLEET0.fleet_start_planet
518
      " .
519
      // Блокировка всех юнитов, принадлежащих этим флотам
520
      "LEFT JOIN {{unit}} as UNIT4 ON
521
        UNIT4.unit_location_type = " . LOC_FLEET . " AND
522
        UNIT4.unit_location_id = FLEET4.fleet_id
523
      " .
524
      // Lock fleet owner
525
      "LEFT JOIN {{users}} as USER4 on
526
        USER4.id = FLEET4.fleet_owner
527
      " .
528
529
530
      // Locking start planet
531
      "LEFT JOIN {{planets}} AS PLANETS5 ON
532
        FLEET0.fleet_mess = 1 AND
533
        PLANETS5.galaxy = FLEET0.fleet_start_galaxy AND
534
        PLANETS5.system = FLEET0.fleet_start_system AND
535
        PLANETS5.planet = FLEET0.fleet_start_planet
536
      " .
537
      // Lock planet owner
538
      "LEFT JOIN {{users}} as USER5 on
539
        USER5.id = PLANETS5.id_owner
540
      " .
541
      // Блокировка всех юнитов, принадлежащих этой планете
542
      "LEFT JOIN {{unit}} as UNIT5 ON
543
        UNIT5.unit_location_type = " . LOC_PLANET . " AND
544
        UNIT5.unit_location_id = PLANETS5.id
545
      " .
546
547
548
      // Locking destination planet
549
      "LEFT JOIN {{planets}} AS PLANETS6 ON
550
        FLEET0.fleet_mess = 0 AND
551
        PLANETS6.galaxy = FLEET0.fleet_end_galaxy AND
552
        PLANETS6.system = FLEET0.fleet_end_system AND
553
        PLANETS6.planet = FLEET0.fleet_end_planet
554
      " .
555
      // Lock planet owner
556
      "LEFT JOIN {{users}} as USER6 on
557
        USER6.id = PLANETS6.id_owner
558
      " .
559
      // Блокировка всех юнитов, принадлежащих этой планете
560
      "LEFT JOIN {{unit}} as UNIT6 ON
561
        UNIT6.unit_location_type = " . LOC_PLANET . " AND
562
        UNIT6.unit_location_id = PLANETS6.id
563
      " .
564
      "WHERE FLEET0.fleet_id = {$dbId} GROUP BY 1 FOR UPDATE"
565
    );
566
  }
567
568
569
  public function dbRowParse($db_row) {
570
    parent::dbRowParse($db_row); // TODO: Change the autogenerated stub
571
    $player = new Player();
572
    $player->dbLoad($db_row['fleet_owner']);
573
    $this->setLocatedAt($player);
574
  }
575
576
  /* FLEET HELPERS =====================================================================================================*/
577
  /**
578
   * Forcibly returns fleet before time outs
579
   */
580
  public function commandReturn() {
581
    $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;
582
583
    $this->markReturned();
584
585
    // Считаем, что флот уже долетел TODO
586
    $this->time_arrive_to_target = SN_TIME_NOW;
587
    // Убираем флот из группы
588
    $this->group_id = 0;
589
    // Отменяем работу в точке назначения
590
    $this->time_mission_job_complete = 0;
591
    // TODO - правильно вычслять время возвращения - по проделанному пути, а не по старому времени возвращения
592
    $this->time_return_to_source = $ReturnFlyingTime;
593
594
    // Записываем изменения в БД
595
    $this->dbSave();
596
597
    if ($this->_group_id) {
598
      // TODO: Make here to delete only one AKS - by adding aks_fleet_count to AKS table
599
      DBStaticFleetACS::db_fleet_aks_purge();
600
    }
601
  }
602
603
604
  /**
605
   * @return array
606
   */
607
  public function target_coordinates_without_type() {
608
    return array(
609
      'galaxy' => $this->_fleet_end_galaxy,
610
      'system' => $this->_fleet_end_system,
611
      'planet' => $this->_fleet_end_planet,
612
    );
613
  }
614
615
  /**
616
   * @return array
617
   */
618
  public function target_coordinates_typed() {
619
    return array(
620
      'galaxy' => $this->_fleet_end_galaxy,
621
      'system' => $this->_fleet_end_system,
622
      'planet' => $this->_fleet_end_planet,
623
      'type'   => $this->_fleet_end_type,
624
    );
625
  }
626
627
  /**
628
   * @return array
629
   */
630
  public function launch_coordinates_typed() {
631
    return array(
632
      'galaxy' => $this->_fleet_start_galaxy,
633
      'system' => $this->_fleet_start_system,
634
      'planet' => $this->_fleet_start_planet,
635
      'type'   => $this->_fleet_start_type,
636
    );
637
  }
638
639
640
  /**
641
   * Sets object fields for fleet return
642
   */
643
  public function markReturned() {
644
    // TODO - Проверка - а не возвращается ли уже флот?
645
    $this->is_returning = 1;
646
  }
647
648
  public function isReturning() {
649
    return 1 == $this->_is_returning;
650
  }
651
652
  public function markReturnedAndSave() {
653
    $this->markReturned();
654
    $this->dbSave();
655
  }
656
657
  /**
658
   * Parses extended unit_array which can include not only ships but resources, captains etc
659
   *
660
   * @param $unit_array
661
   *
662
   * @throws Exception
663
   */
664
  // TODO - separate shipList and unitList
665
  public function unitsSetFromArray($unit_array) {
666
    if (empty($unit_array) || !is_array($unit_array)) {
667
      return;
668
    }
669
    foreach ($unit_array as $unit_id => $unit_count) {
670
      $unit_count = floatval($unit_count);
671
      if (!$unit_count) {
672
        continue;
673
      }
674
675
      if ($this->isShip($unit_id) || $this->isMissile($unit_id)) {
676
        $this->unitList->unitSetCount($unit_id, $unit_count);
677
      } elseif ($this->isResource($unit_id)) {
678
        $this->resource_list[$unit_id] = $unit_count;
679
      } else {
680
        throw new Exception('Trying to pass to fleet non-resource and non-ship ' . var_export($unit_array, true), FLIGHT_SHIPS_UNIT_WRONG);
681
      }
682
    }
683
  }
684
685
686
  /**
687
   * Sets fleet timers based on flight duration, time on mission (HOLD/EXPLORE) and fleet departure time.
688
   *
689
   * @param int $time_to_travel - flight duration in seconds
690
   * @param int $time_on_mission - time on mission in seconds
691
   * @param int $flight_departure - fleet departure from source planet timestamp. Allows to send fleet in future or in past
692
   */
693
  public function set_times($time_to_travel, $time_on_mission = 0, $flight_departure = SN_TIME_NOW) {
694
    $this->_time_launch = $flight_departure;
695
696
    $this->_time_arrive_to_target = $this->_time_launch + $time_to_travel;
697
    $this->_time_mission_job_complete = $time_on_mission ? $this->_time_arrive_to_target + $time_on_mission : 0;
698
    $this->_time_return_to_source = ($this->_time_mission_job_complete ? $this->_time_mission_job_complete : $this->_time_arrive_to_target) + $time_to_travel;
699
  }
700
701
702
  public function parse_missile_db_row($missile_db_row) {
703
//    $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...
704
705
    if (empty($missile_db_row) || !is_array($missile_db_row)) {
706
      return;
707
    }
708
709
//      $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...
710
//      $irak_original['fleet_start_name'] = $planet_start['name'];
711
    $this->missile_target = $missile_db_row['primaer'];
712
713
    $this->_dbId = -$missile_db_row['id'];
714
    $this->_playerOwnerId = $missile_db_row['fleet_owner'];
715
    $this->_mission_type = MT_MISSILE;
716
717
    $this->_target_owner_id = $missile_db_row['fleet_target_owner'];
718
719
    $this->_group_id = 0;
720
    $this->_is_returning = 0;
721
722
    $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...
723
    $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...
724
    $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...
725
    $this->_time_return_to_source = $missile_db_row['fleet_end_time'];
726
727
    $this->_fleet_start_planet_id = !empty($missile_db_row['fleet_start_planet_id']) ? $missile_db_row['fleet_start_planet_id'] : null;
728
    $this->_fleet_start_galaxy = $missile_db_row['fleet_start_galaxy'];
729
    $this->_fleet_start_system = $missile_db_row['fleet_start_system'];
730
    $this->_fleet_start_planet = $missile_db_row['fleet_start_planet'];
731
    $this->_fleet_start_type = $missile_db_row['fleet_start_type'];
732
733
    $this->_fleet_end_planet_id = !empty($missile_db_row['fleet_end_planet_id']) ? $missile_db_row['fleet_end_planet_id'] : null;
734
    $this->_fleet_end_galaxy = $missile_db_row['fleet_end_galaxy'];
735
    $this->_fleet_end_system = $missile_db_row['fleet_end_system'];
736
    $this->_fleet_end_planet = $missile_db_row['fleet_end_planet'];
737
    $this->_fleet_end_type = $missile_db_row['fleet_end_type'];
738
739
    $this->unitList->unitSetCount(UNIT_DEF_MISSILE_INTERPLANET, $missile_db_row['fleet_amount']);
740
  }
741
742
743
  /**
744
   * @param $from
745
   */
746
  public function set_start_planet($from) {
747
    $this->fleet_start_planet_id = intval($from['id']) ? $from['id'] : null;
748
    $this->fleet_start_galaxy = $from['galaxy'];
749
    $this->fleet_start_system = $from['system'];
750
    $this->fleet_start_planet = $from['planet'];
751
    $this->fleet_start_type = $from['planet_type'];
752
  }
753
754
  /**
755
   * @param $to
756
   */
757
  public function set_end_planet($to) {
758
    $this->target_owner_id = intval($to['id_owner']) ? $to['id_owner'] : 0;
759
    $this->fleet_end_planet_id = intval($to['id']) ? $to['id'] : null;
760
    $this->fleet_end_galaxy = $to['galaxy'];
761
    $this->fleet_end_system = $to['system'];
762
    $this->fleet_end_planet = $to['planet'];
763
    $this->fleet_end_type = $to['planet_type'];
764
  }
765
766
  /**
767
   * @param Vector $to
768
   */
769
  public function setTargetFromVectorObject($to) {
770
    $this->_fleet_end_galaxy = $to->galaxy;
771
    $this->_fleet_end_system = $to->system;
772
    $this->_fleet_end_planet = $to->planet;
773
    $this->_fleet_end_type = $to->type;
774
  }
775
776
  /**
777
   * @param array $db_row
778
   */
779
  protected function ownerExtract(array &$db_row) {
780
    $player = new Player();
781
    $player->dbLoad($db_row['fleet_owner']);
782
    $this->setLocatedAt($player);
783
  }
784
785
  /**
786
   * @param array $db_row
787
   */
788
  protected function ownerInject(array &$db_row) {
789
    $db_row['fleet_owner'] = $this->getPlayerOwnerId();
790
  }
791
792
793
794
795
  // UnitList/Ships access ***************************************************************************************************
796
797
  // TODO - перекрывать пожже - для миссайл-флотов и дефенс-флотов
798
  protected function isShip($unit_id) {
799
    return UnitShip::is_in_group($unit_id);
800
  }
801
802
  protected function isMissile($unit_id) {
803
    return isInGroup(GROUP_STR_MISSILES, $unit_id);
804
  }
805
806
  /**
807
   * Set unit count of $unit_id to $unit_count
808
   * If there is no $unit_id - it will be created and saved to DB on dbSave
809
   *
810
   * @param int $unit_id
811
   * @param int $unit_count
812
   */
813
  public function shipSetCount($unit_id, $unit_count = 0) {
814
    pdump(__CLASS__ . '->' . __FUNCTION__);
815
    $this->shipAdjustCount($unit_id, $unit_count, true);
816
  }
817
818
  /**
819
   * Adjust unit count of $unit_id by $unit_count - or just replace value
820
   * If there is no $unit_id - it will be created and saved to DB on dbSave
821
   *
822
   * @param int  $unit_id
823
   * @param int  $unit_count
824
   * @param bool $replace_value
825
   */
826
  public function shipAdjustCount($unit_id, $unit_count = 0, $replace_value = false) {
827
    $this->unitList->unitAdjustCount($unit_id, $unit_count, $replace_value);
828
  }
829
830
  public function shipGetCount($unit_id) {
831
    return $this->unitList->unitGetCount($unit_id);
832
  }
833
834
  public function shipsCountApplyLossMultiplier($ships_lost_multiplier) {
835
    $this->unitList->unitsCountApplyLossMultiplier($ships_lost_multiplier);
836
  }
837
838
  /**
839
   * Returns fleet ships cost in metal
840
   *
841
   * @param array $shipCostInMetalPerPiece
842
   *
843
   * @return float[]
844
   */
845
  public function shipsCostInMetal($shipCostInMetalPerPiece) {
846
    return $this->unitList->unitsCostInMetal($shipCostInMetalPerPiece);
847
  }
848
849
  /**
850
   * @return UnitIterator
851
   */
852
  public function shipsIterator() {
853
    return $this->unitList->getUnitIterator();
854
  }
855
856
  public function shipsGetTotal() {
857
    return $this->unitList->unitsCount();
858
  }
859
860
  public function shipsGetCapacity() {
861
    return $this->unitList->shipsCapacity();
862
  }
863
864
  public function shipsGetHoldFree() {
865
    return max(0, $this->shipsGetCapacity() - $this->resourcesGetTotal());
866
  }
867
868
  /**
869
   * Get count of ships with $ship_id
870
   *
871
   * @param int $ship_id
872
   *
873
   * @return int
874
   */
875
  public function shipsGetTotalById($ship_id) {
876
    return $this->unitList->unitsCountById($ship_id);
877
  }
878
879
  /**
880
   * Возвращает ёмкость переработчиков во флоте
881
   *
882
   * @param array $recycler_info
883
   *
884
   * @return int
885
   *
886
   * @version 41a50.57
887
   */
888
  public function shipsGetCapacityRecyclers($recycler_info) {
889
    $recyclers_incoming_capacity = 0;
890
    foreach ($this->shipsIterator() as $unitId => $unit) {
891
      if (!empty(static::$snGroupRecyclers[$unitId]) && $unit->count >= 1) {
892
        $recyclers_incoming_capacity += $unit->count * $recycler_info[$unitId]['capacity'];
893
      }
894
    }
895
896
    return $recyclers_incoming_capacity;
897
  }
898
899
  /**
900
   * @return bool
901
   */
902
  // TODO - А если не на планете????
903
  public function shipsIsEnoughOnPlanet() {
904
    return $this->unitList->shipsIsEnoughOnPlanet($this->dbOwnerRow, $this->dbSourcePlanetRow);
905
  }
906
907
  /**
908
   * @return bool
909
   */
910
  public function shipsAllPositive() {
911
    return $this->unitList->unitsPositive();
912
  }
913
914
  /**
915
   * @return bool
916
   */
917
  public function shipsAllFlying() {
918
    return $this->unitList->unitsInGroup(static::$snGroupFleetAndMissiles);
919
  }
920
921
  /**
922
   * @return bool
923
   */
924
  public function shipsAllMovable() {
925
    return $this->unitList->unitsIsAllMovable($this->dbOwnerRow);
926
  }
927
928
  /**
929
   * Restores fleet or resources to planet
930
   *
931
   * @param bool $start
932
   * @param int  $result
933
   *
934
   * @return int
935
   */
936
  // TODO - split to functions
937
  public function shipsLand($start = true, &$result = CACHE_NOTHING) {
938
    sn_db_transaction_check(true);
939
940
    // Если флот уже обработан - не существует или возращается - тогда ничего не делаем
941
    if ($this->isEmpty()) {
942
      return $result;
943
    }
944
945
    $coordinates = $start ? $this->launch_coordinates_typed() : $this->target_coordinates_typed();
946
947
    // Поскольку эта функция может быть вызвана не из обработчика флотов - нам надо всё заблокировать вроде бы НЕ МОЖЕТ!!!
948
    // TODO Проверить от многократного срабатывания !!!
949
    // Тут не блокируем пока - сначала надо заблокировать пользователя, что бы не было дедлока
950
    // TODO поменять на владельца планеты - когда его будут возвращать всегда !!!
951
952
    // Узнаем ИД владельца планеты.
953
    // С блокировкой, поскольку эта функция может быть вызвана только из менеджера летящих флотов.
954
    // А там уже всё заблокировано как надо и повторная блокировка не вызовет дедлок.
955
    $planet_arrival = DBStaticPlanet::db_planet_by_vector($coordinates, '', true);
956
    // Блокируем пользователя
957
    // TODO - вообще-то нам уже известен пользователь в МЛФ - так что можно просто передать его сюда
958
    $user = DBStaticUser::db_user_by_id($planet_arrival['id_owner'], true);
959
960
    // TODO - Проверка, что планета всё еще существует на указанных координатах, а не телепортировалась, не удалена хозяином, не уничтожена врагом
961
    // Флот, который возвращается на захваченную планету, пропадает
962
    // Ship landing is possible only to fleet owner's planet
963
    if ($this->getPlayerOwnerId() == $planet_arrival['id_owner']) {
964
      $db_changeset = array();
965
966
      foreach ($this->shipsIterator() as $ship_id => $ship) {
967
        if ($ship->count) {
968
          $db_changeset['unit'][] = sn_db_unit_changeset_prepare($ship_id, $ship->count, $user, $planet_arrival['id']);
969
        }
970
      }
971
972
      // Adjusting ship amount on planet
973
      if (!empty($db_changeset)) {
974
        classSupernova::db_changeset_apply($db_changeset);
975
      }
976
977
      // Restoring resources to planet
978
      $this->resourcesUnload($start, $result);
979
    }
980
981
    $result = CACHE_FLEET | ($start ? CACHE_PLANET_SRC : CACHE_PLANET_DST);
982
983
    $result = RestoreFleetToPlanet($this, $start, $result);
984
985
    $this->dbDelete();
986
987
    return $result;
988
  }
989
990
991
  // Resources access ***************************************************************************************************
992
993
  /**
994
   * Extracts resources value from db_row
995
   *
996
   * @param array $db_row
997
   *
998
   * @internal param Fleet $that
999
   * @version 41a50.57
1000
   */
1001
  protected function resourcesExtract(array &$db_row) {
1002
    $this->resource_list = array(
1003
      RES_METAL     => !empty($db_row['fleet_resource_metal']) ? floor($db_row['fleet_resource_metal']) : 0,
1004
      RES_CRYSTAL   => !empty($db_row['fleet_resource_crystal']) ? floor($db_row['fleet_resource_crystal']) : 0,
1005
      RES_DEUTERIUM => !empty($db_row['fleet_resource_deuterium']) ? floor($db_row['fleet_resource_deuterium']) : 0,
1006
    );
1007
  }
1008
1009
  protected function resourcesInject(array &$db_row) {
1010
    $db_row['fleet_resource_metal'] = $this->resource_list[RES_METAL];
1011
    $db_row['fleet_resource_crystal'] = $this->resource_list[RES_CRYSTAL];
1012
    $db_row['fleet_resource_deuterium'] = $this->resource_list[RES_DEUTERIUM];
1013
  }
1014
1015
  /**
1016
   * Set current resource list from array of units
1017
   *
1018
   * @param array $resource_list
1019
   */
1020
  public function resourcesSet($resource_list) {
1021
    if (!empty($this->propertiesAdjusted['resource_list'])) {
1022
      throw new PropertyAccessException('Property "resource_list" already was adjusted so no SET is possible until dbSave in ' . get_called_class() . '::unitSetResourceList', ERR_ERROR);
1023
    }
1024
    $this->resourcesAdjust($resource_list, true);
1025
  }
1026
1027
  /**
1028
   * Updates fleet resource list with deltas
1029
   *
1030
   * @param array $resource_delta_list
1031
   * @param bool  $replace_value
1032
   *
1033
   * @throws Exception
1034
   */
1035
  public function resourcesAdjust($resource_delta_list, $replace_value = false) {
1036
    !is_array($resource_delta_list) ? $resource_delta_list = array() : false;
1037
1038
    foreach ($resource_delta_list as $resource_id => $unit_delta) {
1039
      if (!UnitResourceLoot::is_in_group($resource_id) || !($unit_delta = floor($unit_delta))) {
1040
        // Not a resource or no resources - continuing
1041
        continue;
1042
      }
1043
1044
      if ($replace_value) {
1045
        $this->resource_list[$resource_id] = $unit_delta;
1046
      } else {
1047
        $this->resource_list[$resource_id] += $unit_delta;
1048
        // Preparing changes
1049
        $this->resource_delta[$resource_id] += $unit_delta;
1050
        $this->propertiesAdjusted['resource_list'] = 1;
1051
      }
1052
1053
      // Check for negative unit value
1054
      if ($this->resource_list[$resource_id] < 0) {
1055
        // TODO
1056
        throw new Exception('Resource ' . $resource_id . ' will become negative in ' . get_called_class() . '::unitAdjustResourceList', ERR_ERROR);
1057
      }
1058
    }
1059
  }
1060
1061
  public function resourcesGetTotal() {
1062
    return empty($this->resource_list) || !is_array($this->resource_list) ? 0 : array_sum($this->resource_list);
1063
  }
1064
1065
  /**
1066
   * @param array $rate
1067
   *
1068
   * @return float
1069
   */
1070
  public function resourcesGetTotalInMetal(array $rate) {
1071
    return
1072
      $this->resource_list[RES_METAL] * $rate[RES_METAL]
1073
      + $this->resource_list[RES_CRYSTAL] * $rate[RES_CRYSTAL] / $rate[RES_METAL]
1074
      + $this->resource_list[RES_DEUTERIUM] * $rate[RES_DEUTERIUM] / $rate[RES_METAL];
1075
  }
1076
1077
  /**
1078
   * Returns resource list in fleet
1079
   */
1080
  // TODO
1081
  public function resourcesGetList() {
1082
    return $this->resource_list;
1083
  }
1084
1085
  public function resourcesReset() {
1086
    $this->resourcesSet(array(
1087
      RES_METAL     => 0,
1088
      RES_CRYSTAL   => 0,
1089
      RES_DEUTERIUM => 0,
1090
    ));
1091
  }
1092
1093
  /**
1094
   * Restores fleet or resources to planet
1095
   *
1096
   * @param bool $start
1097
   * @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...
1098
   * @param int  $result
1099
   *
1100
   * @return int
1101
   */
1102
  public function resourcesUnload($start = true, &$result = CACHE_NOTHING) {
1103
    sn_db_transaction_check(true);
1104
1105
    // Если флот уже обработан - не существует или возращается - тогда ничего не делаем
1106
    if (!$this->resourcesGetTotal()) {
1107
      return $result;
1108
    }
1109
1110
    $coordinates = $start ? $this->launch_coordinates_typed() : $this->target_coordinates_typed();
1111
1112
    // Поскольку эта функция может быть вызвана не из обработчика флотов - нам надо всё заблокировать вроде бы НЕ МОЖЕТ!!!
1113
    // TODO Проверить от многократного срабатывания !!!
1114
    // Тут не блокируем пока - сначала надо заблокировать пользователя, что бы не было дедлока
1115
    // TODO поменять на владельца планеты - когда его будут возвращать всегда !!!
1116
1117
1118
    // Узнаем ИД владельца планеты.
1119
    // С блокировкой, поскольку эта функция может быть вызвана только из менеджера летящих флотов.
1120
    // А там уже всё заблокировано как надо и повторная блокировка не вызовет дедлок.
1121
    $planet_arrival = DBStaticPlanet::db_planet_by_vector($coordinates, '', true);
1122
1123
    // TODO - Проверка, что планета всё еще существует на указанных координатах, а не телепортировалась, не удалена хозяином, не уничтожена врагом
1124
1125
    // Restoring resources to planet
1126
    if ($this->resourcesGetTotal()) {
1127
      $fleet_resources = $this->resourcesGetList();
1128
      DBStaticPlanet::db_planet_set_by_id($planet_arrival['id'],
1129
        "`metal` = `metal` + '{$fleet_resources[RES_METAL]}', `crystal` = `crystal` + '{$fleet_resources[RES_CRYSTAL]}', `deuterium` = `deuterium` + '{$fleet_resources[RES_DEUTERIUM]}'");
1130
    }
1131
1132
    $this->resourcesReset();
1133
    $this->markReturned();
1134
1135
    $result = CACHE_FLEET | ($start ? CACHE_PLANET_SRC : CACHE_PLANET_DST);
1136
1137
    return $result;
1138
  }
1139
1140
1141
  protected function isResource($unit_id) {
1142
    return UnitResourceLoot::is_in_group($unit_id);
1143
  }
1144
1145
  /**
1146
   * @param int $speed_percent
1147
   *
1148
   * @return array
1149
   */
1150
  protected function flt_travel_data($speed_percent = 10) {
1151
    $distance = $this->targetVector->distanceFromCoordinates($this->dbSourcePlanetRow);
1152
1153
    return $this->unitList->travelData($speed_percent, $distance, $this->dbOwnerRow);
1154
  }
1155
1156
1157
  /**
1158
   * @param array  $dbPlayerRow
1159
   * @param array  $dbPlanetRow
1160
   * @param Vector $targetVector
1161
   *
1162
   */
1163
  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...
1164
    $objFleet5Player = new Player();
1165
    $objFleet5Player->dbRowParse($dbPlayerRow);
1166
    $this->setLocatedAt($objFleet5Player);
1167
1168
    $this->mission_type = $mission;
1169
1170
    $this->dbOwnerRow = $dbPlayerRow;
1171
1172
    $this->set_start_planet($dbPlanetRow);
1173
    $this->dbSourcePlanetRow = $dbPlanetRow;
1174
1175
    $this->setTargetFromVectorObject($targetVector);
1176
    $this->targetVector = $targetVector;
1177
1178
//    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...
1179
//      $this->restrictTargetTypeByMission();
1180
//
1181
//      // TODO - Нельзя тут просто менять тип планеты или координат!
1182
//      // If current planet type is not allowed on mission - switch planet type
1183
//      if (empty($this->allowed_planet_types[$this->targetVector->type])) {
1184
//        $targetPlanetCoords->type = reset($this->allowed_planet_types);
1185
//      }
1186
//    }
1187
1188
    $this->populateTargetPlanetAndOwner();
1189
1190
    $this->unitsSetFromArray($ships);
1191
1192
    $this->_group_id = intval($fleet_group_mr);
1193
1194
    $this->oldSpeedInTens = $oldSpeedInTens;
1195
1196
    $this->targetedUnitId = $targetedUnitId;
1197
1198
    $this->captainId = $captainId;
1199
1200
    $this->_time_launch = SN_TIME_NOW;
1201
1202
    $this->renderParamCoordinates();
1203
1204
  }
1205
1206
  protected function restrictTargetTypeByMission() {
1207
    if ($this->_mission_type == MT_MISSILE) {
1208
      $this->allowed_planet_types = array(PT_PLANET => PT_PLANET);
1209
    } elseif ($this->_mission_type == MT_COLONIZE || $this->_mission_type == MT_EXPLORE) {
1210
      // TODO - PT_NONE
1211
      $this->allowed_planet_types = array(PT_PLANET => PT_PLANET);
1212
    } elseif ($this->_mission_type == MT_RECYCLE) {
1213
      $this->allowed_planet_types = array(PT_DEBRIS => PT_DEBRIS);
1214
    } elseif ($this->_mission_type == MT_DESTROY) {
1215
      $this->allowed_planet_types = array(PT_MOON => PT_MOON);
1216
    } else {
1217
      $this->allowed_planet_types = array(PT_PLANET => PT_PLANET, PT_MOON => PT_MOON);
1218
    }
1219
  }
1220
1221
  protected function populateTargetPlanetAndOwner() {
1222
    // If vector points to no exact object OR debris - then getting planet on coordinates
1223
    $targetVector = clone $this->targetVector;
1224
    if ($targetVector->type == PT_DEBRIS || $targetVector == PT_NONE) {
1225
      $targetVector->type = PT_PLANET;
1226
    }
1227
1228
    $this->dbTargetRow = DBStaticPlanet::db_planet_by_vector_object($targetVector);
1229 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...
1230
      $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...
1231
    }
1232
  }
1233
1234
1235
  protected function printErrorIfNoShips() {
1236
    if ($this->unitList->unitsCount() <= 0) {
1237
      message(classLocale::$lang['fl_err_no_ships'], classLocale::$lang['fl_error'], 'fleet' . DOT_PHP_EX, 5);
1238
    }
1239
  }
1240
1241
  /**
1242
   */
1243
  public function renderParamCoordinates() {
1244
    global $template_result;
1245
    $template_result += array(
1246
      'thisgalaxy'      => $this->dbSourcePlanetRow['galaxy'],
1247
      'thissystem'      => $this->dbSourcePlanetRow['system'],
1248
      'thisplanet'      => $this->dbSourcePlanetRow['planet'],
1249
      'thisplanet_type' => $this->dbSourcePlanetRow['planet_type'],
1250
1251
      'galaxy'         => $this->targetVector->galaxy,
1252
      'system'         => $this->targetVector->system,
1253
      'planet'         => $this->targetVector->planet,
1254
      'planet_type'    => $this->targetVector->type,
1255
      'target_mission' => $this->_mission_type,
1256
      'MISSION_NAME'   => $this->_mission_type ? classLocale::$lang['type_mission'][$this->_mission_type] : '',
1257
1258
      'MT_COLONIZE' => MT_COLONIZE,
1259
    );
1260
  }
1261
1262
1263
  protected function renderFleetCoordinates($missionStartTimeStamp = SN_TIME_NOW, $timeMissionJob = 0) {
1264
    $timeToReturn = $this->travelData['duration'] * 2 + $timeMissionJob;
1265
1266
    return array(
1267
      'ID'                 => 1,
1268
      'START_TYPE_TEXT_SH' => classLocale::$lang['sys_planet_type_sh'][$this->dbSourcePlanetRow['planet_type']],
1269
      'START_COORDS'       => uni_render_coordinates($this->dbSourcePlanetRow),
1270
      'START_NAME'         => $this->dbSourcePlanetRow['name'],
1271
      'START_TIME_TEXT'    => date(FMT_DATE_TIME, $missionStartTimeStamp + $timeToReturn + SN_CLIENT_TIME_DIFF),
1272
      'START_LEFT'         => floor($timeToReturn),
1273
      'END_TYPE_TEXT_SH'   =>
1274
        !empty($this->targetVector->type)
1275
          ? classLocale::$lang['sys_planet_type_sh'][$this->targetVector->type]
1276
          : '',
1277
      'END_COORDS'         => uniRenderVector($this->targetVector),
1278
      'END_NAME'           => !empty($this->dbTargetRow['name']) ? $this->dbTargetRow['name'] : '',
1279
      'END_TIME_TEXT'      => date(FMT_DATE_TIME, $missionStartTimeStamp + $this->travelData['duration'] + SN_CLIENT_TIME_DIFF),
1280
      'END_LEFT'           => floor($this->travelData['duration']),
1281
    );
1282
  }
1283
1284
  /**
1285
   * @param int $missionStartTimeStamp
1286
   * @param int $timeMissionJob
1287
   *
1288
   * @return array
1289
   *
1290
   * @throws Exception
1291
   */
1292
  protected function renderFleet($missionStartTimeStamp = SN_TIME_NOW, $timeMissionJob = 0) {
1293
    $this->printErrorIfNoShips();
1294
1295
    $result = $this->renderFleetCoordinates($missionStartTimeStamp, $timeMissionJob);
1296
    $result['.']['ships'] = $this->unitList->unitsRender();
1297
1298
    return $result;
1299
  }
1300
1301
  /**
1302
   * @return array
1303
   */
1304
  protected function renderAllowedMissions() {
1305
    $result = array();
1306
1307
    ksort($this->allowed_missions);
1308
    // If mission is not set - setting first mission from allowed
1309
    if (empty($this->_mission_type) && is_array($this->allowed_missions)) {
1310
      reset($this->allowed_missions);
1311
      $this->_mission_type = key($this->allowed_missions);
1312
    }
1313
    foreach ($this->allowed_missions as $key => $value) {
1314
      $result[] = array(
1315
        'ID'   => $key,
1316
        'NAME' => classLocale::$lang['type_mission'][$key],
1317
      );
1318
    };
1319
1320
    return $result;
1321
  }
1322
1323
  /**
1324
   * @param $max_duration
1325
   *
1326
   * @return array
1327
   */
1328
  protected function renderDuration($max_duration) {
1329
    $result = array();
1330
1331
    if (!$max_duration) {
1332
      return $result;
1333
    }
1334
1335
    $config_game_speed_expedition = ($this->_mission_type == MT_EXPLORE && classSupernova::$config->game_speed_expedition ? classSupernova::$config->game_speed_expedition : 1);
1336
    for ($i = 1; $i <= $max_duration; $i++) {
1337
      $result[] = array(
1338
        'ID'   => $i,
1339
        'TIME' => pretty_time(ceil($i * 3600 / $config_game_speed_expedition)),
1340
      );
1341
    }
1342
1343
    return $result;
1344
  }
1345
1346
  /**
1347
   * @param array $planetResources
1348
   *
1349
   * @return array
1350
   */
1351
  // TODO - REDO to resource_id
1352
  protected function renderPlanetResources(&$planetResources) {
1353
    $result = array();
1354
1355
    $i = 0;
1356
    foreach ($planetResources as $resource_id => $resource_amount) {
1357
      $result[] = array(
1358
        'ID'        => $i++, // $resource_id,
1359
        'ON_PLANET' => $resource_amount,
1360
        'TEXT'      => pretty_number($resource_amount),
1361
        'NAME'      => classLocale::$lang['tech'][$resource_id],
1362
      );
1363
    }
1364
1365
    return $result;
1366
  }
1367
1368
  /**
1369
   * @return array
1370
   */
1371
  protected function renderAllowedPlanetTypes() {
1372
    $result = array();
1373
1374
    foreach ($this->allowed_planet_types as $possible_planet_type_id) {
1375
      $result[] = array(
1376
        'ID'         => $possible_planet_type_id,
1377
        'NAME'       => classLocale::$lang['sys_planet_type'][$possible_planet_type_id],
1378
        'NAME_SHORT' => classLocale::$lang['sys_planet_type_sh'][$possible_planet_type_id],
1379
      );
1380
    }
1381
1382
    return $result;
1383
  }
1384
1385
1386
  protected function renderFleet1TargetSelect(&$shortcut) {
1387
    global $note_priority_classes;
1388
1389
    $name = !empty($shortcut['title']) ? $shortcut['title'] : $shortcut['name'];
1390
1391
    $result = array(
1392
      'NAME'       => $name,
1393
      'GALAXY'     => $shortcut['galaxy'],
1394
      'SYSTEM'     => $shortcut['system'],
1395
      'PLANET'     => $shortcut['planet'],
1396
      'TYPE'       => $shortcut['planet_type'],
1397
      'TYPE_PRINT' => classLocale::$lang['fl_shrtcup'][$shortcut['planet_type']],
1398
    );
1399
1400
    if (isset($shortcut['priority'])) {
1401
      $result += array(
1402
        'PRIORITY'       => $shortcut['priority'],
1403
        'PRIORITY_CLASS' => $note_priority_classes[$shortcut['priority']],
1404
      );
1405
    }
1406
1407
    if (isset($shortcut['id'])) {
1408
      $result += array(
1409
        'ID' => $shortcut['id'],
1410
      );
1411
    }
1412
1413
    return $result;
1414
  }
1415
1416
  /**
1417
   * @return array
1418
   */
1419
  protected function renderFleetShortcuts() {
1420
    $result = array();
1421
1422
    // Building list of shortcuts
1423
    $query = DBStaticNote::db_note_list_select_by_owner_and_planet($this->dbOwnerRow);
1424
    while ($row = db_fetch($query)) {
1425
      $result[] = $this->renderFleet1TargetSelect($row);
1426
    }
1427
1428
    return $result;
1429
  }
1430
1431
  /**
1432
   * Building list of own planets & moons
1433
   *
1434
   * @return array
1435
   */
1436
  protected function renderOwnPlanets() {
1437
    $result = array();
1438
1439
    $colonies = DBStaticPlanet::db_planet_list_sorted($this->dbOwnerRow);
1440
    if (count($colonies) <= 1) {
1441
      return $result;
1442
    }
1443
1444
    foreach ($colonies as $row) {
1445
      if ($row['id'] == $this->dbSourcePlanetRow['id']) {
1446
        continue;
1447
      }
1448
1449
      $result[] = $this->renderFleet1TargetSelect($row);
1450
    }
1451
1452
    return $result;
1453
  }
1454
1455
  /**
1456
   * @return array
1457
   */
1458
  protected function renderACSList() {
1459
    $result = array();
1460
1461
    $query = DBStaticFleetACS::db_acs_get_list();
1462
    while ($row = db_fetch($query)) {
1463
      $members = explode(',', $row['eingeladen']);
1464
      foreach ($members as $a => $b) {
1465
        if ($b == $this->dbOwnerRow['id']) {
1466
          $result[] = $this->renderFleet1TargetSelect($row);
1467
        }
1468
      }
1469
    }
1470
1471
    return $result;
1472
  }
1473
1474
1475
  /**
1476
   * @param $template_result
1477
   */
1478
  protected function renderShipSortOptions(&$template_result) {
1479
    foreach (classLocale::$lang['player_option_fleet_ship_sort'] as $sort_id => $sort_text) {
1480
      $template_result['.']['ship_sort_list'][] = array(
1481
        'VALUE' => $sort_id,
1482
        'TEXT'  => $sort_text,
1483
      );
1484
    }
1485
    $template_result += array(
1486
      'FLEET_SHIP_SORT'         => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_SORT],
1487
      'FLEET_SHIP_SORT_INVERSE' => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_SORT_INVERSE],
1488
    );
1489
  }
1490
1491
1492
  /**
1493
   *
1494
   */
1495
  public function fleetPage0() {
1496
    global $template_result;
1497
1498
    lng_include('overview');
1499
1500
    if (empty($this->dbSourcePlanetRow)) {
1501
      message(classLocale::$lang['fl_noplanetrow'], classLocale::$lang['fl_error']);
1502
    }
1503
1504
    // TODO - redo to unitlist render/unit render
1505
    $this->renderAvailableShips($template_result, $this->dbOwnerRow, $this->dbSourcePlanetRow);
1506
1507
    $this->renderShipSortOptions($template_result);
1508
1509
    /**
1510
     * @var Player $playerOwner
1511
     */
1512
    $playerOwner = $this->getLocatedAt();
1513
1514
    $template_result += array(
1515
      'FLYING_FLEETS'      => $playerOwner->fleetsFlying(),
1516
      'MAX_FLEETS'         => $playerOwner->fleetsMax(),
1517
      'FREE_FLEETS'        => $playerOwner->fleetsMax() - $playerOwner->fleetsFlying(),
1518
      'FLYING_EXPEDITIONS' => $playerOwner->expeditionsFlying(),
1519
      'MAX_EXPEDITIONS'    => $playerOwner->expeditionsMax(),
1520
      'FREE_EXPEDITIONS'   => $playerOwner->expeditionsMax() - $playerOwner->expeditionsFlying(),
1521
      'COLONIES_CURRENT'   => $playerOwner->coloniesCurrent(),
1522
      'COLONIES_MAX'       => $playerOwner->coloniesMax(),
1523
1524
      'TYPE_NAME' => classLocale::$lang['fl_planettype'][$this->targetVector->type],
1525
1526
      'speed_factor' => flt_server_flight_speed_multiplier(),
1527
1528
      'PLANET_RESOURCES' => pretty_number($this->dbSourcePlanetRow['metal'] + $this->dbSourcePlanetRow['crystal'] + $this->dbSourcePlanetRow['deuterium']),
1529
      'PLANET_DEUTERIUM' => pretty_number($this->dbSourcePlanetRow['deuterium']),
1530
1531
      'PLAYER_OPTION_FLEET_SHIP_SELECT_OLD'       => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_SELECT_OLD],
1532
      'PLAYER_OPTION_FLEET_SHIP_HIDE_SPEED'       => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_HIDE_SPEED],
1533
      'PLAYER_OPTION_FLEET_SHIP_HIDE_CAPACITY'    => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_HIDE_CAPACITY],
1534
      'PLAYER_OPTION_FLEET_SHIP_HIDE_CONSUMPTION' => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_HIDE_CONSUMPTION],
1535
    );
1536
1537
    $template = gettemplate('fleet0', true);
1538
    $template->assign_recursive($template_result);
1539
    display($template, classLocale::$lang['fl_title']);
1540
  }
1541
1542
  /**
1543
   *
1544
   */
1545
  public function fleetPage1() {
1546
    global $template_result;
1547
1548
    $template_result['.']['fleets'][] = $this->renderFleet(SN_TIME_NOW);
1549
    $template_result['.']['possible_planet_type_id'] = $this->renderAllowedPlanetTypes();
1550
    $template_result['.']['colonies'] = $this->renderOwnPlanets();
1551
    $template_result['.']['shortcut'] = $this->renderFleetShortcuts();
1552
    $template_result['.']['acss'] = $this->renderACSList();
1553
1554
    $template_result += array(
1555
      'speed_factor' => flt_server_flight_speed_multiplier(),
1556
1557
      'fleet_speed'    => $this->fleetSpeed(),
1558
      'fleet_capacity' => $this->shipsGetCapacity(),
1559
1560
      'PLANET_DEUTERIUM' => pretty_number($this->dbSourcePlanetRow['deuterium']),
1561
1562
      'PAGE_HINT' => classLocale::$lang['fl_page1_hint'],
1563
    );
1564
1565
    $template = gettemplate('fleet1', true);
1566
    $template->assign_recursive($template_result);
1567
    display($template, classLocale::$lang['fl_title']);
1568
  }
1569
1570
  public function fleetSpeed() {
1571
    $maxSpeed = array();
1572
    foreach ($this->shipsIterator() as $ship_id => $unit) {
1573
      if ($unit->count > 0 && !empty(static::$snGroupFleetAndMissiles[$ship_id])) {
1574
        $single_ship_data = get_ship_data($ship_id, $this->dbOwnerRow);
1575
        $maxSpeed[$ship_id] = $single_ship_data['speed'];
1576
      }
1577
    }
1578
1579
    return empty($maxSpeed) ? 0 : min($maxSpeed);
1580
  }
1581
1582
  /**
1583
   * @param array $planetResourcesWithoutConsumption
1584
   */
1585
  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...
1586
    $this->travelData = $this->flt_travel_data($this->oldSpeedInTens);
1587
1588
//    /**
1589
//     * @var array $allowed_missions
1590
//     */
1591
//    public $allowed_missions = array();
1592
//    /**
1593
//     * @var array $exists_missions
1594
//     */
1595
//    public $exists_missions = array();
1596
//    public $allowed_planet_types = array(
1597
//      // PT_NONE => PT_NONE,
1598
//      PT_PLANET => PT_PLANET,
1599
//      PT_MOON   => PT_MOON,
1600
//      PT_DEBRIS => PT_DEBRIS
1601
//    );
1602
1603
//    $this->exists_missions = array(
1604
////      MT_EXPLORE => MT_EXPLORE,
1605
////      MT_MISSILE => MT_MISSILE,
1606
//      MT_COLONIZE => MT_COLONIZE,
1607
//    );  // TODO
1608
    $this->allowed_missions = array();
1609
1610
    if ($this->mission_type != MT_NONE && empty($this->exists_missions[$this->mission_type])) {
1611
      throw new ExceptionFleetInvalid(FLIGHT_MISSION_UNKNOWN, FLIGHT_MISSION_UNKNOWN);
1612
    }
1613
1614
    $this->validator->validateGlobals();
1615
1616
    $validateResult = array();
1617
    foreach ($this->exists_missions as $missionType => $missionData) {
1618
//print('qwe');
1619
      $mission = \Mission\MissionFactory::build($missionType, $this);
1620
//print('wer');
1621
      $validateResult[$missionType] = $mission->validate();
1622
      if (FLIGHT_ALLOWED == $validateResult[$missionType]) {
1623
        $this->allowed_missions[$missionType] = $mission;
1624
      } else {
1625
        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...
1626
        }
1627
        unset($this->allowed_missions[$missionType]);
1628
      }
1629
    }
1630
//    print('asd');
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...
1631
//var_dump($this->allowed_missions);
1632
//    print('выф');
1633
    if(empty($this->allowed_missions)) {
1634
      if($this->mission_type != MT_NONE && isset($validateResult[$this->mission_type])) {
1635
        throw new ExceptionFleetInvalid($validateResult[$this->mission_type], $validateResult[$this->mission_type]);
1636
      } else {
1637
        throw new ExceptionFleetInvalid(FLIGHT_MISSION_IMPOSSIBLE, FLIGHT_MISSION_IMPOSSIBLE);
1638
      }
1639
    }
1640
1641
//    $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...
1642
  }
1643
1644
  /**
1645
   * @param array $planetResourcesWithoutConsumption
1646
   */
1647
  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...
1648
    $this->travelData = $this->flt_travel_data($this->oldSpeedInTens);
1649
1650
    if (empty($this->exists_missions[$this->mission_type])) {
1651
      throw new ExceptionFleetInvalid(FLIGHT_MISSION_UNKNOWN, FLIGHT_MISSION_UNKNOWN);
1652
    }
1653
1654
    $this->validator->validateGlobals();
1655
1656
    $mission = \Mission\MissionFactory::build($this->mission_type, $this);
1657
    $result = $mission->validate();
1658
    if (FLIGHT_ALLOWED != $result) {
1659
      throw new ExceptionFleetInvalid($result, $result);
1660
    }
1661
1662
  }
1663
1664
  /**
1665
   *
1666
   */
1667
  public function fleetPage2() {
1668
    global $template_result;
1669
1670
    $planetResourcesTotal = DBStaticPlanet::getResources($this->dbOwnerRow, $this->dbSourcePlanetRow);
1671
    $planetResourcesWithoutConsumption = $this->resourcesSubstractConsumption($planetResourcesTotal);
1672
1673
    try {
1674
      $this->fleetPage2Prepare($planetResourcesWithoutConsumption);
1675
    } catch (Exception $e) {
1676
      // TODO - MESSAGE BOX
1677 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...
1678
        sn_db_transaction_rollback();
1679
        pdie(classLocale::$lang['fl_attack_error'][$e->getCode()]);
1680
      } else {
1681
        throw $e;
1682
      }
1683
    }
1684
1685
    // Flight allowed here
1686
    pdump('FLIGHT_ALLOWED', FLIGHT_ALLOWED);
1687
//    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...
1688
1689
    $template_result['.']['missions'] = $this->renderAllowedMissions();
1690
1691
    $template_result['.']['fleets'][] = $this->renderFleet(SN_TIME_NOW);
1692
1693
    $max_duration =
1694
      $this->_mission_type == MT_EXPLORE
1695
        ? get_player_max_expedition_duration($this->dbOwnerRow)
1696
        : (isset($this->allowed_missions[MT_HOLD]) ? 12 : 0);
1697
    $template_result['.']['duration'] = $this->renderDuration($max_duration);
1698
1699
    $this->captainGet();
1700
    $template_result += $this->renderCaptain();
1701
1702
    $template_result['.']['resources'] = $this->renderPlanetResources($planetResourcesWithoutConsumption);
1703
1704
    $template_result += array(
1705
      'planet_metal'     => $planetResourcesWithoutConsumption[RES_METAL],
1706
      'planet_crystal'   => $planetResourcesWithoutConsumption[RES_CRYSTAL],
1707
      'planet_deuterium' => $planetResourcesWithoutConsumption[RES_DEUTERIUM],
1708
1709
      'fleet_capacity' => $this->shipsGetCapacity() - $this->travelData['consumption'],
1710
      'speed'          => $this->oldSpeedInTens,
1711
      'fleet_group'    => $this->_group_id,
1712
1713
      'MAX_DURATION'          => $max_duration,
1714
1715
      // 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...
1716
//      'IS_TRANSPORT_MISSIONS' => !empty($this->allowed_missions[$this->_mission_type]['transport']),
1717
      'IS_TRANSPORT_MISSIONS' => true,
1718
1719
      'PLAYER_COLONIES_CURRENT' => get_player_current_colonies($this->dbOwnerRow),
1720
      'PLAYER_COLONIES_MAX'     => get_player_max_colonies($this->dbOwnerRow),
1721
    );
1722
1723
    $template = gettemplate('fleet2', true);
1724
    $template->assign_recursive($template_result);
1725
    display($template, classLocale::$lang['fl_title']);
1726
  }
1727
1728
  /**
1729
   *
1730
   */
1731
  public function fleetPage3() {
1732
    global $template_result;
1733
1734
    $this->isRealFlight = true;
1735
1736
    sn_db_transaction_start();
1737
1738
    DBStaticUser::db_user_lock_with_target_owner_and_acs($this->dbOwnerRow, $this->dbTargetRow);
1739
1740
    // Checking for group
1741
    $this->groupCheck();
1742
1743
    $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...
1744
    $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...
1745
    if (!empty($this->dbTargetRow['id'])) {
1746
      $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...
1747
    }
1748
    // TODO - deprecated! Filled in populateTargetPlanetAndOwner
1749 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...
1750
      $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...
1751
    }
1752
1753
    $this->resource_list = array(
1754
      RES_METAL     => max(0, floor(sys_get_param_float('resource0'))),
1755
      RES_CRYSTAL   => max(0, floor(sys_get_param_float('resource1'))),
1756
      RES_DEUTERIUM => max(0, floor(sys_get_param_float('resource2'))),
1757
    );
1758
1759
    $this->captainGet();
1760
1761
    $this->travelData = $this->flt_travel_data($this->oldSpeedInTens);
1762
1763
    $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...
1764
    $planetResourcesWithoutConsumption = $this->resourcesSubstractConsumption($planetResourcesTotal);
1765
1766
    try {
1767
      $this->fleetPage3Prepare($planetResourcesWithoutConsumption);
1768
    } catch (Exception $e) {
1769
      // TODO - MESSAGE BOX
1770 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...
1771
        sn_db_transaction_rollback();
1772
        pdie(classLocale::$lang['fl_attack_error'][$e->getCode()]);
1773
      } else {
1774
        throw $e;
1775
      }
1776
    }
1777
1778
//    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...
1779
//      $validator = new FleetValidator($this);
1780
//      $validator->validate();
1781
//    } catch (Exception $e) {
1782
//      // TODO - MESSAGE BOX
1783
//      if($e instanceof ExceptionFleetInvalid) {
1784
//        sn_db_transaction_rollback();
1785
//        pdie(classLocale::$lang['fl_attack_error'][$e->getCode()]);
1786
//      } else {
1787
//        throw $e;
1788
//      }
1789
//    }
1790
1791
    // TODO - check if mission is not 0 and in ALLOWED_MISSIONS
1792
1793
    // Flight allowed here
1794
    pdump('FLIGHT_ALLOWED', FLIGHT_ALLOWED);
1795
//    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...
1796
1797
1798
    $timeMissionJob = 0;
1799
    // TODO check for empty mission AKA mission allowed
1800
    /*
1801
        if ($this->_mission_type == MT_ACS && $aks) {
1802
          $acsTimeToArrive = $aks['ankunft'] - SN_TIME_NOW;
1803
          if ($acsTimeToArrive < $this->travelData['duration']) {
1804
            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']);
1805
          }
1806
          // Set time to travel to ACS' TTT
1807
          $this->travelData['duration'] = $acsTimeToArrive;
1808
    */
1809
    if ($this->_mission_type != MT_ACS) {
1810
      if ($this->_mission_type == MT_EXPLORE || $this->_mission_type == MT_HOLD) {
1811
        $max_duration = $this->_mission_type == MT_EXPLORE ? get_player_max_expedition_duration($this->dbOwnerRow) : ($this->_mission_type == MT_HOLD ? 12 : 0);
1812
        if ($max_duration) {
1813
          $mission_time_in_hours = sys_get_param_id('missiontime');
1814
          if ($mission_time_in_hours > $max_duration || $mission_time_in_hours < 1) {
1815
            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...
1816
            die();
1817
          }
1818
          $timeMissionJob = ceil($mission_time_in_hours * 3600 / ($this->_mission_type == MT_EXPLORE && classSupernova::$config->game_speed_expedition ? classSupernova::$config->game_speed_expedition : 1));
1819
        }
1820
      }
1821
    }
1822
1823
    //
1824
    //
1825
    //
1826
    //
1827
    //
1828
    //
1829
    //
1830
    //
1831
    // ---------------- END OF CHECKS ------------------------------------------------------
1832
1833
    $this->set_times($this->travelData['duration'], $timeMissionJob);
1834
    $this->dbInsert();
1835
1836
    DBStaticPlanet::db_planet_set_by_id($this->dbSourcePlanetRow['id'],
1837
      "`metal` = `metal` - {$this->resource_list[RES_METAL]},
1838
      `crystal` = `crystal` - {$this->resource_list[RES_CRYSTAL]},
1839
      `deuterium` = `deuterium` - {$this->resource_list[RES_DEUTERIUM]} - {$this->travelData['consumption']}"
1840
    );
1841
1842
    $db_changeset = $this->unitList->db_prepare_old_changeset_for_planet($this->dbOwnerRow, $this->dbSourcePlanetRow['id']);
1843
    classSupernova::db_changeset_apply($db_changeset);
1844
1845
1846
    if (!empty($this->captain['unit_id'])) {
1847
      DBStaticUnit::db_unit_set_by_id($this->captain['unit_id'], "`unit_location_type` = " . LOC_FLEET . ", `unit_location_id` = {$this->_dbId}");
1848
    }
1849
1850
//    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...
1851
//
1852
//    // Set time to travel to ACS' TTT
1853
//    $this->fleet->travelData['duration'] = $acsTimeToArrive;
1854
1855
1856
    $template_result['.']['fleets'][] = $this->renderFleet(SN_TIME_NOW, $timeMissionJob);
1857
1858
    $template_result += array(
1859
      'mission'         => classLocale::$lang['type_mission'][$this->_mission_type] . ($this->_mission_type == MT_EXPLORE || $this->_mission_type == MT_HOLD ? ' ' . pretty_time($timeMissionJob) : ''),
1860
      'dist'            => pretty_number($this->travelData['distance']),
1861
      'speed'           => pretty_number($this->travelData['fleet_speed']),
1862
      'deute_need'      => pretty_number($this->travelData['consumption']),
1863
      'from'            => "{$this->dbSourcePlanetRow['galaxy']}:{$this->dbSourcePlanetRow['system']}:{$this->dbSourcePlanetRow['planet']}",
1864
      'time_go'         => date(FMT_DATE_TIME, $this->_time_arrive_to_target),
1865
      'time_go_local'   => date(FMT_DATE_TIME, $this->_time_arrive_to_target + SN_CLIENT_TIME_DIFF),
1866
      'time_back'       => date(FMT_DATE_TIME, $this->_time_return_to_source),
1867
      'time_back_local' => date(FMT_DATE_TIME, $this->_time_return_to_source + SN_CLIENT_TIME_DIFF),
1868
    );
1869
1870
    $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...
1871
1872
    pdie('Stop for debug');
1873
1874
    sn_db_transaction_commit();
1875
1876
    $template = gettemplate('fleet3', true);
1877
    $template->assign_recursive($template_result);
1878
    display($template, classLocale::$lang['fl_title']);
1879
  }
1880
1881
  protected function groupCheck() {
1882
    if (empty($this->_group_id)) {
1883
      return;
1884
    }
1885
1886
    // ACS attack must exist (if acs fleet has arrived this will also return false (2 checks in 1!!!)
1887
    $this->acs = DBStaticFleetACS::db_acs_get_by_group_id($this->_group_id);
1888
    if (empty($this->acs)) {
1889
      $this->_group_id = 0;
1890
    } else {
1891
      $this->targetVector->convertToVector($this->acs);
1892
    }
1893
  }
1894
1895
  /**
1896
   * @param array $planetResources
1897
   *
1898
   * @return array
1899
   */
1900
  protected function resourcesSubstractConsumption($planetResources) {
1901
    !isset($planetResources[RES_DEUTERIUM]) ? $planetResources[RES_DEUTERIUM] = 0 : false;
1902
1903
    if ($this->travelData['consumption'] >= 0) {
1904
      $planetResources[RES_DEUTERIUM] -= ceil($this->travelData['consumption']);
1905
    }
1906
1907
    return $planetResources;
1908
  }
1909
1910
  /**
1911
   */
1912
  public function captainGet() {
1913
    $this->captain = array();
1914
1915
    /**
1916
     * @var unit_captain $moduleCaptain
1917
     */
1918
    if (sn_module::isModuleActive('unit_captain')) {
1919
      $moduleCaptain = sn_module::getModule('unit_captain');
1920
      $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...
1921
    }
1922
  }
1923
1924
  /**
1925
   * @return array
1926
   */
1927
  protected function renderCaptain() {
1928
    $result = array();
1929
1930
    if (!empty($this->captain['unit_id']) && $this->captain['unit_location_type'] == LOC_PLANET) {
1931
      $result = array(
1932
        'CAPTAIN_ID'     => $this->captain['unit_id'],
1933
        'CAPTAIN_LEVEL'  => $this->captain['captain_level'],
1934
        'CAPTAIN_SHIELD' => $this->captain['captain_shield'],
1935
        'CAPTAIN_ARMOR'  => $this->captain['captain_armor'],
1936
        'CAPTAIN_ATTACK' => $this->captain['captain_attack'],
1937
      );
1938
    }
1939
1940
    return $result;
1941
  }
1942
1943
}
1944