Completed
Push — work-fleets ( d40084...46e295 )
by SuperNova.WS
05:22
created

Fleet::populateTargetPlanetAndOwner()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 7
nc 4
nop 0
dl 0
loc 12
ccs 0
cts 7
cp 0
crap 20
rs 9.2
c 1
b 0
f 0
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
   * Fleet constructor.
323
   */
324
  public function __construct() {
325
    parent::__construct();
326
    $this->exists_missions = sn_get_groups('missions');
327
    $this->allowed_missions = $this->exists_missions;
328
    if(empty(static::$snGroupFleet)) {
329
      static::$snGroupFleet = sn_get_groups('fleet');
330
      static::$snGroupFleetAndMissiles = sn_get_groups(array('fleet', 'missile'));
331
      static::$snGroupRecyclers = sn_get_groups('flt_recyclers');
332
    }
333
  }
334
335
  /**
336
   * @param array $template_result
337
   * @param array $playerRow
338
   * @param array $planetRow
339
   */
340
  // TODO - redo to unit/unitlist renderer
341
  public function renderAvailableShips(&$template_result, $playerRow, $planetRow) {
342
    $record_index = 0;
343
    $ship_list = array();
344
    foreach (Fleet::$snGroupFleet as $n => $unit_id) {
345
      $unit_level = mrc_get_level($playerRow, $planetRow, $unit_id, false, true);
346
      if ($unit_level <= 0) {
347
        continue;
348
      }
349
      $ship_data = get_ship_data($unit_id, $playerRow);
350
      $ship_list[$unit_id] = array(
351
        '__INDEX'          => $record_index++,
352
        'ID'               => $unit_id,
353
        'NAME'             => classLocale::$lang['tech'][$unit_id],
354
        'AMOUNT'           => $unit_level,
355
        'AMOUNT_TEXT'      => pretty_number($unit_level),
356
        'CONSUMPTION'      => $ship_data['consumption'],
357
        'CONSUMPTION_TEXT' => pretty_number($ship_data['consumption']),
358
        'SPEED'            => $ship_data['speed'],
359
        'SPEED_TEXT'       => pretty_number($ship_data['speed']),
360
        'CAPACITY'         => $ship_data['capacity'],
361
        'CAPACITY_TEXT'    => pretty_number($ship_data['capacity']),
362
      );
363
    }
364
365
    sortUnitRenderedList($ship_list, classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_SORT], classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_SORT_INVERSE]);
366
367
    foreach ($ship_list as $ship_data) {
368
      $template_result['.']['ships'][] = $ship_data;
369
    }
370
  }
371
372
  public function isEmpty() {
373
    return !$this->resourcesGetTotal() && !$this->shipsGetTotal();
374
  }
375
376
//  public function getPlayerOwnerId() {
0 ignored issues
show
Unused Code Comprehensibility introduced by
48% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
377
//    return $this->playerOwnerId;
378
//  }
379
380
  /**
381
   * Initializes Fleet from user params and posts it to DB
382
   */
383
  public function dbInsert() {
384
    // WARNING! MISSION TIMES MUST BE SET WITH set_times() method!
385
    // TODO - more checks!
386
    if (empty($this->_time_launch)) {
387
      die('Fleet time not set!');
388
    }
389
390
    parent::dbInsert();
391
  }
392
393
394
  /* FLEET DB ACCESS =================================================================================================*/
395
396
  /**
397
   * LOCK - Lock all records which can be used with mission
398
   *
399
   * @param $mission_data
400
   *
401
   * @return array|bool|mysqli_result|null
402
   */
403
  public function dbLockFlying(&$mission_data) {
404
    // Тупо лочим всех юзеров, чьи флоты летят или улетают с координат отбытия/прибытия $fleet_row
405
    // Что бы делать это умно - надо учитывать fleet__mess во $fleet_row и в таблице fleets
406
407
    $fleet_id_safe = idval($this->_dbId);
408
409
    return doquery(
410
    // Блокировка самого флота
411
      "SELECT 1 FROM {{fleets}} AS f " .
412
413
      // Блокировка всех юнитов, принадлежащих этому флоту
414
      "LEFT JOIN {{unit}} as unit ON unit.unit_location_type = " . static::$locationType . " AND unit.unit_location_id = f.fleet_id " .
415
416
      // Блокировка всех прилетающих и улетающих флотов, если нужно
417
      // TODO - lock fleets by COORDINATES
418
      ($mission_data['dst_fleets'] ? "LEFT JOIN {{fleets}} AS fd ON fd.fleet_end_planet_id = f.fleet_end_planet_id OR fd.fleet_start_planet_id = f.fleet_end_planet_id " : '') .
419
      // Блокировка всех юнитов, принадлежащих прилетающим и улетающим флотам - ufd = unit_fleet_destination
420
      ($mission_data['dst_fleets'] ? "LEFT JOIN {{unit}} AS ufd ON ufd.unit_location_type = " . static::$locationType . " AND ufd.unit_location_id = fd.fleet_id " : '') .
421
422
      ($mission_data['dst_user'] || $mission_data['dst_planet'] ? "LEFT JOIN {{users}} AS ud ON ud.id = f.fleet_target_owner " : '') .
423
      // Блокировка всех юнитов, принадлежащих владельцу планеты-цели
424
      ($mission_data['dst_user'] || $mission_data['dst_planet'] ? "LEFT JOIN {{unit}} AS unit_player_dest ON unit_player_dest.unit_player_id = ud.id " : '') .
425
      // Блокировка планеты-цели
426
      ($mission_data['dst_planet'] ? "LEFT JOIN {{planets}} AS pd ON pd.id = f.fleet_end_planet_id " : '') .
427
      // Блокировка всех юнитов, принадлежащих планете-цели - НЕ НУЖНО. Уже залочили ранее, как принадлежащие игроку-цели
428
//      ($mission_data['dst_planet'] ? "LEFT JOIN {{unit}} AS upd ON upd.unit_location_type = " . LOC_PLANET . " AND upd.unit_location_id = pd.id " : '') .
429
430
431
      ($mission_data['src_user'] || $mission_data['src_planet'] ? "LEFT JOIN {{users}} AS us ON us.id = f.fleet_owner " : '') .
432
      // Блокировка всех юнитов, принадлежащих владельцу флота
433
      ($mission_data['src_user'] || $mission_data['src_planet'] ? "LEFT JOIN {{unit}} AS unit_player_src ON unit_player_src.unit_player_id = us.id " : '') .
434
      // Блокировка планеты отправления
435
      ($mission_data['src_planet'] ? "LEFT JOIN {{planets}} AS ps ON ps.id = f.fleet_start_planet_id " : '') .
436
      // Блокировка всех юнитов, принадлежащих планете с которой юниты были отправлены - НЕ НУЖНО. Уже залочили ранее, как принадлежащие владельцу флота
437
//      ($mission_data['src_planet'] ? "LEFT JOIN {{unit}} AS ups ON ups.unit_location_type = " . LOC_PLANET . " AND ups.unit_location_id = ps.id " : '') .
438
439
      "WHERE f.fleet_id = {$fleet_id_safe} GROUP BY 1 FOR UPDATE"
440
    );
441
  }
442
443
  /**
444
   * Lock all fields that belongs to operation
445
   *
446
   * @param $dbId
447
   */
448
  // TODO = make static
