Completed
Push — work-fleets ( d9c01a...3f92e6 )
by SuperNova.WS
07:11
created

Fleet::resourcesGetTotalInMetal()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 5
nc 1
nop 1
dl 0
loc 6
rs 9.4285
c 1
b 0
f 0
ccs 0
cts 6
cp 0
crap 2
1
<?php
2
use DBStatic\DBStaticFleetACS;
3
use DBStatic\DBStaticNote;
4
use DBStatic\DBStaticPlanet;
5
use DBStatic\DBStaticUnit;
6
use DBStatic\DBStaticUser;
7
use Exception\ExceptionFleetInvalid;
8
use Exception\ExceptionPropertyAccess;
9
use Vector\Vector;
10
11
/**
12
 * Class Fleet
13
 *
14
 * @property int dbId
15
 * @property int playerOwnerId
16
 * @property int group_id
17
 * @property int mission_type
18
 * @property int target_owner_id
19
 * @property int is_returning
20
 *
21
 * @property int time_launch
22
 * @property int time_arrive_to_target
23
 * @property int time_mission_job_complete
24
 * @property int time_return_to_source
25
 *
26
 * @property int fleet_start_planet_id
27
 * @property int fleet_start_galaxy
28
 * @property int fleet_start_system
29
 * @property int fleet_start_planet
30
 * @property int fleet_start_type
31
 *
32
 * @property int fleet_end_planet_id
33
 * @property int fleet_end_galaxy
34
 * @property int fleet_end_system
35
 * @property int fleet_end_planet
36
 * @property int fleet_end_type
37
 *
38
 */
39
class Fleet extends UnitContainer {
40
41
  // DBRow inheritance *************************************************************************************************
42
43
  /**
44
   * Table name in DB
45
   *
46
   * @var string
47
   */
48
  protected static $_table = 'fleets';
49
  /**
50
   * Name of ID field in DB
51
   *
52
   * @var string
53
   */
54
  protected static $_dbIdFieldName = 'fleet_id';
55
  /**
56
   * DB_ROW to Class translation scheme
57
   *
58
   * @var array
59
   */
60
  protected $_properties = array(
61
    'dbId'          => array(
62
      P_DB_FIELD => 'fleet_id',
63
    ),
64
    'playerOwnerId' => array(
65
      P_METHOD_EXTRACT => 'ownerExtract',
66
      P_METHOD_INJECT  => 'ownerInject',
67
//      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...
68
    ),
69
    'mission_type'  => array(
70
      P_DB_FIELD   => 'fleet_mission',
71
      P_FUNC_INPUT => 'intval',
72
    ),
73
74
    'target_owner_id' => array(
75
      P_DB_FIELD => 'fleet_target_owner',
76
    ),
77
    'group_id'        => array(
78
      P_DB_FIELD => 'fleet_group',
79
    ),
80
    'is_returning'    => array(
81
      P_DB_FIELD   => 'fleet_mess',
82
      P_FUNC_INPUT => 'intval',
83
    ),
84
85
    'shipCount' => array(
86
      P_DB_FIELD  => 'fleet_amount',
87
// 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...
88
//      P_FUNC_OUTPUT => 'get_ship_count',
89
//      P_DB_FIELDS_LINKED => array(
90
//        'fleet_amount',
91
//      ),
92
      P_READ_ONLY => true,
93
    ),
94
95
    'time_launch' => array(
96
      P_DB_FIELD => 'start_time',
97
    ),
98
99
    'time_arrive_to_target'     => array(
100
      P_DB_FIELD => 'fleet_start_time',
101
    ),
102
    'time_mission_job_complete' => array(
103
      P_DB_FIELD => 'fleet_end_stay',
104
    ),
105
    'time_return_to_source'     => array(
106
      P_DB_FIELD => 'fleet_end_time',
107
    ),
108
109
    'fleet_start_planet_id' => array(
110
      P_DB_FIELD   => 'fleet_start_planet_id',
111
      P_FUNC_INPUT => 'nullIfEmpty',
112
    ),
113
114
    'fleet_start_galaxy' => array(
115
      P_DB_FIELD => 'fleet_start_galaxy',
116
    ),
117
    'fleet_start_system' => array(
118
      P_DB_FIELD => 'fleet_start_system',
119
    ),
120
    'fleet_start_planet' => array(
121
      P_DB_FIELD => 'fleet_start_planet',
122
    ),
123
    'fleet_start_type'   => array(
124
      P_DB_FIELD => 'fleet_start_type',
125
    ),
126
127
    'fleet_end_planet_id' => array(
128
      P_DB_FIELD   => 'fleet_end_planet_id',
129
      P_FUNC_INPUT => 'nullIfEmpty',
130
    ),
131
    'fleet_end_galaxy'    => array(
132
      P_DB_FIELD => 'fleet_end_galaxy',
133
    ),
134
    'fleet_end_system'    => array(
135
      P_DB_FIELD => 'fleet_end_system',
136
    ),
137
    'fleet_end_planet'    => array(
138
      P_DB_FIELD => 'fleet_end_planet',
139
    ),
140
    'fleet_end_type'      => array(
141
      P_DB_FIELD => 'fleet_end_type',
142
    ),
143
144
    'resource_list' => array(
145
      P_METHOD_EXTRACT   => 'resourcesExtract',
146
      P_METHOD_INJECT    => 'resourcesInject',
147
      P_DB_FIELDS_LINKED => array(
148
        'fleet_resource_metal',
149
        'fleet_resource_crystal',
150
        'fleet_resource_deuterium',
151
      ),
152
    ),
153
  );
154
155
156
  // UnitContainer inheritance *****************************************************************************************
157
  /**
158
   * Type of this location
159
   *
160
   * @var int $locationType
161
   */
162
  protected static $locationType = LOC_FLEET;
163
164
165
  // New properties ****************************************************************************************************
166
  public static $snGroupFleet = array();
167
  public static $snGroupFleetAndMissiles = array();
168
  public static $snGroupRecyclers = array();
169
170
  /**
171
   * `fleet_owner`
172
   *
173
   * @var int
174
   */
175
  protected $_playerOwnerId = 0;
176
  /**
177
   * `fleet_group`
178
   *
179
   * @var int
180
   */
181
  protected $_group_id = 0;
182
  public $acs = array();
183
184
  /**
185
   * `fleet_mission`
186
   *
187
   * @var int
188
   */
189
  protected $_mission_type = 0;
190
191
  /**
192
   * `fleet_target_owner`
193
   *
194
   * @var int
195
   */
196
  protected $_target_owner_id = null;
197
198
  /**
199
   * @var array
200
   */
201
  public $resource_list = array(
202
    RES_METAL     => 0,
203
    RES_CRYSTAL   => 0,
204
    RES_DEUTERIUM => 0,
205
  );
206
207
208
  /**
209
   * `fleet__mess` - Флаг возвращающегося флота
210
   *
211
   * @var int
212
   */
213
  protected $_is_returning = 0;
214
  /**
215
   * `start_time` - Время отправления - таймштамп взлёта флота из точки отправления
216
   *
217
   * @var int $_time_launch
218
   */
219
  protected $_time_launch = 0; // `start_time` = SN_TIME_NOW
220
  /**
221
   * `fleet_start_time` - Время прибытия в точку миссии/время начала выполнения миссии
222
   *
223
   * @var int $_time_arrive_to_target
224
   */
225
  protected $_time_arrive_to_target = 0; // `fleet_start_time` = SN_TIME_NOW + $time_travel
226
  /**
227
   * `fleet_end_stay` - Время окончания миссии в точке назначения
228
   *
229
   * @var int $_time_mission_job_complete
230
   */
231
  protected $_time_mission_job_complete = 0; // `fleet_end_stay`
232
  /**
233
   * `fleet_end_time` - Время возвращения флота после окончания миссии
234
   *
235
   * @var int $_time_return_to_source
236
   */
237
  protected $_time_return_to_source = 0; // `fleet_end_time`
238
239
240
  protected $_fleet_start_planet_id = null;
241
  protected $_fleet_start_galaxy = 0;
242
  protected $_fleet_start_system = 0;
243
  protected $_fleet_start_planet = 0;
244
  protected $_fleet_start_type = PT_ALL;
245
246
  protected $_fleet_end_planet_id = null;
247
  protected $_fleet_end_galaxy = 0;
248
  protected $_fleet_end_system = 0;
249
  protected $_fleet_end_planet = 0;
250
  protected $_fleet_end_type = PT_ALL;
251
252
  // Missile properties
253
  public $missile_target = 0;
254
255
  // Fleet event properties
256
  public $fleet_start_name = '';
257
  public $fleet_end_name = '';
258
  public $ov_label = '';
259
  public $ov_this_planet = '';
260
  public $event_time = 0;
261
262
  protected $resource_delta = array();
263
  protected $resource_replace = array();
264
265
266
//
267
268
269
  /**
270
   * @var array $allowed_missions
271
   */
272
  public $allowed_missions = array();
273
  /**
274
   * @var array $exists_missions
275
   */
276
  public $exists_missions = array();
277
  public $allowed_planet_types = array(
278
    // PT_NONE => PT_NONE,
279
    PT_PLANET => PT_PLANET,
280
    PT_MOON   => PT_MOON,
281
    PT_DEBRIS => PT_DEBRIS
282
  );
283
284
  // TODO - Move to Player
285
  public $dbOwnerRow = array();
286
  public $dbSourcePlanetRow = array();
287
288
  /**
289
   * GSPT coordinates of target
290
   *
291
   * @var Vector
292
   */
293
  public $targetVector = array();
294
  /**
295
   * Target planet row
296
   *
297
   * @var array
298
   */
299
  public $dbTargetRow = array();
300
  public $dbTargetOwnerRow = array();
301
302
  /**
303
   * Fleet speed - old in 1/10 of 100%
304
   *
305
   * @var int
306
   */
307
  public $oldSpeedInTens = 0;
308
309
  public $tempPlayerMaxFleets = 0;
310
  public $travelData = array();
311
312
  public $isRealFlight = false;
313
314
  /**
315
   * @var int $targetedUnitId
316
   */
317
  public $targetedUnitId = 0;
318
319
  /**
320
   * @var array $captain
321
   */
322
  public $captain = array();
323
  /**
324
   * @var int $captainId
325
   */
326
  public $captainId = 0;
327
328
  /**
329
   * @var FleetValidator $validator
330
   */
331
  public $validator;
332
333
334
  /**
335
   * @var UnitList $unitList
336
   */
337
  protected $unitList = null;
338
339
340
  /**
341
   * Fleet constructor.
342
   */
343
  public function __construct() {
344
    parent::__construct();
345
    $this->exists_missions = sn_get_groups('missions');
346
    $this->validator = new FleetValidator($this);
347
  }
348
349
  /**
350
   * @param array $playerRow
351
   * @param array $planetRow
352
   *
353
   * @return array
354
   */
355
  // TODO - redo to unit/unitlist renderer
356
  public function renderAvailableShips($playerRow, $planetRow) {
357
    $record_index = 0;
358
    $ship_list = array();
359
    foreach (Fleet::$snGroupFleet as $n => $unit_id) {
360
      $unit_level = mrc_get_level($playerRow, $planetRow, $unit_id, false, true);
361
      if ($unit_level <= 0) {
362
        continue;
363
      }
364
      $ship_data = get_ship_data($unit_id, $playerRow);
365
      $ship_list[$unit_id] = array(
366
        '__INDEX'          => $record_index++,
367
        'ID'               => $unit_id,
368
        'NAME'             => classLocale::$lang['tech'][$unit_id],
369
        'AMOUNT'           => $unit_level,
370
        'AMOUNT_TEXT'      => pretty_number($unit_level),
371
        'CONSUMPTION'      => $ship_data['consumption'],
372
        'CONSUMPTION_TEXT' => pretty_number($ship_data['consumption']),
373
        'SPEED'            => $ship_data['speed'],
374
        'SPEED_TEXT'       => pretty_number($ship_data['speed']),
375
        'CAPACITY'         => $ship_data['capacity'],
376
        'CAPACITY_TEXT'    => pretty_number($ship_data['capacity']),
377
      );
378
    }
379
380
    sortUnitRenderedList($ship_list, classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_SORT], classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_SORT_INVERSE]);