449
  public function dbGetLockById($dbId) {
450
    doquery(
451
    // Блокировка самого флота
452
      "SELECT 1 FROM {{fleets}} AS FLEET0 " .
453
      // Lock fleet owner
454
      "LEFT JOIN {{users}} as USER0 on USER0.id = FLEET0.fleet_owner " .
455
      // Блокировка всех юнитов, принадлежащих этому флоту
456
      "LEFT JOIN {{unit}} as UNIT0 ON UNIT0.unit_location_type = " . LOC_FLEET . " AND UNIT0.unit_location_id = FLEET0.fleet_id " .
457
458
      // Без предварительной выборки неизвестно - куда летит этот флот.
459
      // Поэтому надо выбирать флоты, чьи координаты прибытия ИЛИ отбытия совпадают с координатами прибытия ИЛИ отбытия текущего флота.
460
      // Получаем матрицу 2х2 - т.е. 4 подзапроса.
461
      // При блокировке всегда нужно выбирать И лпанету, И луну - поскольку при бое на орбите луны обломки падают на орбиту планеты.
462
      // Поэтому тип планеты не указывается
463
464
      // Lock fleet heading to destination planet. Only if FLEET0.fleet_mess == 0
465
      "LEFT JOIN {{fleets}} AS FLEET1 ON
466
        FLEET1.fleet_mess = 0 AND FLEET0.fleet_mess = 0 AND
467
        FLEET1.fleet_end_galaxy = FLEET0.fleet_end_galaxy AND
468
        FLEET1.fleet_end_system = FLEET0.fleet_end_system AND
469
        FLEET1.fleet_end_planet = FLEET0.fleet_end_planet
470
      " .
471
      // Блокировка всех юнитов, принадлежащих этим флотам
472
      "LEFT JOIN {{unit}} as UNIT1 ON UNIT1.unit_location_type = " . LOC_FLEET . " AND UNIT1.unit_location_id = FLEET1.fleet_id " .
473
      // Lock fleet owner
474
      "LEFT JOIN {{users}} as USER1 on USER1.id = FLEET1.fleet_owner " .
475
476
      "LEFT JOIN {{fleets}} AS FLEET2 ON
477
        FLEET2.fleet_mess = 1   AND FLEET0.fleet_mess = 0 AND
478
        FLEET2.fleet_start_galaxy = FLEET0.fleet_end_galaxy AND
479
        FLEET2.fleet_start_system = FLEET0.fleet_end_system AND
480
        FLEET2.fleet_start_planet = FLEET0.fleet_end_planet
481
      " .
482
      // Блокировка всех юнитов, принадлежащих этим флотам
483
      "LEFT JOIN {{unit}} as UNIT2 ON
484
        UNIT2.unit_location_type = " . LOC_FLEET . " AND
485
        UNIT2.unit_location_id = FLEET2.fleet_id
486
      " .
487
      // Lock fleet owner
488
      "LEFT JOIN {{users}} as USER2 on
489
        USER2.id = FLEET2.fleet_owner
490
      " .
491
492
      // Lock fleet heading to source planet. Only if FLEET0.fleet_mess == 1
493
      "LEFT JOIN {{fleets}} AS FLEET3 ON
494
        FLEET3.fleet_mess = 0 AND FLEET0.fleet_mess = 1 AND
495
        FLEET3.fleet_end_galaxy = FLEET0.fleet_start_galaxy AND
496
        FLEET3.fleet_end_system = FLEET0.fleet_start_system AND
497
        FLEET3.fleet_end_planet = FLEET0.fleet_start_planet
498
      " .
499
      // Блокировка всех юнитов, принадлежащих этим флотам
500
      "LEFT JOIN {{unit}} as UNIT3 ON
501
        UNIT3.unit_location_type = " . LOC_FLEET . " AND
502
        UNIT3.unit_location_id = FLEET3.fleet_id
503
      " .
504
      // Lock fleet owner
505
      "LEFT JOIN {{users}} as USER3 on USER3.id = FLEET3.fleet_owner " .
506
507
      "LEFT JOIN {{fleets}} AS FLEET4 ON
508
        FLEET4.fleet_mess = 1   AND FLEET0.fleet_mess = 1 AND
509
        FLEET4.fleet_start_galaxy = FLEET0.fleet_start_galaxy AND
510
        FLEET4.fleet_start_system = FLEET0.fleet_start_system AND
511
        FLEET4.fleet_start_planet = FLEET0.fleet_start_planet
512
      " .
513
      // Блокировка всех юнитов, принадлежащих этим флотам
514
      "LEFT JOIN {{unit}} as UNIT4 ON
515
        UNIT4.unit_location_type = " . LOC_FLEET . " AND
516
        UNIT4.unit_location_id = FLEET4.fleet_id
517
      " .
518
      // Lock fleet owner
519
      "LEFT JOIN {{users}} as USER4 on
520
        USER4.id = FLEET4.fleet_owner
521
      " .
522
523
524
      // Locking start planet
525
      "LEFT JOIN {{planets}} AS PLANETS5 ON
526
        FLEET0.fleet_mess = 1 AND
527
        PLANETS5.galaxy = FLEET0.fleet_start_galaxy AND
528
        PLANETS5.system = FLEET0.fleet_start_system AND
529
        PLANETS5.planet = FLEET0.fleet_start_planet
530
      " .
531
      // Lock planet owner
532
      "LEFT JOIN {{users}} as USER5 on
533
        USER5.id = PLANETS5.id_owner
534
      " .
535
      // Блокировка всех юнитов, принадлежащих этой планете
536
      "LEFT JOIN {{unit}} as UNIT5 ON
537
        UNIT5.unit_location_type = " . LOC_PLANET . " AND
538
        UNIT5.unit_location_id = PLANETS5.id
539
      " .
540
541
542
      // Locking destination planet
543
      "LEFT JOIN {{planets}} AS PLANETS6 ON
544
        FLEET0.fleet_mess = 0 AND
545
        PLANETS6.galaxy = FLEET0.fleet_end_galaxy AND
546
        PLANETS6.system = FLEET0.fleet_end_system AND
547
        PLANETS6.planet = FLEET0.fleet_end_planet
548
      " .
549
      // Lock planet owner
550
      "LEFT JOIN {{users}} as USER6 on
551
        USER6.id = PLANETS6.id_owner
552
      " .
553
      // Блокировка всех юнитов, принадлежащих этой планете
554
      "LEFT JOIN {{unit}} as UNIT6 ON
555
        UNIT6.unit_location_type = " . LOC_PLANET . " AND
556
        UNIT6.unit_location_id = PLANETS6.id
557
      " .
558
      "WHERE FLEET0.fleet_id = {$dbId} GROUP BY 1 FOR UPDATE"
559
    );
560
  }
561
562
563
  public function dbRowParse($db_row) {
564
    parent::dbRowParse($db_row); // TODO: Change the autogenerated stub
565
    $player = new Player();
566
    $player->dbLoad($db_row['fleet_owner']);
567
    $this->setLocatedAt($player);
568
  }
569
570
  /* FLEET HELPERS =====================================================================================================*/
571
  /**
572
   * Forcibly returns fleet before time outs
573
   */
574
  public function commandReturn() {
575
    $ReturnFlyingTime = ($this->_time_mission_job_complete != 0 && $this->_time_arrive_to_target < SN_TIME_NOW ? $this->_time_arrive_to_target : SN_TIME_NOW) - $this->_time_launch + SN_TIME_NOW + 1;
576
577
    $this->markReturned();
578
579
    // Считаем, что флот уже долетел TODO
580
    $this->time_arrive_to_target = SN_TIME_NOW;
581
    // Убираем флот из группы
582
    $this->group_id = 0;
583
    // Отменяем работу в точке назначения
584
    $this->time_mission_job_complete = 0;
585
    // TODO - правильно вычслять время возвращения - по проделанному пути, а не по старому времени возвращения
586
    $this->time_return_to_source = $ReturnFlyingTime;
587
588
    // Записываем изменения в БД
589
    $this->dbSave();
590
591
    if ($this->_group_id) {
592
      // TODO: Make here to delete only one AKS - by adding aks_fleet_count to AKS table
593
      DBStaticFleetACS::db_fleet_aks_purge();
594
    }
595
  }
596
597
598
  /**
599
   * @return array
600
   */
601
  public function target_coordinates_without_type() {
602
    return array(
603
      'galaxy' => $this->_fleet_end_galaxy,
604
      'system' => $this->_fleet_end_system,
605
      'planet' => $this->_fleet_end_planet,
606
    );
607
  }
608
609
  /**
610
   * @return array
611
   */
612
  public function target_coordinates_typed() {
613
    return array(
614
      'galaxy' => $this->_fleet_end_galaxy,
615
      'system' => $this->_fleet_end_system,
616
      'planet' => $this->_fleet_end_planet,
617
      'type'   => $this->_fleet_end_type,
618
    );
619
  }
620
621
  /**
622
   * @return array
623
   */
624
  public function launch_coordinates_typed() {
625
    return array(
626
      'galaxy' => $this->_fleet_start_galaxy,
627
      'system' => $this->_fleet_start_system,
628
      'planet' => $this->_fleet_start_planet,
629
      'type'   => $this->_fleet_start_type,
630
    );
631
  }
632
633
634
  /**
635
   * Sets object fields for fleet return
636
   */
637
  public function markReturned() {
638
    // TODO - Проверка - а не возвращается ли уже флот?
639
    $this->is_returning = 1;
640
  }
641
642
  public function isReturning() {
643
    return 1 == $this->_is_returning;
644
  }
645
646
  public function markReturnedAndSave() {
647
    $this->markReturned();
648
    $this->dbSave();
649
  }