381
382
    return $ship_list;
383
  }
384
385
  public function isEmpty() {
386
    return !$this->resourcesGetTotal() && !$this->shipsGetTotal();
387
  }
388
389
//  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...
390
//    return $this->playerOwnerId;
391
//  }
392
393
  /**
394
   * Initializes Fleet from user params and posts it to DB
395
   */
396
  public function dbInsert() {
397
    // WARNING! MISSION TIMES MUST BE SET WITH set_times() method!
398
    // TODO - more checks!
399
    if (empty($this->_time_launch)) {
400
      die('Fleet time not set!');
401
    }
402
403
    parent::dbInsert();
404
  }
405
406
407
  /* FLEET DB ACCESS =================================================================================================*/
408
409
  /**
410
   * LOCK - Lock all records which can be used with mission
411
   *
412
   * @param $mission_data
413
   *
414
   * @return array|bool|mysqli_result|null
415
   */
416
  public function dbLockFlying(&$mission_data) {
417
    // Тупо лочим всех юзеров, чьи флоты летят или улетают с координат отбытия/прибытия $fleet_row
418
    // Что бы делать это умно - надо учитывать fleet__mess во $fleet_row и в таблице fleets
419
420
    $fleet_id_safe = idval($this->_dbId);
421
422
    return classSupernova::$db->doSelect(
423
    // Блокировка самого флота
424
      "SELECT 1 FROM {{fleets}} AS f " .
425
426
      // Блокировка всех юнитов, принадлежащих этому флоту
427
      "LEFT JOIN {{unit}} as unit ON unit.unit_location_type = " . static::$locationType . " AND unit.unit_location_id = f.fleet_id " .
428
429
      // Блокировка всех прилетающих и улетающих флотов, если нужно
430
      // TODO - lock fleets by COORDINATES
431
      ($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 " : '') .
432
      // Блокировка всех юнитов, принадлежащих прилетающим и улетающим флотам - ufd = unit_fleet_destination
433
      ($mission_data['dst_fleets'] ? "LEFT JOIN {{unit}} AS ufd ON ufd.unit_location_type = " . static::$locationType . " AND ufd.unit_location_id = fd.fleet_id " : '') .
434
435
      ($mission_data['dst_user'] || $mission_data['dst_planet'] ? "LEFT JOIN {{users}} AS ud ON ud.id = f.fleet_target_owner " : '') .
436
      // Блокировка всех юнитов, принадлежащих владельцу планеты-цели
437
      ($mission_data['dst_user'] || $mission_data['dst_planet'] ? "LEFT JOIN {{unit}} AS unit_player_dest ON unit_player_dest.unit_player_id = ud.id " : '') .
438
      // Блокировка планеты-цели
439
      ($mission_data['dst_planet'] ? "LEFT JOIN {{planets}} AS pd ON pd.id = f.fleet_end_planet_id " : '') .
440
      // Блокировка всех юнитов, принадлежащих планете-цели - НЕ НУЖНО. Уже залочили ранее, как принадлежащие игроку-цели
441
//      ($mission_data['dst_planet'] ? "LEFT JOIN {{unit}} AS upd ON upd.unit_location_type = " . LOC_PLANET . " AND upd.unit_location_id = pd.id " : '') .
442
443
444
      ($mission_data['src_user'] || $mission_data['src_planet'] ? "LEFT JOIN {{users}} AS us ON us.id = f.fleet_owner " : '') .
445
      // Блокировка всех юнитов, принадлежащих владельцу флота
446
      ($mission_data['src_user'] || $mission_data['src_planet'] ? "LEFT JOIN {{unit}} AS unit_player_src ON unit_player_src.unit_player_id = us.id " : '') .
447
      // Блокировка планеты отправления
448
      ($mission_data['src_planet'] ? "LEFT JOIN {{planets}} AS ps ON ps.id = f.fleet_start_planet_id " : '') .
449
      // Блокировка всех юнитов, принадлежащих планете с которой юниты были отправлены - НЕ НУЖНО. Уже залочили ранее, как принадлежащие владельцу флота
450
//      ($mission_data['src_planet'] ? "LEFT JOIN {{unit}} AS ups ON ups.unit_location_type = " . LOC_PLANET . " AND ups.unit_location_id = ps.id " : '') .
451
452
      "WHERE f.fleet_id = {$fleet_id_safe} GROUP BY 1 FOR UPDATE"
453
    );
454
  }
455
456
  /**
457
   * Lock all fields that belongs to operation
458
   *
459
   * @param $dbId
460
   */
461
  // TODO = make static
462
  public function dbGetLockById($dbId) {
463
    classSupernova::$db->doSelect(
464
    // Блокировка самого флота
465
      "SELECT 1 FROM {{fleets}} AS FLEET0 " .
466
      // Lock fleet owner
467
      "LEFT JOIN {{users}} as USER0 on USER0.id = FLEET0.fleet_owner " .
468
      // Блокировка всех юнитов, принадлежащих этому флоту
469
      "LEFT JOIN {{unit}} as UNIT0 ON UNIT0.unit_location_type = " . LOC_FLEET . " AND UNIT0.unit_location_id = FLEET0.fleet_id " .
470
471
      // Без предварительной выборки неизвестно - куда летит этот флот.
472
      // Поэтому надо выбирать флоты, чьи координаты прибытия ИЛИ отбытия совпадают с координатами прибытия ИЛИ отбытия текущего флота.
473
      // Получаем матрицу 2х2 - т.е. 4 подзапроса.
474
      // При блокировке всегда нужно выбирать И лпанету, И луну - поскольку при бое на орбите луны обломки падают на орбиту планеты.
475
      // Поэтому тип планеты не указывается
476
477
      // Lock fleet heading to destination planet. Only if FLEET0.fleet_mess == 0
478
      "LEFT JOIN {{fleets}} AS FLEET1 ON
479
        FLEET1.fleet_mess = 0 AND FLEET0.fleet_mess = 0 AND
480
        FLEET1.fleet_end_galaxy = FLEET0.fleet_end_galaxy AND
481
        FLEET1.fleet_end_system = FLEET0.fleet_end_system AND
482
        FLEET1.fleet_end_planet = FLEET0.fleet_end_planet
483
      " .
484
      // Блокировка всех юнитов, принадлежащих этим флотам
485
      "LEFT JOIN {{unit}} as UNIT1 ON UNIT1.unit_location_type = " . LOC_FLEET . " AND UNIT1.unit_location_id = FLEET1.fleet_id " .
486
      // Lock fleet owner
487
      "LEFT JOIN {{users}} as USER1 on USER1.id = FLEET1.fleet_owner " .
488
489
      "LEFT JOIN {{fleets}} AS FLEET2 ON
490
        FLEET2.fleet_mess = 1   AND FLEET0.fleet_mess = 0 AND
491
        FLEET2.fleet_start_galaxy = FLEET0.fleet_end_galaxy AND
492
        FLEET2.fleet_start_system = FLEET0.fleet_end_system AND
493
        FLEET2.fleet_start_planet = FLEET0.fleet_end_planet
494
      " .
495
      // Блокировка всех юнитов, принадлежащих этим флотам
496
      "LEFT JOIN {{unit}} as UNIT2 ON
497
        UNIT2.unit_location_type = " . LOC_FLEET . " AND
498
        UNIT2.unit_location_id = FLEET2.fleet_id
499
      " .
500
      // Lock fleet owner
501
      "LEFT JOIN {{users}} as USER2 on
502
        USER2.id = FLEET2.fleet_owner
503
      " .
504
505
      // Lock fleet heading to source planet. Only if FLEET0.fleet_mess == 1
506
      "LEFT JOIN {{fleets}} AS FLEET3 ON
507
        FLEET3.fleet_mess = 0 AND FLEET0.fleet_mess = 1 AND
508
        FLEET3.fleet_end_galaxy = FLEET0.fleet_start_galaxy AND
509
        FLEET3.fleet_end_system = FLEET0.fleet_start_system AND
510
        FLEET3.fleet_end_planet = FLEET0.fleet_start_planet
511
      " .
512
      // Блокировка всех юнитов, принадлежащих этим флотам
513
      "LEFT JOIN {{unit}} as UNIT3 ON
514
        UNIT3.unit_location_type = " . LOC_FLEET . " AND
515
        UNIT3.unit_location_id = FLEET3.fleet_id
516
      " .
517
      // Lock fleet owner
518
      "LEFT JOIN {{users}} as USER3 on USER3.id = FLEET3.fleet_owner " .
519
520
      "LEFT JOIN {{fleets}} AS FLEET4 ON
521
        FLEET4.fleet_mess = 1   AND FLEET0.fleet_mess = 1 AND
522
        FLEET4.fleet_start_galaxy = FLEET0.fleet_start_galaxy AND
523
        FLEET4.fleet_start_system = FLEET0.fleet_start_system AND
524
        FLEET4.fleet_start_planet = FLEET0.fleet_start_planet
525
      " .
526
      // Блокировка всех юнитов, принадлежащих этим флотам
527
      "LEFT JOIN {{unit}} as UNIT4 ON
528
        UNIT4.unit_location_type = " . LOC_FLEET . " AND
529
        UNIT4.unit_location_id = FLEET4.fleet_id
530
      " .
531
      // Lock fleet owner
532
      "LEFT JOIN {{users}} as USER4 on
533
        USER4.id = FLEET4.fleet_owner
534
      " .
535
536
537
      // Locking start planet
538
      "LEFT JOIN {{planets}} AS PLANETS5 ON
539
        FLEET0.fleet_mess = 1 AND
540
        PLANETS5.galaxy = FLEET0.fleet_start_galaxy AND
541
        PLANETS5.system = FLEET0.fleet_start_system AND
542
        PLANETS5.planet = FLEET0.fleet_start_planet
543
      " .
544
      // Lock planet owner
545
      "LEFT JOIN {{users}} as USER5 on
546
        USER5.id = PLANETS5.id_owner
547
      " .
548
      // Блокировка всех юнитов, принадлежащих этой планете
549
      "LEFT JOIN {{unit}} as UNIT5 ON
550
        UNIT5.unit_location_type = " . LOC_PLANET . " AND
551
        UNIT5.unit_location_id = PLANETS5.id
552
      " .
553
554
555
      // Locking destination planet
556
      "LEFT JOIN {{planets}} AS PLANETS6 ON
557
        FLEET0.fleet_mess = 0 AND
558
        PLANETS6.galaxy = FLEET0.fleet_end_galaxy AND
559
        PLANETS6.system = FLEET0.fleet_end_system AND
560
        PLANETS6.planet = FLEET0.fleet_end_planet
561
      " .
562
      // Lock planet owner
563
      "LEFT JOIN {{users}} as USER6 on
564
        USER6.id = PLANETS6.id_owner
565
      " .
566
      // Блокировка всех юнитов, принадлежащих этой планете
567
      "LEFT JOIN {{unit}} as UNIT6 ON
568
        UNIT6.unit_location_type = " . LOC_PLANET . " AND
569
        UNIT6.unit_location_id = PLANETS6.id
570
      " .
571
      "WHERE FLEET0.fleet_id = {$dbId} GROUP BY 1 FOR UPDATE"
572
    );
573
  }
574
575
576
  public function dbRowParse($db_row) {
577
    parent::dbRowParse($db_row); // TODO: Change the autogenerated stub
578
    $player = new Player();
579
    $player->dbLoad($db_row['fleet_owner']);
580
    $this->setLocatedAt($player);
581
  }
582
583
  /* FLEET HELPERS =====================================================================================================*/
584
  /**
585
   * Forcibly returns fleet before time outs
586
   */
587
  public function commandReturn() {
588
    $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;
589
590
    // Считаем, что флот уже долетел TODO
591
    $this->time_arrive_to_target = SN_TIME_NOW;
592
    // Убираем флот из группы
593
    $this->group_id = 0;
594
    // Отменяем работу в точке назначения
595
    $this->time_mission_job_complete = 0;
596
    // TODO - правильно вычслять время возвращения - по проделанному пути, а не по старому времени возвращения
597
    $this->time_return_to_source = $ReturnFlyingTime;
598
599
    // Записываем изменения в БД
600
    $this->markReturnedAndSave();
601
602
    if ($this->_group_id) {
603
      // TODO: Make here to delete only one AKS - by adding aks_fleet_count to AKS table
604
      DBStaticFleetACS::db_fleet_aks_purge();
605
    }
606
  }
607
608
609
  /**
610
   * @return array
611
   */
612
  public function target_coordinates_without_type() {
613
    return array(
614
      'galaxy' => $this->_fleet_end_galaxy,
615
      'system' => $this->_fleet_end_system,
616
      'planet' => $this->_fleet_end_planet,
617
    );
618
  }
619
620
  /**
621
   * @return array
622
   */
623
  public function target_coordinates_typed() {
624
    return array(
625
      'galaxy' => $this->_fleet_end_galaxy,
626
      'system' => $this->_fleet_end_system,
627
      'planet' => $this->_fleet_end_planet,
628
      'type'   => $this->_fleet_end_type,
629
    );
630
  }
631
632
  /**
633
   * @return array
634
   */
635
  public function launch_coordinates_typed() {
636
    return array(
637
      'galaxy' => $this->_fleet_start_galaxy,
638
      'system' => $this->_fleet_start_system,
639
      'planet' => $this->_fleet_start_planet,
640
      'type'   => $this->_fleet_start_type,
641
    );
642
  }
643
644
  public function isReturning() {
645
    return FLEET_FLAG_RETURNING == $this->_is_returning;
646
  }
647
648
  /**
649
   * Sets object fields for fleet return
650
   */
651
  public function markReturnedAndSave() {
652
    // TODO - Проверка - а не возвращается ли уже флот?
653
    $this->is_returning = FLEET_FLAG_RETURNING;
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_PREFIX, false, 'name');
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...
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
   */
887
  public function shipsGetCapacityRecyclers($recycler_info) {
888
    $recyclers_incoming_capacity = 0;
889
    foreach ($this->shipsIterator() as $unitId => $unit) {
890
      if (!empty(static::$snGroupRecyclers[$unitId]) && $unit->count >= 1) {
891
        $recyclers_incoming_capacity += $unit->count * $recycler_info[$unitId]['capacity'];
892
      }
893
    }
894
895
    return $recyclers_incoming_capacity;
896
  }
897
898
  /**
899
   * @return bool
900
   */
901
  // TODO - А если не на планете????
902
  public function shipsIsEnoughOnPlanet() {
903
    return $this->unitList->shipsIsEnoughOnPlanet($this->dbOwnerRow, $this->dbSourcePlanetRow);
904
  }
905
906
  /**
907
   * @return bool
908
   */
909
  public function shipsAllPositive() {
910
    return $this->unitList->unitsPositive();
911
  }
912
913
  /**
914
   * @return bool
915
   */
916
  public function shipsAllFlying() {
917
    return $this->unitList->unitsInGroup(static::$snGroupFleetAndMissiles);
918
  }
919
920
  /**
921
   * @return bool
922
   */
923
  public function shipsAllMovable() {
924
    return $this->unitList->unitsIsAllMovable($this->dbOwnerRow);
925
  }
926
927
  /**
928
   * Restores fleet or resources to planet
929
   *
930
   * @param bool $start
931
   * @param int  $result
932
   *
933
   * @return int
934
   */
935
  // TODO - split to functions
936
  public function shipsLand($start = true, &$result = CACHE_NOTHING) {
937
    sn_db_transaction_check(true);
938
939
    // Если флот уже обработан - не существует или возращается - тогда ничего не делаем
940
    if ($this->isEmpty()) {
941
      return $result;
942
    }
943
944
    $coordinates = $start ? $this->launch_coordinates_typed() : $this->target_coordinates_typed();
945
946
    // Поскольку эта функция может быть вызвана не из обработчика флотов - нам надо всё заблокировать вроде бы НЕ МОЖЕТ!!!
947
    // TODO Проверить от многократного срабатывания !!!
948
    // Тут не блокируем пока - сначала надо заблокировать пользователя, что бы не было дедлока
949
    // TODO поменять на владельца планеты - когда его будут возвращать всегда !!!
950
951
    // Узнаем ИД владельца планеты.
952
    // С блокировкой, поскольку эта функция может быть вызвана только из менеджера летящих флотов.
953
    // А там уже всё заблокировано как надо и повторная блокировка не вызовет дедлок.
954
    $planet_arrival = DBStaticPlanet::db_planet_by_vector($coordinates, '', true);
955
    // Блокируем пользователя
956
    // TODO - вообще-то нам уже известен пользователь в МЛФ - так что можно просто передать его сюда
957
    $user = DBStaticUser::db_user_by_id($planet_arrival['id_owner'], true);
958
959
    // TODO - Проверка, что планета всё еще существует на указанных координатах, а не телепортировалась, не удалена хозяином, не уничтожена врагом
960
    // Флот, который возвращается на захваченную планету, пропадает
961
    // Ship landing is possible only to fleet owner's planet
962
    if ($this->getPlayerOwnerId() == $planet_arrival['id_owner']) {
963
      // Adjusting ship amount on planet
964
      foreach ($this->shipsIterator() as $ship_id => $ship) {
965
        if ($ship->count) {
966
          DBStaticUnit::dbUpdateOrInsertUnit($ship_id, $ship->count, $user, $planet_arrival['id']);
967
        }
968
      }
969
970
      // Restoring resources to planet
971
      $this->resourcesUnload($start, $result);
972
    }
973
974
    $result = CACHE_FLEET | ($start ? CACHE_PLANET_SRC : CACHE_PLANET_DST);
975
976
    $result = RestoreFleetToPlanet($this, $start, $result);
977
978
    $this->dbDelete();
979
980
    return $result;
981
  }
982
983
984
  // Resources access ***************************************************************************************************
985
986
  /**
987
   * Extracts resources value from db_row
988
   *
989
   * @param array $db_row
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 ExceptionPropertyAccess('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_update_adjust_by_id(
1119
        $planet_arrival['id'],
1120
        array(
1121
          'metal'     => +$fleet_resources[RES_METAL],
1122
          'crystal'   => +$fleet_resources[RES_CRYSTAL],
1123
          'deuterium' => +$fleet_resources[RES_DEUTERIUM],
1124
        )
1125
      );
1126
    }
1127
1128
    $this->resourcesReset();
1129
1130
    $result = CACHE_FLEET | ($start ? CACHE_PLANET_SRC : CACHE_PLANET_DST);
1131
1132
    return $result;
1133
  }
1134
1135
1136
  protected function isResource($unit_id) {
1137
    return UnitResourceLoot::is_in_group($unit_id);
1138
  }
1139
1140
  /**
1141
   * @param int $speed_percent
1142
   *
1143
   * @return array
1144
   */
1145
  protected function flt_travel_data($speed_percent = 10) {
1146
    $distance = $this->targetVector->distanceFromCoordinates($this->dbSourcePlanetRow);
1147
1148
    return $this->unitList->travelData($speed_percent, $distance, $this->dbOwnerRow);
1149
  }
1150
1151
1152
  /**
1153
   * @param array  $dbPlayerRow
1154
   * @param array  $dbPlanetRow
1155
   * @param Vector $targetVector
1156
   *
1157
   */
1158
  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...
1159
    $objFleet5Player = new Player();
1160
    $objFleet5Player->dbRowParse($dbPlayerRow);
1161
    $this->setLocatedAt($objFleet5Player);
1162
1163
    $this->mission_type = $mission;
1164
1165
    $this->dbOwnerRow = $dbPlayerRow;
1166
1167
    $this->set_start_planet($dbPlanetRow);
1168
    $this->dbSourcePlanetRow = $dbPlanetRow;
1169
1170
    $this->setTargetFromVectorObject($targetVector);
1171
    $this->targetVector = $targetVector;
1172
1173
//    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...
1174
//      $this->restrictTargetTypeByMission();
1175
//
1176
//      // TODO - Нельзя тут просто менять тип планеты или координат!
1177
//      // If current planet type is not allowed on mission - switch planet type
1178
//      if (empty($this->allowed_planet_types[$this->targetVector->type])) {
1179
//        $targetPlanetCoords->type = reset($this->allowed_planet_types);
1180
//      }
1181
//    }
1182
1183
    $this->populateTargetPlanetAndOwner();
1184
1185
    $this->unitsSetFromArray($ships);
1186
1187
    $this->_group_id = intval($fleet_group_mr);
1188
1189
    $this->oldSpeedInTens = $oldSpeedInTens;
1190
1191
    $this->targetedUnitId = $targetedUnitId;
1192
1193
    $this->captainId = $captainId;
1194
1195
    $this->_time_launch = SN_TIME_NOW;
1196
1197
    $this->renderParamCoordinates();
1198
1199
  }