650
651
  /**
652
   * Parses extended unit_array which can include not only ships but resources, captains etc
653
   *
654
   * @param $unit_array
655
   *
656
   * @throws Exception
657
   */
658
  // TODO - separate shipList and unitList
659
  public function unitsSetFromArray($unit_array) {
660
    if (empty($unit_array) || !is_array($unit_array)) {
661
      return;
662
    }
663
    foreach ($unit_array as $unit_id => $unit_count) {
664
      $unit_count = floatval($unit_count);
665
      if (!$unit_count) {
666
        continue;
667
      }
668
669
      if ($this->isShip($unit_id)) {
670
        $this->unitList->unitSetCount($unit_id, $unit_count);
671
      } elseif ($this->isResource($unit_id)) {
672
        $this->resource_list[$unit_id] = $unit_count;
673
      } else {
674
        throw new Exception('Trying to pass to fleet non-resource and non-ship ' . var_export($unit_array, true), ERR_ERROR);
675
      }
676
    }
677
  }
678
679
680
  /**
681
   * Sets fleet timers based on flight duration, time on mission (HOLD/EXPLORE) and fleet departure time.
682
   *
683
   * @param int $time_to_travel - flight duration in seconds
684
   * @param int $time_on_mission - time on mission in seconds
685
   * @param int $flight_departure - fleet departure from source planet timestamp. Allows to send fleet in future or in past
686
   */
687
  public function set_times($time_to_travel, $time_on_mission = 0, $flight_departure = SN_TIME_NOW) {
688
    $this->_time_launch = $flight_departure;
689
690
    $this->_time_arrive_to_target = $this->_time_launch + $time_to_travel;
691
    $this->_time_mission_job_complete = $time_on_mission ? $this->_time_arrive_to_target + $time_on_mission : 0;
692
    $this->_time_return_to_source = ($this->_time_mission_job_complete ? $this->_time_mission_job_complete : $this->_time_arrive_to_target) + $time_to_travel;
693
  }
694
695
696
  public function parse_missile_db_row($missile_db_row) {
697
//    $this->_reset();
0 ignored issues
show
Unused Code Comprehensibility introduced by
72% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
698
699
    if (empty($missile_db_row) || !is_array($missile_db_row)) {
700
      return;
701
    }
702
703
//      $planet_start = db_planet_by_vector($irak_original, 'fleet_start_', false, 'name');
0 ignored issues
show
Unused Code Comprehensibility introduced by
61% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
704
//      $irak_original['fleet_start_name'] = $planet_start['name'];
705
    $this->missile_target = $missile_db_row['primaer'];
706
707
    $this->_dbId = -$missile_db_row['id'];
708
    $this->_playerOwnerId = $missile_db_row['fleet_owner'];
709
    $this->_mission_type = MT_MISSILE;
710
711
    $this->_target_owner_id = $missile_db_row['fleet_target_owner'];
712
713
    $this->_group_id = 0;
714
    $this->_is_returning = 0;
715
716
    $this->_time_launch = 0; // $irak['start_time'];
0 ignored issues
show
Unused Code Comprehensibility introduced by
84% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
717
    $this->_time_arrive_to_target = 0; // $irak['fleet_start_time'];
0 ignored issues
show
Unused Code Comprehensibility introduced by
84% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
718
    $this->_time_mission_job_complete = 0; // $irak['fleet_end_stay'];
0 ignored issues
show
Unused Code Comprehensibility introduced by
84% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
719
    $this->_time_return_to_source = $missile_db_row['fleet_end_time'];
720
721
    $this->_fleet_start_planet_id = !empty($missile_db_row['fleet_start_planet_id']) ? $missile_db_row['fleet_start_planet_id'] : null;
722
    $this->_fleet_start_galaxy = $missile_db_row['fleet_start_galaxy'];
723
    $this->_fleet_start_system = $missile_db_row['fleet_start_system'];
724
    $this->_fleet_start_planet = $missile_db_row['fleet_start_planet'];
725
    $this->_fleet_start_type = $missile_db_row['fleet_start_type'];
726
727
    $this->_fleet_end_planet_id = !empty($missile_db_row['fleet_end_planet_id']) ? $missile_db_row['fleet_end_planet_id'] : null;
728
    $this->_fleet_end_galaxy = $missile_db_row['fleet_end_galaxy'];
729
    $this->_fleet_end_system = $missile_db_row['fleet_end_system'];
730
    $this->_fleet_end_planet = $missile_db_row['fleet_end_planet'];
731
    $this->_fleet_end_type = $missile_db_row['fleet_end_type'];
732
733
    $this->unitList->unitSetCount(UNIT_DEF_MISSILE_INTERPLANET, $missile_db_row['fleet_amount']);
734
  }
735
736
737
  /**
738
   * @param $from
739
   */
740
  public function set_start_planet($from) {
741
    $this->fleet_start_planet_id = intval($from['id']) ? $from['id'] : null;
742
    $this->fleet_start_galaxy = $from['galaxy'];
743
    $this->fleet_start_system = $from['system'];
744
    $this->fleet_start_planet = $from['planet'];
745
    $this->fleet_start_type = $from['planet_type'];
746
  }
747
748
  /**
749
   * @param $to
750
   */
751
  public function set_end_planet($to) {
752
    $this->target_owner_id = intval($to['id_owner']) ? $to['id_owner'] : 0;
753
    $this->fleet_end_planet_id = intval($to['id']) ? $to['id'] : null;
754
    $this->fleet_end_galaxy = $to['galaxy'];
755
    $this->fleet_end_system = $to['system'];
756
    $this->fleet_end_planet = $to['planet'];
757
    $this->fleet_end_type = $to['planet_type'];
758
  }
759
760
  /**
761
   * @param Vector $to
762
   */
763
  public function setTargetFromVectorObject($to) {
764
    $this->_fleet_end_galaxy = $to->galaxy;
765
    $this->_fleet_end_system = $to->system;
766
    $this->_fleet_end_planet = $to->planet;
767
    $this->_fleet_end_type = $to->type;
768
  }
769
770
  /**
771
   * @param array $db_row
772
   */
773
  protected function ownerExtract(array &$db_row) {
774
    $player = new Player();
775
    $player->dbLoad($db_row['fleet_owner']);
776
    $this->setLocatedAt($player);
777
  }
778
779
  /**
780
   * @param array $db_row
781
   */
782
  protected function ownerInject(array &$db_row) {
783
    $db_row['fleet_owner'] = $this->getPlayerOwnerId();
784
  }
785
786
787
788
789
  // UnitList/Ships access ***************************************************************************************************
790
791
  // TODO - перекрывать пожже - для миссайл-флотов и дефенс-флотов
792
  protected function isShip($unit_id) {
793
    return UnitShip::is_in_group($unit_id);
794
  }
795
796
  /**
797
   * Set unit count of $unit_id to $unit_count
798
   * If there is no $unit_id - it will be created and saved to DB on dbSave
799
   *
800
   * @param int $unit_id
801
   * @param int $unit_count
802
   */
803
  public function shipSetCount($unit_id, $unit_count = 0) {
804
pdump(__CLASS__ . '->' . __FUNCTION__);
805
    $this->shipAdjustCount($unit_id, $unit_count, true);
806
  }
807
808
  /**
809
   * Adjust unit count of $unit_id by $unit_count - or just replace value
810
   * If there is no $unit_id - it will be created and saved to DB on dbSave
811
   *
812
   * @param int  $unit_id
813
   * @param int  $unit_count
814
   * @param bool $replace_value
815
   */
816
  public function shipAdjustCount($unit_id, $unit_count = 0, $replace_value = false) {
817
    $this->unitList->unitAdjustCount($unit_id, $unit_count, $replace_value);
818
  }
819
820
  public function shipGetCount($unit_id) {
821
    return $this->unitList->unitGetCount($unit_id);
822
  }
823
824
  public function shipsCountApplyLossMultiplier($ships_lost_multiplier) {
825
    $this->unitList->unitsCountApplyLossMultiplier($ships_lost_multiplier);
826
  }
827
828
  /**
829
   * Returns fleet ships cost in metal
830
   *
831
   * @param array $shipCostInMetalPerPiece
832
   *
833
   * @return float[]
834
   */
835
  public function shipsCostInMetal($shipCostInMetalPerPiece) {
836
    return $this->unitList->unitsCostInMetal($shipCostInMetalPerPiece);
837
  }
838
839
  /**
840
   * @return UnitIterator
841
   */
842
  public function shipsIterator() {
843
    return $this->unitList->getUnitIterator();
844
  }
845
846
  public function shipsGetTotal() {
847
    return $this->unitList->unitsCount();
848
  }