1200
1201
  protected function restrictTargetTypeByMission() {
1202
    if ($this->_mission_type == MT_MISSILE) {
1203
      $this->allowed_planet_types = array(PT_PLANET => PT_PLANET);
1204
    } elseif ($this->_mission_type == MT_COLONIZE || $this->_mission_type == MT_EXPLORE) {
1205
      // TODO - PT_NONE
1206
      $this->allowed_planet_types = array(PT_PLANET => PT_PLANET);
1207
    } elseif ($this->_mission_type == MT_RECYCLE) {
1208
      $this->allowed_planet_types = array(PT_DEBRIS => PT_DEBRIS);
1209
    } elseif ($this->_mission_type == MT_DESTROY) {
1210
      $this->allowed_planet_types = array(PT_MOON => PT_MOON);
1211
    } else {
1212
      $this->allowed_planet_types = array(PT_PLANET => PT_PLANET, PT_MOON => PT_MOON);
1213
    }
1214
  }
1215
1216
  protected function populateTargetPlanetAndOwner() {
1217
    // If vector points to no exact object OR debris - then getting planet on coordinates
1218
    $targetVector = clone $this->targetVector;
1219
    if ($targetVector->type == PT_DEBRIS || $targetVector == PT_NONE) {
1220
      $targetVector->type = PT_PLANET;
1221
    }
1222
1223
    $this->dbTargetRow = DBStaticPlanet::db_planet_by_vector_object($targetVector);
1224 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...
1225
      $this->dbTargetOwnerRow = DBStaticUser::db_user_by_id($this->dbTargetRow['id_owner'], true);
0 ignored issues
show
Documentation Bug introduced by
It seems like \DBStatic\DBStaticUser::...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...
1226
    }
1227
  }
1228
1229
1230
  protected function printErrorIfNoShips() {
1231
    if ($this->unitList->unitsCount() <= 0) {
1232
      message(classLocale::$lang['fl_err_no_ships'], classLocale::$lang['fl_error'], 'fleet' . DOT_PHP_EX, 5);
1233
    }
1234
  }
1235
1236
  /**
1237
   */
1238
  public function renderParamCoordinates() {
1239
    global $template_result;
1240
    $template_result += array(
1241
      'thisgalaxy'      => $this->dbSourcePlanetRow['galaxy'],
1242
      'thissystem'      => $this->dbSourcePlanetRow['system'],
1243
      'thisplanet'      => $this->dbSourcePlanetRow['planet'],
1244
      'thisplanet_type' => $this->dbSourcePlanetRow['planet_type'],
1245
1246
      'galaxy'         => $this->targetVector->galaxy,
1247
      'system'         => $this->targetVector->system,
1248
      'planet'         => $this->targetVector->planet,
1249
      'planet_type'    => $this->targetVector->type,
1250
      'target_mission' => $this->_mission_type,
1251
      'MISSION_NAME'   => $this->_mission_type ? classLocale::$lang['type_mission'][$this->_mission_type] : '',
1252
1253
      'MT_COLONIZE' => MT_COLONIZE,
1254
    );
1255
  }