849
850
  public function shipsGetCapacity() {
851
    return $this->unitList->shipsCapacity();
852
  }
853
854
  public function shipsGetHoldFree() {
855
    return max(0, $this->shipsGetCapacity() - $this->resourcesGetTotal());
856
  }
857
858
  /**
859
   * Get count of ships with $ship_id
860
   *
861
   * @param int $ship_id
862
   *
863
   * @return int
864
   */
865
  public function shipsGetTotalById($ship_id) {
866
    return $this->unitList->unitsCountById($ship_id);
867
  }
868
869
  /**
870
   * Возвращает ёмкость переработчиков во флоте
871
   *
872
   * @param array $recycler_info
873
   *
874
   * @return int
875
   *
876
   * @version 41a50.30
877
   */
878
  public function shipsGetCapacityRecyclers($recycler_info) {
879
    $recyclers_incoming_capacity = 0;
880
    foreach($this->shipsIterator() as $unitId => $unit) {
881
      if(!empty(static::$snGroupRecyclers[$unitId]) && $unit->count >= 1) {
882
        $recyclers_incoming_capacity += $unit->count * $recycler_info[$unitId]['capacity'];
883
      }
884
    }
885
886
    return $recyclers_incoming_capacity;
887
  }
888
889
  /**
890
   * @return bool
891
   */
892
  // TODO - А если не на планете????
893
  public function shipsIsEnoughOnPlanet() {
894
    return $this->unitList->shipsIsEnoughOnPlanet($this->dbOwnerRow, $this->dbSourcePlanetRow);
895
  }
896
897
  /**
898
   * @return bool
899
   */
900
  public function shipsAllPositive() {
901
    return $this->unitList->unitsPositive();
902
  }
903
904
  /**
905
   * @return bool
906
   */
907
  public function shipsAllFlying() {
908
    return $this->unitList->unitsInGroup(static::$snGroupFleetAndMissiles);
909
  }
910
911
  /**
912
   * @return bool
913
   */
914
  public function shipsAllMovable() {
915
    return $this->unitList->unitsIsAllMovable($this->dbOwnerRow);
916
  }
917
918
  /**
919
   * Restores fleet or resources to planet
920
   *
921
   * @param bool $start
922
   * @param int  $result
923
   *
924
   * @return int
925
   */
926
  // TODO - split to functions
927
  public function shipsLand($start = true, &$result = CACHE_NOTHING) {
928
    sn_db_transaction_check(true);
929
930
    // Если флот уже обработан - не существует или возращается - тогда ничего не делаем
931
    if ($this->isEmpty()) {
932
      return $result;
933
    }
934
935
    $coordinates = $start ? $this->launch_coordinates_typed() : $this->target_coordinates_typed();
936
937
    // Поскольку эта функция может быть вызвана не из обработчика флотов - нам надо всё заблокировать вроде бы НЕ МОЖЕТ!!!
938
    // TODO Проверить от многократного срабатывания !!!
939
    // Тут не блокируем пока - сначала надо заблокировать пользователя, что бы не было дедлока
940
    // TODO поменять на владельца планеты - когда его будут возвращать всегда !!!
941
942
    // Узнаем ИД владельца планеты.
943
    // С блокировкой, поскольку эта функция может быть вызвана только из менеджера летящих флотов.
944
    // А там уже всё заблокировано как надо и повторная блокировка не вызовет дедлок.
945
    $planet_arrival = DBStaticPlanet::db_planet_by_vector($coordinates, '', true);
946
    // Блокируем пользователя
947
    // TODO - вообще-то нам уже известен пользователь в МЛФ - так что можно просто передать его сюда
948
    $user = DBStaticUser::db_user_by_id($planet_arrival['id_owner'], true);
949
950
    // TODO - Проверка, что планета всё еще существует на указанных координатах, а не телепортировалась, не удалена хозяином, не уничтожена врагом
951
    // Флот, который возвращается на захваченную планету, пропадает
952
    // Ship landing is possible only to fleet owner's planet
953
    if ($this->getPlayerOwnerId() == $planet_arrival['id_owner']) {
954
      $db_changeset = array();
955
956
      foreach ($this->shipsIterator() as $ship_id => $ship) {
957
        if ($ship->count) {
958
          $db_changeset['unit'][] = sn_db_unit_changeset_prepare($ship_id, $ship->count, $user, $planet_arrival['id']);
959
        }
960
      }
961
962
      // Adjusting ship amount on planet
963
      if (!empty($db_changeset)) {
964
        db_changeset_apply($db_changeset);
965
      }
966
967
      // Restoring resources to planet
968
      $this->resourcesUnload($start, $result);
969
    }
970
971
    $result = CACHE_FLEET | ($start ? CACHE_PLANET_SRC : CACHE_PLANET_DST);
972
973
    $result = RestoreFleetToPlanet($this, $start, $result);
974
975
    $this->dbDelete();
976
977
    return $result;
978
  }
979
980
981
  // Resources access ***************************************************************************************************
982
983
  /**
984
   * Extracts resources value from db_row
985
   *
986
   * @param array $db_row
987
   *
988
   * @internal param Fleet $that
989
   * @version 41a50.30
990
   */
991
  protected function resourcesExtract(array &$db_row) {
992
    $this->resource_list = array(
993
      RES_METAL     => !empty($db_row['fleet_resource_metal']) ? floor($db_row['fleet_resource_metal']) : 0,
994
      RES_CRYSTAL   => !empty($db_row['fleet_resource_crystal']) ? floor($db_row['fleet_resource_crystal']) : 0,
995
      RES_DEUTERIUM => !empty($db_row['fleet_resource_deuterium']) ? floor($db_row['fleet_resource_deuterium']) : 0,
996
    );
997
  }
998
999
  protected function resourcesInject(array &$db_row) {
1000
    $db_row['fleet_resource_metal'] = $this->resource_list[RES_METAL];
1001
    $db_row['fleet_resource_crystal'] = $this->resource_list[RES_CRYSTAL];
1002
    $db_row['fleet_resource_deuterium'] = $this->resource_list[RES_DEUTERIUM];
1003
  }
1004
1005
  /**
1006
   * Set current resource list from array of units
1007
   *
1008
   * @param array $resource_list
1009
   */
1010
  public function resourcesSet($resource_list) {
1011
    if (!empty($this->propertiesAdjusted['resource_list'])) {
1012
      throw new PropertyAccessException('Property "resource_list" already was adjusted so no SET is possible until dbSave in ' . get_called_class() . '::unitSetResourceList', ERR_ERROR);
1013
    }
1014
    $this->resourcesAdjust($resource_list, true);
1015
  }
1016
1017
  /**
1018
   * Updates fleet resource list with deltas
1019
   *
1020
   * @param array $resource_delta_list
1021
   * @param bool  $replace_value
1022
   *
1023
   * @throws Exception
1024
   */
1025
  public function resourcesAdjust($resource_delta_list, $replace_value = false) {
1026
    !is_array($resource_delta_list) ? $resource_delta_list = array() : false;
1027
1028
    foreach ($resource_delta_list as $resource_id => $unit_delta) {
1029
      if (!UnitResourceLoot::is_in_group($resource_id) || !($unit_delta = floor($unit_delta))) {
1030
        // Not a resource or no resources - continuing
1031
        continue;
1032
      }
1033
1034
      if ($replace_value) {
1035
        $this->resource_list[$resource_id] = $unit_delta;
1036
      } else {
1037
        $this->resource_list[$resource_id] += $unit_delta;
1038
        // Preparing changes
1039
        $this->resource_delta[$resource_id] += $unit_delta;
1040
        $this->propertiesAdjusted['resource_list'] = 1;
1041
      }
1042
1043
      // Check for negative unit value
1044
      if ($this->resource_list[$resource_id] < 0) {
1045
        // TODO
1046
        throw new Exception('Resource ' . $resource_id . ' will become negative in ' . get_called_class() . '::unitAdjustResourceList', ERR_ERROR);
1047
      }
1048
    }
1049
  }
1050
1051
  public function resourcesGetTotal() {
1052
    return empty($this->resource_list) || !is_array($this->resource_list) ? 0 : array_sum($this->resource_list);
1053
  }
1054
1055
  /**
1056
   * @param array $rate
1057
   *
1058
   * @return float
1059
   */
1060
  public function resourcesGetTotalInMetal(array $rate) {
1061
    return
1062
      $this->resource_list[RES_METAL] * $rate[RES_METAL]
1063
      + $this->resource_list[RES_CRYSTAL] * $rate[RES_CRYSTAL] / $rate[RES_METAL]
1064
      + $this->resource_list[RES_DEUTERIUM] * $rate[RES_DEUTERIUM] / $rate[RES_METAL];
1065
  }