1256
1257
1258
  protected function renderFleetCoordinates($missionStartTimeStamp = SN_TIME_NOW, $timeMissionJob = 0) {
1259
    $timeToReturn = $this->travelData['duration'] * 2 + $timeMissionJob;
1260
1261
    return array(
1262
      'ID'                 => 1,
1263
      'START_TYPE_TEXT_SH' => classLocale::$lang['sys_planet_type_sh'][$this->dbSourcePlanetRow['planet_type']],
1264
      'START_COORDS'       => uni_render_coordinates($this->dbSourcePlanetRow),
1265
      'START_NAME'         => $this->dbSourcePlanetRow['name'],
1266
      'START_TIME_TEXT'    => date(FMT_DATE_TIME, $missionStartTimeStamp + $timeToReturn + SN_CLIENT_TIME_DIFF),
1267
      'START_LEFT'         => floor($timeToReturn),
1268
      'END_TYPE_TEXT_SH'   =>
1269
        !empty($this->targetVector->type)
1270
          ? classLocale::$lang['sys_planet_type_sh'][$this->targetVector->type]
1271
          : '',
1272
      'END_COORDS'         => uniRenderVector($this->targetVector),
1273
      'END_NAME'           => !empty($this->dbTargetRow['name']) ? $this->dbTargetRow['name'] : '',
1274
      'END_TIME_TEXT'      => date(FMT_DATE_TIME, $missionStartTimeStamp + $this->travelData['duration'] + SN_CLIENT_TIME_DIFF),
1275
      'END_LEFT'           => floor($this->travelData['duration']),
1276
    );
1277
  }
1278
1279
  /**
1280
   * @param int $missionStartTimeStamp
1281
   * @param int $timeMissionJob
1282
   *
1283
   * @return array
1284
   *
1285
   * @throws Exception
1286
   */
1287
  protected function renderFleet($missionStartTimeStamp = SN_TIME_NOW, $timeMissionJob = 0) {
1288
    $this->printErrorIfNoShips();
1289
1290
    $result = $this->renderFleetCoordinates($missionStartTimeStamp, $timeMissionJob);
1291
    $result['.']['ships'] = $this->unitList->unitsRender();
1292
1293
    return $result;
1294
  }
1295
1296
  /**
1297
   * @return array
1298
   */
1299
  protected function renderAllowedMissions() {
1300
    $result = array();
1301
1302
    ksort($this->allowed_missions);
1303
    // If mission is not set - setting first mission from allowed
1304
    if (empty($this->_mission_type) && is_array($this->allowed_missions)) {
1305
      reset($this->allowed_missions);
1306
      $this->_mission_type = key($this->allowed_missions);
1307
    }
1308
    foreach ($this->allowed_missions as $key => $value) {
1309
      $result[] = array(
1310
        'ID'   => $key,
1311
        'NAME' => classLocale::$lang['type_mission'][$key],
1312
      );
1313
    };
1314
1315
    return $result;
1316
  }