1066
1067
  /**
1068
   * Returns resource list in fleet
1069
   */
1070
  // TODO
1071
  public function resourcesGetList() {
1072
    return $this->resource_list;
1073
  }
1074
1075
  public function resourcesReset() {
1076
    $this->resourcesSet(array(
1077
      RES_METAL     => 0,
1078
      RES_CRYSTAL   => 0,
1079
      RES_DEUTERIUM => 0,
1080
    ));
1081
  }
1082
1083
  /**
1084
   * Restores fleet or resources to planet
1085
   *
1086
   * @param bool $start
1087
   * @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...
1088
   * @param int  $result
1089
   *
1090
   * @return int
1091
   */
1092
  public function resourcesUnload($start = true, &$result = CACHE_NOTHING) {
1093
    sn_db_transaction_check(true);
1094
1095
    // Если флот уже обработан - не существует или возращается - тогда ничего не делаем
1096
    if (!$this->resourcesGetTotal()) {
1097
      return $result;
1098
    }
1099
1100
    $coordinates = $start ? $this->launch_coordinates_typed() : $this->target_coordinates_typed();
1101
1102
    // Поскольку эта функция может быть вызвана не из обработчика флотов - нам надо всё заблокировать вроде бы НЕ МОЖЕТ!!!
1103
    // TODO Проверить от многократного срабатывания !!!
1104
    // Тут не блокируем пока - сначала надо заблокировать пользователя, что бы не было дедлока
1105
    // TODO поменять на владельца планеты - когда его будут возвращать всегда !!!
1106
1107
1108
    // Узнаем ИД владельца планеты.
1109
    // С блокировкой, поскольку эта функция может быть вызвана только из менеджера летящих флотов.
1110
    // А там уже всё заблокировано как надо и повторная блокировка не вызовет дедлок.
1111
    $planet_arrival = DBStaticPlanet::db_planet_by_vector($coordinates, '', true);
1112
1113
    // TODO - Проверка, что планета всё еще существует на указанных координатах, а не телепортировалась, не удалена хозяином, не уничтожена врагом
1114
1115
    // Restoring resources to planet
1116
    if ($this->resourcesGetTotal()) {
1117
      $fleet_resources = $this->resourcesGetList();
1118
      DBStaticPlanet::db_planet_set_by_id($planet_arrival['id'],
1119
        "`metal` = `metal` + '{$fleet_resources[RES_METAL]}', `crystal` = `crystal` + '{$fleet_resources[RES_CRYSTAL]}', `deuterium` = `deuterium` + '{$fleet_resources[RES_DEUTERIUM]}'");
1120
    }
1121
1122
    $this->resourcesReset();
1123
    $this->markReturned();
1124
1125
    $result = CACHE_FLEET | ($start ? CACHE_PLANET_SRC : CACHE_PLANET_DST);
1126
1127
    return $result;
1128
  }
1129
1130
1131
  protected function isResource($unit_id) {
1132
    return UnitResourceLoot::is_in_group($unit_id);
1133
  }
1134
1135
  /**
1136
   * @param int $speed_percent
1137
   *
1138
   * @return array
1139
   */
1140
  protected function flt_travel_data($speed_percent = 10) {
1141
    $distance = $this->targetVector->distanceFromCoordinates($this->dbSourcePlanetRow);
1142
1143
    return $this->unitList->travelData($speed_percent, $distance, $this->dbOwnerRow);
1144
  }
1145
1146
1147
  /**
1148
   * @param array  $dbPlayerRow
1149
   * @param array  $dbPlanetRow
1150
   * @param Vector $targetVector
1151
   *
1152
   */
1153
  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...
1154
    $objFleet5Player = new Player();
1155
    $objFleet5Player->dbRowParse($dbPlayerRow);
1156
    $this->setLocatedAt($objFleet5Player);
1157
1158
    $this->mission_type = $mission;
1159
1160
    $this->dbOwnerRow = $dbPlayerRow;
1161
1162
    $this->set_start_planet($dbPlanetRow);
1163
    $this->dbSourcePlanetRow = $dbPlanetRow;
1164
1165
    $this->setTargetFromVectorObject($targetVector);
1166
    $this->targetVector = $targetVector;
1167
1168
//    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...
1169
//      $this->restrictTargetTypeByMission();
1170
//
1171
//      // TODO - Нельзя тут просто менять тип планеты или координат!
1172
//      // If current planet type is not allowed on mission - switch planet type
1173
//      if (empty($this->allowed_planet_types[$this->targetVector->type])) {
1174
//        $targetPlanetCoords->type = reset($this->allowed_planet_types);
1175
//      }
1176
//    }
1177
1178
    $this->populateTargetPlanetAndOwner();
1179
1180
    $this->unitsSetFromArray($ships);
1181
1182
    $this->_group_id = intval($fleet_group_mr);
1183
1184
    $this->oldSpeedInTens = $oldSpeedInTens;
1185
1186
    $this->targetedUnitId = $targetedUnitId;
1187
1188
    $this->captainId = $captainId;
1189
1190
    $this->_time_launch = SN_TIME_NOW;
1191
1192
    $this->renderParamCoordinates();
1193
1194
  }
1195
1196
  protected function restrictTargetTypeByMission() {
1197
    if ($this->_mission_type == MT_MISSILE) {
1198
      $this->allowed_planet_types = array(PT_PLANET => PT_PLANET);
1199
    } elseif ($this->_mission_type == MT_COLONIZE || $this->_mission_type == MT_EXPLORE) {
1200
      // TODO - PT_NONE
1201
      $this->allowed_planet_types = array(PT_PLANET => PT_PLANET);
1202
    } elseif ($this->_mission_type == MT_RECYCLE) {
1203
      $this->allowed_planet_types = array(PT_DEBRIS => PT_DEBRIS);
1204
    } elseif ($this->_mission_type == MT_DESTROY) {
1205
      $this->allowed_planet_types = array(PT_MOON => PT_MOON);
1206
    } else {
1207
      $this->allowed_planet_types = array(PT_PLANET => PT_PLANET, PT_MOON => PT_MOON);
1208
    }
1209
  }
1210
1211
  protected function populateTargetPlanetAndOwner() {
1212
    // If vector points to no exact object OR debris - then getting planet on coordinates
1213
    $targetVector = clone $this->targetVector;
1214
    if($targetVector->type == PT_DEBRIS || $targetVector == PT_NONE) {
1215
      $targetVector->type = PT_PLANET;
1216
    }
1217
1218
    $this->dbTargetRow = DBStaticPlanet::db_planet_by_vector_object($targetVector);
1219
    if (!empty($this->dbTargetRow['id_owner'])) {
1220
      $this->dbTargetOwnerRow = DBStaticUser::getRecordById($this->dbTargetRow['id_owner'], '*', true);
1221
    }
1222
  }
1223
1224
1225
  protected function printErrorIfNoShips() {
1226
    if ($this->unitList->unitsCount() <= 0) {
1227
      message(classLocale::$lang['fl_err_no_ships'], classLocale::$lang['fl_error'], 'fleet' . DOT_PHP_EX, 5);
1228
    }
1229
  }
1230
1231
  /**
1232
   */
1233
  public function renderParamCoordinates() {
1234
    global $template_result;
1235
    $template_result += array(
1236
      'thisgalaxy'      => $this->dbSourcePlanetRow['galaxy'],
1237
      'thissystem'      => $this->dbSourcePlanetRow['system'],
1238
      'thisplanet'      => $this->dbSourcePlanetRow['planet'],
1239
      'thisplanet_type' => $this->dbSourcePlanetRow['planet_type'],
1240
1241
      'galaxy'         => $this->targetVector->galaxy,
1242
      'system'         => $this->targetVector->system,
1243
      'planet'         => $this->targetVector->planet,
1244
      'planet_type'    => $this->targetVector->type,
1245
      'target_mission' => $this->_mission_type,
1246
      'MISSION_NAME'   => $this->_mission_type ? classLocale::$lang['type_mission'][$this->_mission_type] : '',
1247
1248
      'MT_COLONIZE' => MT_COLONIZE,
1249
    );
1250
  }