1317
1318
  /**
1319
   * @param $max_duration
1320
   *
1321
   * @return array
1322
   */
1323
  protected function renderDuration($max_duration) {
1324
    $result = array();
1325
1326
    if (!$max_duration) {
1327
      return $result;
1328
    }
1329
1330
    $config_game_speed_expedition = ($this->_mission_type == MT_EXPLORE && classSupernova::$config->game_speed_expedition ? classSupernova::$config->game_speed_expedition : 1);
1331
    for ($i = 1; $i <= $max_duration; $i++) {
1332
      $result[] = array(
1333
        'ID'   => $i,
1334
        'TIME' => pretty_time(ceil($i * 3600 / $config_game_speed_expedition)),
1335
      );
1336
    }
1337
1338
    return $result;
1339
  }
1340
1341
  /**
1342
   * @param array $planetResources
1343
   *
1344
   * @return array
1345
   */
1346
  // TODO - REDO to resource_id
1347
  protected function renderPlanetResources(&$planetResources) {
1348
    $result = array();
1349
1350
    $i = 0;
1351
    foreach ($planetResources as $resource_id => $resource_amount) {
1352
      $result[] = array(
1353
        'ID'        => $i++, // $resource_id,
1354
        'ON_PLANET' => $resource_amount,
1355
        'TEXT'      => pretty_number($resource_amount),
1356
        'NAME'      => classLocale::$lang['tech'][$resource_id],
1357
      );
1358
    }
1359
1360
    return $result;
1361
  }
1362
1363
  /**
1364
   * @return array
1365
   */
1366
  protected function renderAllowedPlanetTypes() {
1367
    $result = array();
1368
1369
    foreach ($this->allowed_planet_types as $possible_planet_type_id) {
1370
      $result[] = array(
1371
        'ID'         => $possible_planet_type_id,
1372
        'NAME'       => classLocale::$lang['sys_planet_type'][$possible_planet_type_id],
1373
        'NAME_SHORT' => classLocale::$lang['sys_planet_type_sh'][$possible_planet_type_id],
1374
      );
1375
    }
1376
1377
    return $result;
1378
  }
1379
1380
1381
  protected function renderFleet1TargetSelect(&$shortcut) {
1382
    global $note_priority_classes;
1383
1384
    $name = !empty($shortcut['title']) ? $shortcut['title'] : $shortcut['name'];
1385
1386
    $result = array(
1387
      'NAME'       => $name,
1388
      'GALAXY'     => $shortcut['galaxy'],
1389
      'SYSTEM'     => $shortcut['system'],
1390
      'PLANET'     => $shortcut['planet'],
1391
      'TYPE'       => $shortcut['planet_type'],
1392
      'TYPE_PRINT' => classLocale::$lang['fl_shrtcup'][$shortcut['planet_type']],
1393
    );
1394
1395
    if (isset($shortcut['priority'])) {
1396
      $result += array(
1397
        'PRIORITY'       => $shortcut['priority'],
1398
        'PRIORITY_CLASS' => $note_priority_classes[$shortcut['priority']],
1399
      );
1400
    }
1401
1402
    if (isset($shortcut['id'])) {
1403
      $result += array(
1404
        'ID' => $shortcut['id'],
1405
      );
1406
    }
1407
1408
    return $result;
1409
  }
1410
1411
  /**
1412
   * @return array
1413
   */
1414
  protected function renderFleetShortcuts() {
1415
    $result = array();
1416
1417
    // Building list of shortcuts
1418
    $query = DBStaticNote::db_note_list_select_by_owner_and_planet($this->dbOwnerRow);
1419
    while ($row = db_fetch($query)) {
1420
      $result[] = $this->renderFleet1TargetSelect($row);
1421
    }
1422
1423
    return $result;
1424
  }
1425
1426
  /**
1427
   * Building list of own planets & moons
1428
   *
1429
   * @return array
1430
   */
1431
  protected function renderOwnPlanets() {
1432
    $result = array();
1433
1434
    $colonies = DBStaticPlanet::db_planet_list_sorted($this->dbOwnerRow);
1435
    if (count($colonies) <= 1) {
1436
      return $result;
1437
    }
1438
1439
    foreach ($colonies as $row) {
1440
      if ($row['id'] == $this->dbSourcePlanetRow['id']) {
1441
        continue;
1442
      }
1443
1444
      $result[] = $this->renderFleet1TargetSelect($row);
1445
    }
1446
1447
    return $result;
1448
  }
1449
1450
  /**
1451
   * @return array
1452
   */
1453
  protected function renderACSList() {
1454
    $result = array();
1455
1456
    $query = DBStaticFleetACS::db_acs_get_list();
1457
    while ($row = db_fetch($query)) {
1458
      $members = explode(',', $row['eingeladen']);
1459
      foreach ($members as $a => $b) {
1460
        if ($b == $this->dbOwnerRow['id']) {
1461
          $result[] = $this->renderFleet1TargetSelect($row);
1462
        }
1463
      }
1464
    }
1465
1466
    return $result;
1467
  }
1468
1469
1470
  /**
1471
   * @param $template_result
1472
   */
1473
  protected function renderShipSortOptions(&$template_result) {
1474
    foreach (classLocale::$lang['player_option_fleet_ship_sort'] as $sort_id => $sort_text) {
1475
      $template_result['.']['ship_sort_list'][] = array(
1476
        'VALUE' => $sort_id,
1477
        'TEXT'  => $sort_text,
1478
      );
1479
    }
1480
    $template_result += array(
1481
      'FLEET_SHIP_SORT'         => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_SORT],
1482
      'FLEET_SHIP_SORT_INVERSE' => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_SORT_INVERSE],
1483
    );
1484
  }
1485
1486
1487
  /**
1488
   *
1489
   */
1490
  public function fleetPage0() {
1491
    global $template_result;
1492
1493
    lng_include('overview');
1494
1495
    if (empty($this->dbSourcePlanetRow)) {
1496
      message(classLocale::$lang['fl_noplanetrow'], classLocale::$lang['fl_error']);
1497
    }
1498
1499
    // TODO - redo to unitlist render/unit render
1500
    $template_result['.']['ships'] = $this->renderAvailableShips($this->dbOwnerRow, $this->dbSourcePlanetRow);
1501
1502
    $this->renderShipSortOptions($template_result);
1503
1504
    /**
1505
     * @var Player $playerOwner
1506
     */
1507
    $playerOwner = $this->getLocatedAt();
1508
1509
    $template_result += array(
1510
      'FLYING_FLEETS'      => $playerOwner->fleetsFlying(),
1511
      'MAX_FLEETS'         => $playerOwner->fleetsMax(),
1512
      'FREE_FLEETS'        => $playerOwner->fleetsMax() - $playerOwner->fleetsFlying(),
1513
      'FLYING_EXPEDITIONS' => $playerOwner->expeditionsFlying(),
1514
      'MAX_EXPEDITIONS'    => $playerOwner->expeditionsMax(),
1515
      'FREE_EXPEDITIONS'   => $playerOwner->expeditionsMax() - $playerOwner->expeditionsFlying(),
1516
      'COLONIES_CURRENT'   => $playerOwner->coloniesCurrent(),
1517
      'COLONIES_MAX'       => $playerOwner->coloniesMax(),
1518
1519
      'TYPE_NAME' => classLocale::$lang['fl_planettype'][$this->targetVector->type],
1520
1521
      'speed_factor' => flt_server_flight_speed_multiplier(),
1522
1523
      'PLANET_RESOURCES' => pretty_number($this->dbSourcePlanetRow['metal'] + $this->dbSourcePlanetRow['crystal'] + $this->dbSourcePlanetRow['deuterium']),
1524
      'PLANET_DEUTERIUM' => pretty_number($this->dbSourcePlanetRow['deuterium']),
1525
1526
      'PLAYER_OPTION_FLEET_SHIP_SELECT_OLD'       => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_SELECT_OLD],
1527
      'PLAYER_OPTION_FLEET_SHIP_HIDE_SPEED'       => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_HIDE_SPEED],
1528
      'PLAYER_OPTION_FLEET_SHIP_HIDE_CAPACITY'    => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_HIDE_CAPACITY],
1529
      'PLAYER_OPTION_FLEET_SHIP_HIDE_CONSUMPTION' => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_HIDE_CONSUMPTION],
1530
    );
1531
1532
    $template = gettemplate('fleet0', true);
1533
    $template->assign_recursive($template_result);
1534
    display($template, classLocale::$lang['fl_title']);
1535
  }
1536
1537
  /**
1538
   *
1539
   */
1540
  public function fleetPage1() {
1541
    global $template_result;
1542
1543
    $template_result['.']['fleets'][] = $this->renderFleet(SN_TIME_NOW);
1544
    $template_result['.']['possible_planet_type_id'] = $this->renderAllowedPlanetTypes();
1545
    $template_result['.']['colonies'] = $this->renderOwnPlanets();
1546
    $template_result['.']['shortcut'] = $this->renderFleetShortcuts();
1547
    $template_result['.']['acss'] = $this->renderACSList();
1548
1549
    $template_result += array(
1550
      'speed_factor' => flt_server_flight_speed_multiplier(),
1551
1552
      'fleet_speed'    => $this->fleetSpeed(),
1553
      'fleet_capacity' => $this->shipsGetCapacity(),
1554
1555
      'PLANET_DEUTERIUM' => pretty_number($this->dbSourcePlanetRow['deuterium']),
1556
1557
      'PAGE_HINT' => classLocale::$lang['fl_page1_hint'],
1558
    );
1559
1560
    $template = gettemplate('fleet1', true);
1561
    $template->assign_recursive($template_result);
1562
    display($template, classLocale::$lang['fl_title']);
1563
  }
1564
1565
  public function fleetSpeed() {
1566
    $maxSpeed = array();
1567
    foreach ($this->shipsIterator() as $ship_id => $unit) {
1568
      if ($unit->count > 0 && !empty(static::$snGroupFleetAndMissiles[$ship_id])) {
1569
        $single_ship_data = get_ship_data($ship_id, $this->dbOwnerRow);
1570
        $maxSpeed[$ship_id] = $single_ship_data['speed'];
1571
      }
1572
    }
1573
1574
    return empty($maxSpeed) ? 0 : min($maxSpeed);
1575
  }
1576
1577
  /**
1578
   * @param array $planetResourcesWithoutConsumption
1579
   */
1580
  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...
1581
    $this->travelData = $this->flt_travel_data($this->oldSpeedInTens);
1582
1583
//    /**
1584
//     * @var array $allowed_missions
1585
//     */
1586
//    public $allowed_missions = array();
1587
//    /**
1588
//     * @var array $exists_missions
1589
//     */
1590
//    public $exists_missions = array();
1591
//    public $allowed_planet_types = array(
1592
//      // PT_NONE => PT_NONE,
1593
//      PT_PLANET => PT_PLANET,
1594
//      PT_MOON   => PT_MOON,
1595
//      PT_DEBRIS => PT_DEBRIS
1596
//    );
1597
1598
//    $this->exists_missions = array(
1599
////      MT_EXPLORE => MT_EXPLORE,
1600
////      MT_MISSILE => MT_MISSILE,
1601
//      MT_COLONIZE => MT_COLONIZE,
1602
//    );  // TODO
1603
    $this->allowed_missions = array();
1604
1605
    if ($this->mission_type != MT_NONE && empty($this->exists_missions[$this->mission_type])) {
1606
      throw new ExceptionFleetInvalid(FLIGHT_MISSION_UNKNOWN, FLIGHT_MISSION_UNKNOWN);
1607
    }
1608
1609
    $this->validator->validateGlobals();
1610
1611
    $validateResult = array();
1612
    foreach ($this->exists_missions as $missionType => $missionData) {
1613
//print('qwe');
1614
      $mission = \Mission\MissionFactory::build($missionType, $this);
1615
//print('wer');
1616
      $validateResult[$missionType] = $mission->validate();
1617
      if (FLIGHT_ALLOWED == $validateResult[$missionType]) {
1618
        $this->allowed_missions[$missionType] = $mission;
1619
      } else {
1620
        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...
1621
        }
1622
        unset($this->allowed_missions[$missionType]);
1623
      }
1624
    }
1625
1626
    if(empty($this->allowed_missions)) {
1627
      if($this->mission_type != MT_NONE && isset($validateResult[$this->mission_type])) {
1628
        throw new ExceptionFleetInvalid($validateResult[$this->mission_type], $validateResult[$this->mission_type]);
1629
      } else {
1630
        throw new ExceptionFleetInvalid(FLIGHT_MISSION_IMPOSSIBLE, FLIGHT_MISSION_IMPOSSIBLE);
1631
      }
1632
    }
1633
1634
//    $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...
1635
  }
1636
1637
  /**
1638
   * @param array $planetResourcesWithoutConsumption
1639
   */
1640
  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...
1641
    $this->travelData = $this->flt_travel_data($this->oldSpeedInTens);
1642
1643
    if (empty($this->exists_missions[$this->mission_type])) {
1644
      throw new ExceptionFleetInvalid(FLIGHT_MISSION_UNKNOWN, FLIGHT_MISSION_UNKNOWN);
1645
    }
1646
1647
    $this->validator->validateGlobals();
1648
1649
    $mission = \Mission\MissionFactory::build($this->mission_type, $this);
1650
    $result = $mission->validate();
1651
    if (FLIGHT_ALLOWED != $result) {
1652
      throw new ExceptionFleetInvalid($result, $result);
1653
    }
1654
1655
  }
1656
1657
  /**
1658
   *
1659
   */
1660
  public function fleetPage2() {
1661
    global $template_result;
1662
1663
    $planetResourcesTotal = DBStaticPlanet::getResources($this->dbOwnerRow, $this->dbSourcePlanetRow);
1664
    $planetResourcesWithoutConsumption = $this->resourcesSubstractConsumption($planetResourcesTotal);
1665
1666
    try {
1667
      $this->fleetPage2Prepare($planetResourcesWithoutConsumption);
1668
    } catch (Exception $e) {
1669
      // TODO - MESSAGE BOX
1670 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...
1671
        sn_db_transaction_rollback();
1672
        pdie(classLocale::$lang['fl_attack_error'][$e->getCode()]);
1673
      } else {
1674
        throw $e;
1675
      }
1676
    }
1677
1678
    // Flight allowed here
1679
    pdump('FLIGHT_ALLOWED', FLIGHT_ALLOWED);
1680
//    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...
1681
1682
    $template_result['.']['missions'] = $this->renderAllowedMissions();
1683
1684
    $template_result['.']['fleets'][] = $this->renderFleet(SN_TIME_NOW);
1685
1686
    $max_duration =
1687
      $this->_mission_type == MT_EXPLORE
1688
        ? get_player_max_expedition_duration($this->dbOwnerRow)
1689
        : (isset($this->allowed_missions[MT_HOLD]) ? 12 : 0);
1690
    $template_result['.']['duration'] = $this->renderDuration($max_duration);
1691
1692
    $this->captainGet();
1693
    $template_result += $this->renderCaptain();
1694
1695
    $template_result['.']['resources'] = $this->renderPlanetResources($planetResourcesWithoutConsumption);