1251
1252
1253
  protected function renderFleetCoordinates($missionStartTimeStamp = SN_TIME_NOW, $timeMissionJob = 0) {
1254
    $timeToReturn = $this->travelData['duration'] * 2 + $timeMissionJob;
1255
1256
    return array(
1257
      'ID'                 => 1,
1258
      'START_TYPE_TEXT_SH' => classLocale::$lang['sys_planet_type_sh'][$this->dbSourcePlanetRow['planet_type']],
1259
      'START_COORDS'       => uni_render_coordinates($this->dbSourcePlanetRow),
1260
      'START_NAME'         => $this->dbSourcePlanetRow['name'],
1261
      'START_TIME_TEXT'    => date(FMT_DATE_TIME, $missionStartTimeStamp + $timeToReturn + SN_CLIENT_TIME_DIFF),
1262
      'START_LEFT'         => floor($timeToReturn),
1263
      'END_TYPE_TEXT_SH'   =>
1264
        !empty($this->targetVector->type)
1265
          ? classLocale::$lang['sys_planet_type_sh'][$this->targetVector->type]
1266
          : '',
1267
      'END_COORDS'         => uniRenderVector($this->targetVector),
1268
      'END_NAME'           => !empty($this->dbTargetRow['name']) ? $this->dbTargetRow['name'] : '',
1269
      'END_TIME_TEXT'      => date(FMT_DATE_TIME, $missionStartTimeStamp + $this->travelData['duration'] + SN_CLIENT_TIME_DIFF),
1270
      'END_LEFT'           => floor($this->travelData['duration']),
1271
    );
1272
  }
1273
1274
  /**
1275
   * @param int $missionStartTimeStamp
1276
   * @param int $timeMissionJob
1277
   *
1278
   * @return array
1279
   *
1280
   * @throws Exception
1281
   */
1282
  protected function renderFleet($missionStartTimeStamp = SN_TIME_NOW, $timeMissionJob = 0) {
1283
    $this->printErrorIfNoShips();
1284
1285
    $result = $this->renderFleetCoordinates($missionStartTimeStamp, $timeMissionJob);
1286
    $result['.']['ships'] = $this->unitList->unitsRender();
1287
1288
    return $result;
1289
  }
1290
1291
  /**
1292
   * @return array
1293
   */
1294
  protected function renderAllowedMissions() {
1295
    $result = array();
1296
1297
    ksort($this->allowed_missions);
1298
    // If mission is not set - setting first mission from allowed
1299
    if (empty($this->_mission_type) && is_array($this->allowed_missions)) {
1300
      reset($this->allowed_missions);
1301
      $this->_mission_type = key($this->allowed_missions);
1302
    }
1303
    foreach ($this->allowed_missions as $key => $value) {
1304
      $result[] = array(
1305
        'ID'   => $key,
1306
        'NAME' => classLocale::$lang['type_mission'][$key],
1307
      );
1308
    };
1309
1310
    return $result;
1311
  }
1312
1313
  /**
1314
   * @param $max_duration
1315
   *
1316
   * @return array
1317
   */
1318
  protected function renderDuration($max_duration) {
1319
    $result = array();
1320
1321
    if (!$max_duration) {
1322
      return $result;
1323
    }
1324
1325
    $config_game_speed_expedition = ($this->_mission_type == MT_EXPLORE && classSupernova::$config->game_speed_expedition ? classSupernova::$config->game_speed_expedition : 1);
1326
    for ($i = 1; $i <= $max_duration; $i++) {
1327
      $result[] = array(
1328
        'ID'   => $i,
1329
        'TIME' => pretty_time(ceil($i * 3600 / $config_game_speed_expedition)),
1330
      );
1331
    }
1332
1333
    return $result;
1334
  }
1335
1336
  /**
1337
   * @param array $planetResources
1338
   *
1339
   * @return array
1340
   */
1341
  // TODO - REDO to resource_id
1342
  protected function renderPlanetResources(&$planetResources) {
1343
    $result = array();
1344
1345
    $i = 0;
1346
    foreach ($planetResources as $resource_id => $resource_amount) {
1347
      $result[] = array(
1348
        'ID'        => $i++, // $resource_id,
1349
        'ON_PLANET' => $resource_amount,
1350
        'TEXT'      => pretty_number($resource_amount),
1351
        'NAME'      => classLocale::$lang['tech'][$resource_id],
1352
      );
1353
    }
1354
1355
    return $result;
1356
  }
1357
1358
  /**
1359
   * @return array
1360
   */
1361
  protected function renderAllowedPlanetTypes() {
1362
    $result = array();
1363
1364
    foreach ($this->allowed_planet_types as $possible_planet_type_id) {
1365
      $result[] = array(
1366
        'ID'         => $possible_planet_type_id,
1367
        'NAME'       => classLocale::$lang['sys_planet_type'][$possible_planet_type_id],
1368
        'NAME_SHORT' => classLocale::$lang['sys_planet_type_sh'][$possible_planet_type_id],
1369
      );
1370
    }
1371
1372
    return $result;
1373
  }
1374
1375
1376
  protected function renderFleet1TargetSelect(&$shortcut) {
1377
    global $note_priority_classes;
1378
1379
    $name = !empty($shortcut['title']) ? $shortcut['title'] : $shortcut['name'];
1380
1381
    $result = array(
1382
      'NAME'       => $name,
1383
      'GALAXY'     => $shortcut['galaxy'],
1384
      'SYSTEM'     => $shortcut['system'],
1385
      'PLANET'     => $shortcut['planet'],
1386
      'TYPE'       => $shortcut['planet_type'],
1387
      'TYPE_PRINT' => classLocale::$lang['fl_shrtcup'][$shortcut['planet_type']],
1388
    );
1389
1390
    if (isset($shortcut['priority'])) {
1391
      $result += array(
1392
        'PRIORITY'       => $shortcut['priority'],
1393
        'PRIORITY_CLASS' => $note_priority_classes[$shortcut['priority']],
1394
      );
1395
    }
1396
1397
    if (isset($shortcut['id'])) {
1398
      $result += array(
1399
        'ID' => $shortcut['id'],
1400
      );
1401
    }
1402
1403
    return $result;
1404
  }
1405
1406
  /**
1407
   * @return array
1408
   */
1409
  protected function renderFleetShortcuts() {
1410
    $result = array();
1411
1412
    // Building list of shortcuts
1413
    $query = DBStaticNote::db_note_list_select_by_owner_and_planet($this->dbOwnerRow);
1414
    while ($row = db_fetch($query)) {
1415
      $result[] = $this->renderFleet1TargetSelect($row);
1416
    }
1417
1418
    return $result;
1419
  }
1420
1421
  /**
1422
   * Building list of own planets & moons
1423
   *
1424
   * @return array
1425
   */
1426
  protected function renderOwnPlanets() {
1427
    $result = array();
1428
1429
    $colonies = DBStaticPlanet::db_planet_list_sorted($this->dbOwnerRow);
1430
    if (count($colonies) <= 1) {
1431
      return $result;
1432
    }
1433
1434
    foreach ($colonies as $row) {
1435
      if ($row['id'] == $this->dbSourcePlanetRow['id']) {
1436
        continue;
1437
      }
1438
1439
      $result[] = $this->renderFleet1TargetSelect($row);
1440
    }
1441
1442
    return $result;
1443
  }
1444
1445
  /**
1446
   * @return array
1447
   */
1448
  protected function renderACSList() {
1449
    $result = array();
1450
1451
    $query = DBStaticFleetACS::db_acs_get_list();
1452
    while ($row = db_fetch($query)) {
1453
      $members = explode(',', $row['eingeladen']);
1454
      foreach ($members as $a => $b) {
1455
        if ($b == $this->dbOwnerRow['id']) {
1456
          $result[] = $this->renderFleet1TargetSelect($row);
1457
        }
1458
      }
1459
    }
1460
1461
    return $result;
1462
  }
1463
1464
1465
  /**
1466
   * @param $template_result
1467
   */
1468
  protected function renderShipSortOptions(&$template_result) {
1469
    foreach (classLocale::$lang['player_option_fleet_ship_sort'] as $sort_id => $sort_text) {
1470
      $template_result['.']['ship_sort_list'][] = array(
1471
        'VALUE' => $sort_id,
1472
        'TEXT'  => $sort_text,
1473
      );
1474
    }
1475
    $template_result += array(
1476
      'FLEET_SHIP_SORT'         => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_SORT],
1477
      'FLEET_SHIP_SORT_INVERSE' => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_SORT_INVERSE],
1478
    );
1479
  }
1480
1481
1482
  /**
1483
   *
1484
   */