1696
1697
    $template_result += array(
1698
      'planet_metal'     => $planetResourcesWithoutConsumption[RES_METAL],
1699
      'planet_crystal'   => $planetResourcesWithoutConsumption[RES_CRYSTAL],
1700
      'planet_deuterium' => $planetResourcesWithoutConsumption[RES_DEUTERIUM],
1701
1702
      'fleet_capacity' => $this->shipsGetCapacity() - $this->travelData['consumption'],
1703
      'speed'          => $this->oldSpeedInTens,
1704
      'fleet_group'    => $this->_group_id,
1705
1706
      'MAX_DURATION'          => $max_duration,
1707
1708
      // 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...
1709
//      'IS_TRANSPORT_MISSIONS' => !empty($this->allowed_missions[$this->_mission_type]['transport']),
1710
      'IS_TRANSPORT_MISSIONS' => true,
1711
1712
      'PLAYER_COLONIES_CURRENT' => get_player_current_colonies($this->dbOwnerRow),
1713
      'PLAYER_COLONIES_MAX'     => get_player_max_colonies($this->dbOwnerRow),
1714
    );
1715
1716
    $template = gettemplate('fleet2', true);
1717
    $template->assign_recursive($template_result);
1718
    display($template, classLocale::$lang['fl_title']);
1719
  }
1720
1721
  /**
1722
   *
1723
   */
1724
  public function fleetPage3() {
1725
    global $template_result;
1726
1727
    $this->isRealFlight = true;
1728
1729
    sn_db_transaction_start();
1730
1731
    DBStaticUser::db_user_lock_with_target_owner_and_acs($this->dbOwnerRow, $this->dbTargetRow);
1732
1733
    // Checking for group
1734
    $this->groupCheck();
1735
1736
    $this->dbOwnerRow = DBStaticUser::db_user_by_id($this->dbOwnerRow['id'], true);
0 ignored issues
show
Documentation Bug introduced by
It seems like \DBStatic\DBStaticUser::...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...
1737
    $this->dbSourcePlanetRow = DBStaticPlanet::db_planet_by_id($this->dbSourcePlanetRow['id'], true);
0 ignored issues
show
Documentation Bug introduced by
It seems like \DBStatic\DBStaticPlanet...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...
1738
    if (!empty($this->dbTargetRow['id'])) {
1739
      $this->dbTargetRow = DBStaticPlanet::db_planet_by_id($this->dbTargetRow['id'], true);
0 ignored issues
show
Documentation Bug introduced by
It seems like \DBStatic\DBStaticPlanet...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...
1740
    }
1741
    // TODO - deprecated! Filled in populateTargetPlanetAndOwner
1742 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...
1743
      $this->dbTargetOwnerRow = DBStaticUser::db_user_by_id($this->dbTargetRow['id_owner'], true);
0 ignored issues
show
Documentation Bug introduced by
It seems like \DBStatic\DBStaticUser::...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...
1744
    }
1745
1746
    $this->resource_list = array(
1747
      RES_METAL     => max(0, floor(sys_get_param_float('resource0'))),
1748
      RES_CRYSTAL   => max(0, floor(sys_get_param_float('resource1'))),
1749
      RES_DEUTERIUM => max(0, floor(sys_get_param_float('resource2'))),
1750
    );
1751
1752
    $this->captainGet();
1753
1754
    $this->travelData = $this->flt_travel_data($this->oldSpeedInTens);
1755
1756
    $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, DBStatic\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, DBStatic\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...
1757
    $planetResourcesWithoutConsumption = $this->resourcesSubstractConsumption($planetResourcesTotal);
1758
1759
    try {
1760
      $this->fleetPage3Prepare($planetResourcesWithoutConsumption);
1761
    } catch (Exception $e) {
1762
      // TODO - MESSAGE BOX
1763 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...
1764
        sn_db_transaction_rollback();
1765
        pdie(classLocale::$lang['fl_attack_error'][$e->getCode()]);
1766
      } else {
1767
        throw $e;
1768
      }
1769
    }
1770
1771
//    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...
1772
//      $validator = new FleetValidator($this);
1773
//      $validator->validate();
1774
//    } catch (Exception $e) {
1775
//      // TODO - MESSAGE BOX
1776
//      if($e instanceof Exception\ExceptionFleetInvalid) {
1777
//        sn_db_transaction_rollback();
1778
//        pdie(classLocale::$lang['fl_attack_error'][$e->getCode()]);
1779
//      } else {
1780
//        throw $e;
1781
//      }
1782
//    }
1783
1784
    // TODO - check if mission is not 0 and in ALLOWED_MISSIONS
1785
1786
    // Flight allowed here
1787
    pdump('FLIGHT_ALLOWED', FLIGHT_ALLOWED);
1788
//    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...
1789
1790
1791
    $timeMissionJob = 0;
1792
    // TODO check for empty mission AKA mission allowed
1793
    /*
1794
        if ($this->_mission_type == MT_ACS && $aks) {
1795
          $acsTimeToArrive = $aks['ankunft'] - SN_TIME_NOW;
1796
          if ($acsTimeToArrive < $this->travelData['duration']) {
1797
            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']);
1798
          }
1799
          // Set time to travel to ACS' TTT
1800
          $this->travelData['duration'] = $acsTimeToArrive;
1801
    */
1802
    if ($this->_mission_type != MT_ACS) {
1803
      if ($this->_mission_type == MT_EXPLORE || $this->_mission_type == MT_HOLD) {
1804
        $max_duration = $this->_mission_type == MT_EXPLORE ? get_player_max_expedition_duration($this->dbOwnerRow) : ($this->_mission_type == MT_HOLD ? 12 : 0);
1805
        if ($max_duration) {
1806
          $mission_time_in_hours = sys_get_param_id('missiontime');
1807
          if ($mission_time_in_hours > $max_duration || $mission_time_in_hours < 1) {
1808
            classSupernova::$debug->warning('Supplying wrong mission time', 'Hack attempt', 302, array('base_dump' => true));
1809
            die();
1810
          }
1811
          $timeMissionJob = ceil($mission_time_in_hours * 3600 / ($this->_mission_type == MT_EXPLORE && classSupernova::$config->game_speed_expedition ? classSupernova::$config->game_speed_expedition : 1));
1812
        }
1813
      }
1814
    }
1815
1816
    //
1817
    //
1818
    //
1819
    //
1820
    //
1821
    //
1822
    //
1823
    //
1824
    // ---------------- END OF CHECKS ------------------------------------------------------
1825
1826
    $this->set_times($this->travelData['duration'], $timeMissionJob);
1827
    $this->dbInsert();
1828
    $this->unitList->dbSubstractUnitsFromPlanet($this->dbOwnerRow, $this->dbSourcePlanetRow['id']);
1829
1830
    DBStaticPlanet::db_planet_update_adjust_by_id(
1831
      $this->dbSourcePlanetRow['id'],
1832
      array(
1833
        'metal'     => -$this->resource_list[RES_METAL],
1834
        'crystal'   => -$this->resource_list[RES_CRYSTAL],
1835
        'deuterium' => -$this->resource_list[RES_DEUTERIUM] - $this->travelData['consumption'],
1836
      )
1837
    );
1838
1839
    if (!empty($this->captain['unit_id'])) {
1840
      DBStaticUnit::db_unit_set_by_id(
1841
        $this->captain['unit_id'],
1842
        array(
1843
          'unit_location_type' => LOC_FLEET,
1844
          'unit_location_id'   => $this->_dbId,
1845
        ),
1846
        array()
1847
      );
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 \DBStatic\DBStaticPlanet...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
1945
if (empty(Fleet::$snGroupFleet)) {
1946
  Fleet::$snGroupFleet = sn_get_groups('fleet');
1947
  Fleet::$snGroupFleetAndMissiles = sn_get_groups(array('fleet', GROUP_STR_MISSILES));
1948
  Fleet::$snGroupRecyclers = sn_get_groups('flt_recyclers');
1949
}
1950