1485
  public function fleetPage0() {
1486
    global $template_result;
1487
1488
    lng_include('overview');
1489
1490
    if (empty($this->dbSourcePlanetRow)) {
1491
      message(classLocale::$lang['fl_noplanetrow'], classLocale::$lang['fl_error']);
1492
    }
1493
1494
    // TODO - redo to unitlist render/unit render
1495
    $this->renderAvailableShips($template_result, $this->dbOwnerRow, $this->dbSourcePlanetRow);
1496
1497
    $this->renderShipSortOptions($template_result);
1498
1499
    /**
1500
     * @var Player $playerOwner
1501
     */
1502
    $playerOwner = $this->getLocatedAt();
1503
1504
    $template_result += array(
1505
      'FLYING_FLEETS'      => $playerOwner->fleetsFlying(),
1506
      'MAX_FLEETS'         => $playerOwner->fleetsMax(),
1507
      'FREE_FLEETS'        => $playerOwner->fleetsMax() - $playerOwner->fleetsFlying(),
1508
      'FLYING_EXPEDITIONS' => $playerOwner->expeditionsFlying(),
1509
      'MAX_EXPEDITIONS'    => $playerOwner->expeditionsMax(),
1510
      'FREE_EXPEDITIONS'   => $playerOwner->expeditionsMax() - $playerOwner->expeditionsFlying(),
1511
      'COLONIES_CURRENT'   => $playerOwner->coloniesCurrent(),
1512
      'COLONIES_MAX'       => $playerOwner->coloniesMax(),
1513
1514
      'TYPE_NAME' => classLocale::$lang['fl_planettype'][$this->targetVector->type],
1515
1516
      'speed_factor' => flt_server_flight_speed_multiplier(),
1517
1518
      'PLANET_RESOURCES' => pretty_number($this->dbSourcePlanetRow['metal'] + $this->dbSourcePlanetRow['crystal'] + $this->dbSourcePlanetRow['deuterium']),
1519
      'PLANET_DEUTERIUM' => pretty_number($this->dbSourcePlanetRow['deuterium']),
1520
1521
      'PLAYER_OPTION_FLEET_SHIP_SELECT_OLD'       => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_SELECT_OLD],
1522
      'PLAYER_OPTION_FLEET_SHIP_HIDE_SPEED'       => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_HIDE_SPEED],
1523
      'PLAYER_OPTION_FLEET_SHIP_HIDE_CAPACITY'    => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_HIDE_CAPACITY],
1524
      'PLAYER_OPTION_FLEET_SHIP_HIDE_CONSUMPTION' => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_HIDE_CONSUMPTION],
1525
    );
1526
1527
    $template = gettemplate('fleet0', true);
1528
    $template->assign_recursive($template_result);
1529
    display($template, classLocale::$lang['fl_title']);
1530
  }
1531
1532
  /**
1533
   *
1534
   */
1535
  public function fleetPage1() {
1536
    global $template_result;
1537
1538
    $template_result['.']['fleets'][] = $this->renderFleet(SN_TIME_NOW);
1539
    $template_result['.']['possible_planet_type_id'] = $this->renderAllowedPlanetTypes();
1540
    $template_result['.']['colonies'] = $this->renderOwnPlanets();
1541
    $template_result['.']['shortcut'] = $this->renderFleetShortcuts();
1542
    $template_result['.']['acss'] = $this->renderACSList();
1543
1544
    $template_result += array(
1545
      'speed_factor' => flt_server_flight_speed_multiplier(),
1546
1547
      'fleet_speed'    => $this->fleetSpeed(),
1548
      'fleet_capacity' => $this->shipsGetCapacity(),
1549
1550
      'PLANET_DEUTERIUM' => pretty_number($this->dbSourcePlanetRow['deuterium']),
1551
1552
      'PAGE_HINT' => classLocale::$lang['fl_page1_hint'],
1553
    );
1554
1555
    $template = gettemplate('fleet1', true);
1556
    $template->assign_recursive($template_result);
1557
    display($template, classLocale::$lang['fl_title']);
1558
  }
1559
1560
  public function fleetSpeed() {
1561
    $maxSpeed = array();
1562
    foreach($this->shipsIterator() as $ship_id => $unit) {
1563
      if($unit->count > 0 && !empty(static::$snGroupFleetAndMissiles[$ship_id])) {
1564
        $single_ship_data = get_ship_data($ship_id, $this->dbOwnerRow);
1565
        $maxSpeed[$ship_id] = $single_ship_data['speed'];
1566
      }
1567
    }
1568
1569
    return empty($maxSpeed) ? 0 : min($maxSpeed);
1570
  }
1571
1572
  /**
1573
   * @param array $planetResourcesWithoutConsumption
1574
   */
1575
  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...
1576
    $this->travelData = $this->flt_travel_data($this->oldSpeedInTens);
1577
1578
    $validator = new FleetValidator($this);
1579
    $validator->validate();
1580
  }
1581
1582
  /**
1583
   *
1584
   */
1585
  public function fleetPage2() {
1586
    global $template_result;
1587
1588
    $planetResourcesTotal = DBStaticPlanet::getResources($this->dbOwnerRow, $this->dbSourcePlanetRow);
1589
    $planetResourcesWithoutConsumption = $this->resourcesSubstractConsumption($planetResourcesTotal);
1590
1591
    try {
1592
      $this->fleetPage2Prepare($planetResourcesWithoutConsumption);
1593
    } catch (Exception $e) {
1594
      // TODO - MESSAGE BOX
1595 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...
1596
        sn_db_transaction_rollback();
1597
        pdie(classLocale::$lang['fl_attack_error'][$e->getCode()]);
1598
      } else {
1599
        throw $e;
1600
      }
1601
    }
1602
1603
    // Flight allowed here
1604
    pdump('FLIGHT_ALLOWED', FLIGHT_ALLOWED);
1605
//    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...
1606
1607
    $template_result['.']['missions'] = $this->renderAllowedMissions();
1608
1609
    $template_result['.']['fleets'][] = $this->renderFleet(SN_TIME_NOW);
1610
1611
    $max_duration =
1612
      $this->_mission_type == MT_EXPLORE
1613
        ? get_player_max_expedition_duration($this->dbOwnerRow)
1614
        : (isset($this->allowed_missions[MT_HOLD]) ? 12 : 0);
1615
    $template_result['.']['duration'] = $this->renderDuration($max_duration);
1616
1617
    $this->captainGet();
1618
    $template_result += $this->renderCaptain();
1619
1620
    $template_result['.']['resources'] = $this->renderPlanetResources($planetResourcesWithoutConsumption);
1621
1622
    $template_result += array(
1623
      'planet_metal'     => $planetResourcesWithoutConsumption[RES_METAL],
1624
      'planet_crystal'   => $planetResourcesWithoutConsumption[RES_CRYSTAL],
1625
      'planet_deuterium' => $planetResourcesWithoutConsumption[RES_DEUTERIUM],
1626
1627
      'fleet_capacity' => $this->shipsGetCapacity() - $this->travelData['consumption'],
1628
      'speed'          => $this->oldSpeedInTens,
1629
      'fleet_group'    => $this->_group_id,
1630
1631
      'MAX_DURATION'          => $max_duration,
1632
1633
      // 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...
1634
//      'IS_TRANSPORT_MISSIONS' => !empty($this->allowed_missions[$this->_mission_type]['transport']),
1635
      'IS_TRANSPORT_MISSIONS' => true,
1636
1637
      'PLAYER_COLONIES_CURRENT' => get_player_current_colonies($this->dbOwnerRow),
1638
      'PLAYER_COLONIES_MAX'     => get_player_max_colonies($this->dbOwnerRow),
1639
    );
1640
1641
    $template = gettemplate('fleet2', true);
1642
    $template->assign_recursive($template_result);
1643
    display($template, classLocale::$lang['fl_title']);
1644
  }
1645
1646
  /**
1647
   *
1648
   */
1649
  public function fleetPage3() {
1650
    global $template_result;
1651
1652
    $this->isRealFlight = true;
1653
1654
    sn_db_transaction_start();
1655
1656
    DBStaticUser::db_user_lock_with_target_owner_and_acs($this->dbOwnerRow, $this->dbTargetRow);
1657
1658
    // Checking for group
1659
    $this->groupCheck();
1660
1661
    $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...
1662
    $this->dbSourcePlanetRow = DBStaticPlanet::db_planet_by_id($this->dbSourcePlanetRow['id'], true);
1663 View Code Duplication
    if (!empty($this->dbTargetRow['id'])) {
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...
1664
      $this->dbTargetRow = DBStaticPlanet::db_planet_by_id($this->dbTargetRow['id'], true);
1665
    }
1666
    // TODO - deprecated! Filled in populateTargetPlanetAndOwner
1667 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...
1668
      $this->dbTargetOwnerRow = DBStaticPlanet::db_planet_by_id($this->dbTargetRow['id_owner'], true);
1669
    }
1670
1671
    $this->resource_list = array(
1672
      RES_METAL     => max(0, floor(sys_get_param_float('resource0'))),
1673
      RES_CRYSTAL   => max(0, floor(sys_get_param_float('resource1'))),
1674
      RES_DEUTERIUM => max(0, floor(sys_get_param_float('resource2'))),
1675
    );
1676
1677
    $this->captainGet();
1678
1679
    $this->travelData = $this->flt_travel_data($this->oldSpeedInTens);
1680
1681
    try {
1682
      $validator = new FleetValidator($this);
1683
      $validator->validate();
1684
    } catch (Exception $e) {
1685
      // TODO - MESSAGE BOX
1686 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...
1687
        sn_db_transaction_rollback();
1688
        pdie(classLocale::$lang['fl_attack_error'][$e->getCode()]);
1689
      } else {
1690
        throw $e;
1691
      }
1692
    }
1693
1694
    // TODO - check if mission is not 0 and in ALLOWED_MISSIONS
1695
1696
    // Flight allowed here
1697
    pdump('FLIGHT_ALLOWED', FLIGHT_ALLOWED);
1698
//    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...
1699
1700
1701
    $timeMissionJob = 0;
1702
    // TODO check for empty mission AKA mission allowed
1703
/*
1704
    if ($this->_mission_type == MT_ACS && $aks) {
1705
      $acsTimeToArrive = $aks['ankunft'] - SN_TIME_NOW;
1706
      if ($acsTimeToArrive < $this->travelData['duration']) {
1707
        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']);
1708
      }
1709
      // Set time to travel to ACS' TTT
1710
      $this->travelData['duration'] = $acsTimeToArrive;
1711
*/
1712
      if ($this->_mission_type != MT_ACS) {
1713
      if ($this->_mission_type == MT_EXPLORE || $this->_mission_type == MT_HOLD) {
1714
        $max_duration = $this->_mission_type == MT_EXPLORE ? get_player_max_expedition_duration($this->dbOwnerRow) : ($this->_mission_type == MT_HOLD ? 12 : 0);
1715
        if ($max_duration) {
1716
          $mission_time_in_hours = sys_get_param_id('missiontime');
1717
          if ($mission_time_in_hours > $max_duration || $mission_time_in_hours < 1) {
1718
            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...
1719
            die();
1720
          }
1721
          $timeMissionJob = ceil($mission_time_in_hours * 3600 / ($this->_mission_type == MT_EXPLORE && classSupernova::$config->game_speed_expedition ? classSupernova::$config->game_speed_expedition : 1));
1722
        }
1723
      }
1724
    }
1725
1726
    //
1727
    //
1728
    //
1729
    //
1730
    //
1731
    //
1732
    //
1733
    //
1734
    // ---------------- END OF CHECKS ------------------------------------------------------
1735
1736
    $this->set_times($this->travelData['duration'], $timeMissionJob);
1737
    $this->dbInsert();
1738
1739
    DBStaticPlanet::db_planet_set_by_id($this->dbSourcePlanetRow['id'],
1740
      "`metal` = `metal` - {$this->resource_list[RES_METAL]},
1741
      `crystal` = `crystal` - {$this->resource_list[RES_CRYSTAL]},
1742
      `deuterium` = `deuterium` - {$this->resource_list[RES_DEUTERIUM]} - {$this->travelData['consumption']}"
1743
    );
1744
1745
    $db_changeset = $this->unitList->db_prepare_old_changeset_for_planet($this->dbOwnerRow, $this->dbSourcePlanetRow['id']);
1746
    db_changeset_apply($db_changeset);
1747
1748
1749
    if (!empty($this->captain['unit_id'])) {
1750
      DBStaticUnit::db_unit_set_by_id($this->captain['unit_id'], "`unit_location_type` = " . LOC_FLEET . ", `unit_location_id` = {$this->_dbId}");
1751
    }
1752
1753
//    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...
1754
//
1755
//    // Set time to travel to ACS' TTT
1756
//    $this->fleet->travelData['duration'] = $acsTimeToArrive;
1757
1758
1759
    $template_result['.']['fleets'][] = $this->renderFleet(SN_TIME_NOW, $timeMissionJob);
1760
1761
    $template_result += array(
1762
      'mission'         => classLocale::$lang['type_mission'][$this->_mission_type] . ($this->_mission_type == MT_EXPLORE || $this->_mission_type == MT_HOLD ? ' ' . pretty_time($timeMissionJob) : ''),
1763
      'dist'            => pretty_number($this->travelData['distance']),
1764
      'speed'           => pretty_number($this->travelData['fleet_speed']),
1765
      'deute_need'      => pretty_number($this->travelData['consumption']),
1766
      'from'            => "{$this->dbSourcePlanetRow['galaxy']}:{$this->dbSourcePlanetRow['system']}:{$this->dbSourcePlanetRow['planet']}",
1767
      'time_go'         => date(FMT_DATE_TIME, $this->_time_arrive_to_target),
1768
      'time_go_local'   => date(FMT_DATE_TIME, $this->_time_arrive_to_target + SN_CLIENT_TIME_DIFF),
1769
      'time_back'       => date(FMT_DATE_TIME, $this->_time_return_to_source),
1770
      'time_back_local' => date(FMT_DATE_TIME, $this->_time_return_to_source + SN_CLIENT_TIME_DIFF),
1771
    );
1772
1773
    $this->dbSourcePlanetRow = DBStaticPlanet::db_planet_by_id($this->dbSourcePlanetRow['id']);
1774
1775
    pdie('Stop for debug');
1776
1777
    sn_db_transaction_commit();
1778
1779
    $template = gettemplate('fleet3', true);
1780
    $template->assign_recursive($template_result);
1781
    display($template, classLocale::$lang['fl_title']);
1782
  }
1783
1784
  protected function groupCheck() {
1785
    if (empty($this->_group_id)) {
1786
      return;
1787
    }
1788
1789
    // ACS attack must exist (if acs fleet has arrived this will also return false (2 checks in 1!!!)
1790
    $this->acs = DBStaticFleetACS::db_acs_get_by_group_id($this->_group_id);
1791
    if (empty($this->acs)) {
1792
      $this->_group_id = 0;
1793
    } else {
1794
      $this->targetVector->convertToVector($this->acs);
1795
    }
1796
  }
1797
1798
  /**
1799
   * @param array $planetResources
1800
   *
1801
   * @return array
1802
   */
1803
  protected function resourcesSubstractConsumption($planetResources) {
1804
    !isset($planetResources[RES_DEUTERIUM]) ? $planetResources[RES_DEUTERIUM] = 0 : false;
1805
1806
    if($this->travelData['consumption'] >= 0) {
1807
      $planetResources[RES_DEUTERIUM] -= ceil($this->travelData['consumption']);
1808
    }
1809
1810
    return $planetResources;
1811
  }
1812
1813
  /**
1814
   */
1815
  public function captainGet() {
1816
    $this->captain = array();
1817
1818
    /**
1819
     * @var unit_captain $moduleCaptain
1820
     */
1821
    $moduleCaptain = !empty(sn_module::$sn_module['unit_captain']) ? sn_module::$sn_module['unit_captain'] : null;
1822
1823
    if (
1824
      !empty($moduleCaptain)
1825
      &&
1826
      $moduleCaptain->manifest['active']
1827
    ) {
1828
      $this->captain = $moduleCaptain->unit_captain_get($this->dbSourcePlanetRow['id']);
1829
    }
1830
  }
1831
1832
  /**
1833
   * @return array
1834
   */
1835
  protected function renderCaptain() {
1836
    $result = array();
1837
1838
    if (!empty($this->captain['unit_id']) && $this->captain['unit_location_type'] == LOC_PLANET) {
1839
      $result = array(
1840
        'CAPTAIN_ID'     => $this->captain['unit_id'],
1841
        'CAPTAIN_LEVEL'  => $this->captain['captain_level'],
1842
        'CAPTAIN_SHIELD' => $this->captain['captain_shield'],
1843
        'CAPTAIN_ARMOR'  => $this->captain['captain_armor'],
1844
        'CAPTAIN_ATTACK' => $this->captain['captain_attack'],
1845
      );
1846
    }
1847
1848
    return $result;
1849
  }
1850
1851
}
1852