Completed
Push — work-fleets ( 17c73c...5437e0 )
by SuperNova.WS
05:14
created

Fleet::isEmpty()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
c 4
b 0
f 0
dl 0
loc 3
rs 10
cc 2
eloc 2
nc 2
nop 0
1
<?php
2
3
/**
4
 * Class Fleet
5
 *
6
 * @property int dbId
7
 * @property int playerOwnerId
8
 * @property int group_id
9
 * @property int mission_type
10
 * @property int target_owner_id
11
 * @property int is_returning
12
 *
13
 * @property int time_launch
14
 * @property int time_arrive_to_target
15
 * @property int time_mission_job_complete
16
 * @property int time_return_to_source
17
 *
18
 * @property int fleet_start_planet_id
19
 * @property int fleet_start_galaxy
20
 * @property int fleet_start_system
21
 * @property int fleet_start_planet
22
 * @property int fleet_start_type
23
 *
24
 * @property int fleet_end_planet_id
25
 * @property int fleet_end_galaxy
26
 * @property int fleet_end_system
27
 * @property int fleet_end_planet
28
 * @property int fleet_end_type
29
 *
30
 */
31
class Fleet extends UnitContainer {
32
33
  // DBRow inheritance *************************************************************************************************
34
35
  /**
36
   * Table name in DB
37
   *
38
   * @var string
39
   */
40
  protected static $_table = 'fleets';
41
  /**
42
   * Name of ID field in DB
43
   *
44
   * @var string
45
   */
46
  protected static $_dbIdFieldName = 'fleet_id';
47
  /**
48
   * DB_ROW to Class translation scheme
49
   *
50
   * @var array
51
   */
52
  protected static $_properties = array(
53
    'dbId'          => array(
54
      P_DB_FIELD => 'fleet_id',
55
    ),
56
    'playerOwnerId' => array(
57
      P_METHOD_EXTRACT => 'ownerExtract',
58
      P_METHOD_INJECT  => 'ownerInject',
59
//      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...
60
    ),
61
    'mission_type'  => array(
62
      P_DB_FIELD   => 'fleet_mission',
63
      P_FUNC_INPUT => 'intval',
64
    ),
65
66
    'target_owner_id' => array(
67
      P_DB_FIELD => 'fleet_target_owner',
68
    ),
69
    'group_id'        => array(
70
      P_DB_FIELD => 'fleet_group',
71
    ),
72
    'is_returning'    => array(
73
      P_DB_FIELD   => 'fleet_mess',
74
      P_FUNC_INPUT => 'intval',
75
    ),
76
77
    'shipCount' => array(
78
      P_DB_FIELD  => 'fleet_amount',
79
// 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...
80
//      P_FUNC_OUTPUT => 'get_ship_count',
81
//      P_DB_FIELDS_LINKED => array(
82
//        'fleet_amount',
83
//      ),
84
      P_READ_ONLY => true,
85
    ),
86
87
    'time_launch' => array(
88
      P_DB_FIELD => 'start_time',
89
    ),
90
91
    'time_arrive_to_target'     => array(
92
      P_DB_FIELD => 'fleet_start_time',
93
    ),
94
    'time_mission_job_complete' => array(
95
      P_DB_FIELD => 'fleet_end_stay',
96
    ),
97
    'time_return_to_source'     => array(
98
      P_DB_FIELD => 'fleet_end_time',
99
    ),
100
101
    'fleet_start_planet_id' => array(
102
      P_DB_FIELD   => 'fleet_start_planet_id',
103
      P_FUNC_INPUT => 'nullIfEmpty',
104
    ),
105
106
    'fleet_start_galaxy' => array(
107
      P_DB_FIELD => 'fleet_start_galaxy',
108
    ),
109
    'fleet_start_system' => array(
110
      P_DB_FIELD => 'fleet_start_system',
111
    ),
112
    'fleet_start_planet' => array(
113
      P_DB_FIELD => 'fleet_start_planet',
114
    ),
115
    'fleet_start_type'   => array(
116
      P_DB_FIELD => 'fleet_start_type',
117
    ),
118
119
    'fleet_end_planet_id' => array(
120
      P_DB_FIELD   => 'fleet_end_planet_id',
121
      P_FUNC_INPUT => 'nullIfEmpty',
122
    ),
123
    'fleet_end_galaxy'    => array(
124
      P_DB_FIELD => 'fleet_end_galaxy',
125
    ),
126
    'fleet_end_system'    => array(
127
      P_DB_FIELD => 'fleet_end_system',
128
    ),
129
    'fleet_end_planet'    => array(
130
      P_DB_FIELD => 'fleet_end_planet',
131
    ),
132
    'fleet_end_type'      => array(
133
      P_DB_FIELD => 'fleet_end_type',
134
    ),
135
136
    'resource_list' => array(
137
      P_METHOD_EXTRACT   => 'resourcesExtract',
138
      P_METHOD_INJECT    => 'resourcesInject',
139
      P_DB_FIELDS_LINKED => array(
140
        'fleet_resource_metal',
141
        'fleet_resource_crystal',
142
        'fleet_resource_deuterium',
143
      ),
144
    ),
145
  );
146
147
148
  // UnitContainer inheritance *****************************************************************************************
149
  /**
150
   * Type of this location
151
   *
152
   * @var int $locationType
153
   */
154
  protected static $locationType = LOC_FLEET;
155
156
157
  // New properties ****************************************************************************************************
158
  /**
159
   * `fleet_owner`
160
   *
161
   * @var int
162
   */
163
  protected $_playerOwnerId = 0;
164
  /**
165
   * `fleet_group`
166
   *
167
   * @var int
168
   */
169
  protected $_group_id = 0;
170
171
  /**
172
   * `fleet_mission`
173
   *
174
   * @var int
175
   */
176
  protected $_mission_type = 0;
177
178
  /**
179
   * `fleet_target_owner`
180
   *
181
   * @var int
182
   */
183
  protected $_target_owner_id = null;
184
185
  /**
186
   * @var array
187
   */
188
  protected $resource_list = array(
189
    RES_METAL     => 0,
190
    RES_CRYSTAL   => 0,
191
    RES_DEUTERIUM => 0,
192
  );
193
194
195
  /**
196
   * `fleet__mess` - Флаг возвращающегося флота
197
   *
198
   * @var int
199
   */
200
  protected $_is_returning = 0;
201
  /**
202
   * `start_time` - Время отправления - таймштамп взлёта флота из точки отправления
203
   *
204
   * @var int $_time_launch
205
   */
206
  protected $_time_launch = 0; // `start_time` = SN_TIME_NOW
207
  /**
208
   * `fleet_start_time` - Время прибытия в точку миссии/время начала выполнения миссии
209
   *
210
   * @var int $_time_arrive_to_target
211
   */
212
  protected $_time_arrive_to_target = 0; // `fleet_start_time` = SN_TIME_NOW + $time_travel
213
  /**
214
   * `fleet_end_stay` - Время окончания миссии в точке назначения
215
   *
216
   * @var int $_time_mission_job_complete
217
   */
218
  protected $_time_mission_job_complete = 0; // `fleet_end_stay`
219
  /**
220
   * `fleet_end_time` - Время возвращения флота после окончания миссии
221
   *
222
   * @var int $_time_return_to_source
223
   */
224
  protected $_time_return_to_source = 0; // `fleet_end_time`
225
226
227
  protected $_fleet_start_planet_id = null;
228
  protected $_fleet_start_galaxy = 0;
229
  protected $_fleet_start_system = 0;
230
  protected $_fleet_start_planet = 0;
231
  protected $_fleet_start_type = PT_ALL;
232
233
  protected $_fleet_end_planet_id = null;
234
  protected $_fleet_end_galaxy = 0;
235
  protected $_fleet_end_system = 0;
236
  protected $_fleet_end_planet = 0;
237
  protected $_fleet_end_type = PT_ALL;
238
239
  // Missile properties
240
  public $missile_target = 0;
241
242
  // Fleet event properties
243
  public $fleet_start_name = '';
244
  public $fleet_end_name = '';
245
  public $ov_label = '';
246
  public $ov_this_planet = '';
247
  public $event_time = 0;
248
249
  protected $resource_delta = array();
250
  protected $resource_replace = array();
251
252
253
//
254
255
256
  /**
257
   * @var array $allowed_missions
258
   */
259
  protected $allowed_missions = array();
260
  /**
261
   * @var array $exists_missions
262
   */
263
  protected $exists_missions = array();
264
  protected $allowed_planet_types = array(
265
    // PT_NONE => PT_NONE,
266
    PT_PLANET => PT_PLANET,
267
    PT_MOON   => PT_MOON,
268
    PT_DEBRIS => PT_DEBRIS
269
  );
270
271
  // TODO - Move to Player
272
  public $dbOwnerRow = array();
273
  public $dbSourcePlanetRow = array();
274
275
  /**
276
   * GSPT coordinates of target
277
   *
278
   * @var Vector
279
   */
280
  public $targetVector = array();
281
  /**
282
   * Target planet row
283
   *
284
   * @var array
285
   */
286
  public $dbTargetRow = array();
287
  public $dbTargetOwnerRow = array();
288
289
  /**
290
   * Fleet speed - old in 1/10 of 100%
291
   *
292
   * @var int
293
   */
294
  public $oldSpeedInTens = 0;
295
296
  public $tempPlayerMaxFleets = 0;
297
  public $travelData = array();
298
299
  protected $isRealFlight = false;
300
301
  /**
302
   * @var int $targetedUnitId
303
   */
304
  public $targetedUnitId = 0;
305
306
  /**
307
   * Fleet constructor.
308
   */
309
  public function __construct() {
310
    parent::__construct();
311
    $this->exists_missions = sn_get_groups('missions');
312
    $this->allowed_missions = $this->exists_missions;
313
  }
314
315
  /**
316
   * @param array $template_result
317
   * @param array $playerRow
318
   * @param array $planetRow
319
   */
320
  // TODO - redo to unit/unitlist renderer
321
  public function renderAvailableShips(&$template_result, $playerRow, $planetRow) {
322
    $record_index = 0;
323
    $ship_list = array();
324
    foreach (sn_get_groups('fleet') as $n => $unit_id) {
325
      $unit_level = mrc_get_level($playerRow, $planetRow, $unit_id, false, true);
326
      if ($unit_level <= 0) {
327
        continue;
328
      }
329
      $ship_data = get_ship_data($unit_id, $playerRow);
330
      $ship_list[$unit_id] = array(
331
        '__INDEX'          => $record_index++,
332
        'ID'               => $unit_id,
333
        'NAME'             => classLocale::$lang['tech'][$unit_id],
334
        'AMOUNT'           => $unit_level,
335
        'AMOUNT_TEXT'      => pretty_number($unit_level),
336
        'CONSUMPTION'      => $ship_data['consumption'],
337
        'CONSUMPTION_TEXT' => pretty_number($ship_data['consumption']),
338
        'SPEED'            => $ship_data['speed'],
339
        'SPEED_TEXT'       => pretty_number($ship_data['speed']),
340
        'CAPACITY'         => $ship_data['capacity'],
341
        'CAPACITY_TEXT'    => pretty_number($ship_data['capacity']),
342
      );
343
    }
344
345
    sortUnitRenderedList($ship_list, classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_SORT], classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_SORT_INVERSE]);
346
347
    foreach ($ship_list as $ship_data) {
348
      $template_result['.']['ships'][] = $ship_data;
349
    }
350
  }
351
352
  public function isEmpty() {
353
    return !$this->resourcesGetTotal() && !$this->shipsGetTotal();
354
  }
355
356
//  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...
357
//    return $this->playerOwnerId;
358
//  }
359
360
  /**
361
   * Initializes Fleet from user params and posts it to DB
362
   */
363
  public function dbInsert() {
364
    // WARNING! MISSION TIMES MUST BE SET WITH set_times() method!
365
    // TODO - more checks!
366
    if (empty($this->_time_launch)) {
367
      die('Fleet time not set!');
368
    }
369
370
    parent::dbInsert();
371
  }
372
373
374
  /* FLEET DB ACCESS =================================================================================================*/
375
376
  /**
377
   * LOCK - Lock all records which can be used with mission
378
   *
379
   * @param $mission_data
380
   *
381
   * @return array|bool|mysqli_result|null
382
   */
383
  public function dbLockFlying(&$mission_data) {
384
    // Тупо лочим всех юзеров, чьи флоты летят или улетают с координат отбытия/прибытия $fleet_row
385
    // Что бы делать это умно - надо учитывать fleet__mess во $fleet_row и в таблице fleets
386
387
    $fleet_id_safe = idval($this->_dbId);
388
389
    return doquery(
390
    // Блокировка самого флота
391
      "SELECT 1 FROM {{fleets}} AS f " .
392
393
      // Блокировка всех юнитов, принадлежащих этому флоту
394
      "LEFT JOIN {{unit}} as unit ON unit.unit_location_type = " . static::$locationType . " AND unit.unit_location_id = f.fleet_id " .
395
396
      // Блокировка всех прилетающих и улетающих флотов, если нужно
397
      // TODO - lock fleets by COORDINATES
398
      ($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 " : '') .
399
      // Блокировка всех юнитов, принадлежащих прилетающим и улетающим флотам - ufd = unit_fleet_destination
400
      ($mission_data['dst_fleets'] ? "LEFT JOIN {{unit}} AS ufd ON ufd.unit_location_type = " . static::$locationType . " AND ufd.unit_location_id = fd.fleet_id " : '') .
401
402
      ($mission_data['dst_user'] || $mission_data['dst_planet'] ? "LEFT JOIN {{users}} AS ud ON ud.id = f.fleet_target_owner " : '') .
403
      // Блокировка всех юнитов, принадлежащих владельцу планеты-цели
404
      ($mission_data['dst_user'] || $mission_data['dst_planet'] ? "LEFT JOIN {{unit}} AS unit_player_dest ON unit_player_dest.unit_player_id = ud.id " : '') .
405
      // Блокировка планеты-цели
406
      ($mission_data['dst_planet'] ? "LEFT JOIN {{planets}} AS pd ON pd.id = f.fleet_end_planet_id " : '') .
407
      // Блокировка всех юнитов, принадлежащих планете-цели - НЕ НУЖНО. Уже залочили ранее, как принадлежащие игроку-цели
408
//      ($mission_data['dst_planet'] ? "LEFT JOIN {{unit}} AS upd ON upd.unit_location_type = " . LOC_PLANET . " AND upd.unit_location_id = pd.id " : '') .
409
410
411
      ($mission_data['src_user'] || $mission_data['src_planet'] ? "LEFT JOIN {{users}} AS us ON us.id = f.fleet_owner " : '') .
412
      // Блокировка всех юнитов, принадлежащих владельцу флота
413
      ($mission_data['src_user'] || $mission_data['src_planet'] ? "LEFT JOIN {{unit}} AS unit_player_src ON unit_player_src.unit_player_id = us.id " : '') .
414
      // Блокировка планеты отправления
415
      ($mission_data['src_planet'] ? "LEFT JOIN {{planets}} AS ps ON ps.id = f.fleet_start_planet_id " : '') .
416
      // Блокировка всех юнитов, принадлежащих планете с которой юниты были отправлены - НЕ НУЖНО. Уже залочили ранее, как принадлежащие владельцу флота
417
//      ($mission_data['src_planet'] ? "LEFT JOIN {{unit}} AS ups ON ups.unit_location_type = " . LOC_PLANET . " AND ups.unit_location_id = ps.id " : '') .
418
419
      "WHERE f.fleet_id = {$fleet_id_safe} GROUP BY 1 FOR UPDATE"
420
    );
421
  }
422
423
  /**
424
   * Lock all fields that belongs to operation
425
   *
426
   * @param $dbId
427
   */
428
  // TODO = make static
429
  public function dbGetLockById($dbId) {
430
    doquery(
431
    // Блокировка самого флота
432
      "SELECT 1 FROM {{fleets}} AS FLEET0 " .
433
      // Lock fleet owner
434
      "LEFT JOIN {{users}} as USER0 on USER0.id = FLEET0.fleet_owner " .
435
      // Блокировка всех юнитов, принадлежащих этому флоту
436
      "LEFT JOIN {{unit}} as UNIT0 ON UNIT0.unit_location_type = " . LOC_FLEET . " AND UNIT0.unit_location_id = FLEET0.fleet_id " .
437
438
      // Без предварительной выборки неизвестно - куда летит этот флот.
439
      // Поэтому надо выбирать флоты, чьи координаты прибытия ИЛИ отбытия совпадают с координатами прибытия ИЛИ отбытия текущего флота.
440
      // Получаем матрицу 2х2 - т.е. 4 подзапроса.
441
      // При блокировке всегда нужно выбирать И лпанету, И луну - поскольку при бое на орбите луны обломки падают на орбиту планеты.
442
      // Поэтому тип планеты не указывается
443
444
      // Lock fleet heading to destination planet. Only if FLEET0.fleet_mess == 0
445
      "LEFT JOIN {{fleets}} AS FLEET1 ON
446
        FLEET1.fleet_mess = 0 AND FLEET0.fleet_mess = 0 AND
447
        FLEET1.fleet_end_galaxy = FLEET0.fleet_end_galaxy AND
448
        FLEET1.fleet_end_system = FLEET0.fleet_end_system AND
449
        FLEET1.fleet_end_planet = FLEET0.fleet_end_planet
450
      " .
451
      // Блокировка всех юнитов, принадлежащих этим флотам
452
      "LEFT JOIN {{unit}} as UNIT1 ON UNIT1.unit_location_type = " . LOC_FLEET . " AND UNIT1.unit_location_id = FLEET1.fleet_id " .
453
      // Lock fleet owner
454
      "LEFT JOIN {{users}} as USER1 on USER1.id = FLEET1.fleet_owner " .
455
456
      "LEFT JOIN {{fleets}} AS FLEET2 ON
457
        FLEET2.fleet_mess = 1   AND FLEET0.fleet_mess = 0 AND
458
        FLEET2.fleet_start_galaxy = FLEET0.fleet_end_galaxy AND
459
        FLEET2.fleet_start_system = FLEET0.fleet_end_system AND
460
        FLEET2.fleet_start_planet = FLEET0.fleet_end_planet
461
      " .
462
      // Блокировка всех юнитов, принадлежащих этим флотам
463
      "LEFT JOIN {{unit}} as UNIT2 ON
464
        UNIT2.unit_location_type = " . LOC_FLEET . " AND
465
        UNIT2.unit_location_id = FLEET2.fleet_id
466
      " .
467
      // Lock fleet owner
468
      "LEFT JOIN {{users}} as USER2 on
469
        USER2.id = FLEET2.fleet_owner
470
      " .
471
472
      // Lock fleet heading to source planet. Only if FLEET0.fleet_mess == 1
473
      "LEFT JOIN {{fleets}} AS FLEET3 ON
474
        FLEET3.fleet_mess = 0 AND FLEET0.fleet_mess = 1 AND
475
        FLEET3.fleet_end_galaxy = FLEET0.fleet_start_galaxy AND
476
        FLEET3.fleet_end_system = FLEET0.fleet_start_system AND
477
        FLEET3.fleet_end_planet = FLEET0.fleet_start_planet
478
      " .
479
      // Блокировка всех юнитов, принадлежащих этим флотам
480
      "LEFT JOIN {{unit}} as UNIT3 ON
481
        UNIT3.unit_location_type = " . LOC_FLEET . " AND
482
        UNIT3.unit_location_id = FLEET3.fleet_id
483
      " .
484
      // Lock fleet owner
485
      "LEFT JOIN {{users}} as USER3 on USER3.id = FLEET3.fleet_owner " .
486
487
      "LEFT JOIN {{fleets}} AS FLEET4 ON
488
        FLEET4.fleet_mess = 1   AND FLEET0.fleet_mess = 1 AND
489
        FLEET4.fleet_start_galaxy = FLEET0.fleet_start_galaxy AND
490
        FLEET4.fleet_start_system = FLEET0.fleet_start_system AND
491
        FLEET4.fleet_start_planet = FLEET0.fleet_start_planet
492
      " .
493
      // Блокировка всех юнитов, принадлежащих этим флотам
494
      "LEFT JOIN {{unit}} as UNIT4 ON
495
        UNIT4.unit_location_type = " . LOC_FLEET . " AND
496
        UNIT4.unit_location_id = FLEET4.fleet_id
497
      " .
498
      // Lock fleet owner
499
      "LEFT JOIN {{users}} as USER4 on
500
        USER4.id = FLEET4.fleet_owner
501
      " .
502
503
504
      // Locking start planet
505
      "LEFT JOIN {{planets}} AS PLANETS5 ON
506
        FLEET0.fleet_mess = 1 AND
507
        PLANETS5.galaxy = FLEET0.fleet_start_galaxy AND
508
        PLANETS5.system = FLEET0.fleet_start_system AND
509
        PLANETS5.planet = FLEET0.fleet_start_planet
510
      " .
511
      // Lock planet owner
512
      "LEFT JOIN {{users}} as USER5 on
513
        USER5.id = PLANETS5.id_owner
514
      " .
515
      // Блокировка всех юнитов, принадлежащих этой планете
516
      "LEFT JOIN {{unit}} as UNIT5 ON
517
        UNIT5.unit_location_type = " . LOC_PLANET . " AND
518
        UNIT5.unit_location_id = PLANETS5.id
519
      " .
520
521
522
      // Locking destination planet
523
      "LEFT JOIN {{planets}} AS PLANETS6 ON
524
        FLEET0.fleet_mess = 0 AND
525
        PLANETS6.galaxy = FLEET0.fleet_end_galaxy AND
526
        PLANETS6.system = FLEET0.fleet_end_system AND
527
        PLANETS6.planet = FLEET0.fleet_end_planet
528
      " .
529
      // Lock planet owner
530
      "LEFT JOIN {{users}} as USER6 on
531
        USER6.id = PLANETS6.id_owner
532
      " .
533
      // Блокировка всех юнитов, принадлежащих этой планете
534
      "LEFT JOIN {{unit}} as UNIT6 ON
535
        UNIT6.unit_location_type = " . LOC_PLANET . " AND
536
        UNIT6.unit_location_id = PLANETS6.id
537
      " .
538
      "WHERE FLEET0.fleet_id = {$dbId} GROUP BY 1 FOR UPDATE"
539
    );
540
  }
541
542
543
  public function dbRowParse($db_row) {
544
    parent::dbRowParse($db_row); // TODO: Change the autogenerated stub
545
    $player = new Player();
546
    $player->dbLoad($db_row['fleet_owner']);
547
    $this->setLocatedAt($player);
548
  }
549
550
  /* FLEET HELPERS =====================================================================================================*/
551
  /**
552
   * Forcibly returns fleet before time outs
553
   */
554
  public function commandReturn() {
555
    $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;
556
557
    $this->markReturned();
558
559
    // Считаем, что флот уже долетел TODO
560
    $this->time_arrive_to_target = SN_TIME_NOW;
561
    // Убираем флот из группы
562
    $this->group_id = 0;
563
    // Отменяем работу в точке назначения
564
    $this->time_mission_job_complete = 0;
565
    // TODO - правильно вычслять время возвращения - по проделанному пути, а не по старому времени возвращения
566
    $this->time_return_to_source = $ReturnFlyingTime;
567
568
    // Записываем изменения в БД
569
    $this->dbSave();
570
571
    if ($this->_group_id) {
572
      // TODO: Make here to delete only one AKS - by adding aks_fleet_count to AKS table
573
      db_fleet_aks_purge();
574
    }
575
  }
576
577
578
  /**
579
   * @return array
580
   */
581
  public function target_coordinates_without_type() {
582
    return array(
583
      'galaxy' => $this->_fleet_end_galaxy,
584
      'system' => $this->_fleet_end_system,
585
      'planet' => $this->_fleet_end_planet,
586
    );
587
  }
588
589
  /**
590
   * @return array
591
   */
592
  public function target_coordinates_typed() {
593
    return array(
594
      'galaxy' => $this->_fleet_end_galaxy,
595
      'system' => $this->_fleet_end_system,
596
      'planet' => $this->_fleet_end_planet,
597
      'type'   => $this->_fleet_end_type,
598
    );
599
  }
600
601
  /**
602
   * @return array
603
   */
604
  public function launch_coordinates_typed() {
605
    return array(
606
      'galaxy' => $this->_fleet_start_galaxy,
607
      'system' => $this->_fleet_start_system,
608
      'planet' => $this->_fleet_start_planet,
609
      'type'   => $this->_fleet_start_type,
610
    );
611
  }
612
613
614
  /**
615
   * Sets object fields for fleet return
616
   */
617
  public function markReturned() {
618
    // TODO - Проверка - а не возвращается ли уже флот?
619
    $this->is_returning = 1;
620
  }
621
622
  public function isReturning() {
623
    return 1 == $this->_is_returning;
624
  }
625
626
  public function markReturnedAndSave() {
627
    $this->markReturned();
628
    $this->dbSave();
629
  }
630
631
  /**
632
   * Parses extended unit_array which can include not only ships but resources, captains etc
633
   *
634
   * @param $unit_array
635
   *
636
   * @throws Exception
637
   */
638
  // TODO - separate shipList and unitList
639
  public function unitsSetFromArray($unit_array) {
640
    if (empty($unit_array) || !is_array($unit_array)) {
641
      return;
642
    }
643
    foreach ($unit_array as $unit_id => $unit_count) {
644
      $unit_count = floatval($unit_count);
645
      if (!$unit_count) {
646
        continue;
647
      }
648
649
      if ($this->isShip($unit_id)) {
650
        $this->unitList->unitSetCount($unit_id, $unit_count);
651
      } elseif ($this->isResource($unit_id)) {
652
        $this->resource_list[$unit_id] = $unit_count;
653
      } else {
654
        throw new Exception('Trying to pass to fleet non-resource and non-ship ' . var_export($unit_array, true), ERR_ERROR);
655
      }
656
    }
657
  }
658
659
660
  /**
661
   * Sets fleet timers based on flight duration, time on mission (HOLD/EXPLORE) and fleet departure time.
662
   *
663
   * @param int $time_to_travel - flight duration in seconds
664
   * @param int $time_on_mission - time on mission in seconds
665
   * @param int $group_sync_delta_time - delta time to adjust fleet arrival time if fleet is a part of group (i.e. ACS)
666
   * @param int $flight_departure - fleet departure from source planet timestamp. Allows to send fleet in future or in past
667
   */
668
  public function set_times($time_to_travel, $time_on_mission = 0, $group_sync_delta_time = 0, $flight_departure = SN_TIME_NOW) {
669
    $this->_time_launch = $flight_departure;
670
671
    $this->_time_arrive_to_target = $this->_time_launch + $time_to_travel + $group_sync_delta_time;
672
    $this->_time_mission_job_complete = $time_on_mission ? $this->_time_arrive_to_target + $time_on_mission : 0;
673
    $this->_time_return_to_source = ($this->_time_mission_job_complete ? $this->_time_mission_job_complete : $this->_time_arrive_to_target) + $time_to_travel;
674
  }
675
676
677
  public function parse_missile_db_row($missile_db_row) {
678
//    $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...
679
680
    if (empty($missile_db_row) || !is_array($missile_db_row)) {
681
      return;
682
    }
683
684
//      $planet_start = db_planet_by_vector($irak_original, 'fleet_start_', false, 'name');
0 ignored issues
show
Unused Code Comprehensibility introduced by
61% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
685
//      $irak_original['fleet_start_name'] = $planet_start['name'];
686
    $this->missile_target = $missile_db_row['primaer'];
687
688
    $this->_dbId = -$missile_db_row['id'];
689
    $this->_playerOwnerId = $missile_db_row['fleet_owner'];
690
    $this->_mission_type = MT_MISSILE;
691
692
    $this->_target_owner_id = $missile_db_row['fleet_target_owner'];
693
694
    $this->_group_id = 0;
695
    $this->_is_returning = 0;
696
697
    $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...
698
    $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...
699
    $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...
700
    $this->_time_return_to_source = $missile_db_row['fleet_end_time'];
701
702
    $this->_fleet_start_planet_id = !empty($missile_db_row['fleet_start_planet_id']) ? $missile_db_row['fleet_start_planet_id'] : null;
703
    $this->_fleet_start_galaxy = $missile_db_row['fleet_start_galaxy'];
704
    $this->_fleet_start_system = $missile_db_row['fleet_start_system'];
705
    $this->_fleet_start_planet = $missile_db_row['fleet_start_planet'];
706
    $this->_fleet_start_type = $missile_db_row['fleet_start_type'];
707
708
    $this->_fleet_end_planet_id = !empty($missile_db_row['fleet_end_planet_id']) ? $missile_db_row['fleet_end_planet_id'] : null;
709
    $this->_fleet_end_galaxy = $missile_db_row['fleet_end_galaxy'];
710
    $this->_fleet_end_system = $missile_db_row['fleet_end_system'];
711
    $this->_fleet_end_planet = $missile_db_row['fleet_end_planet'];
712
    $this->_fleet_end_type = $missile_db_row['fleet_end_type'];
713
714
    $this->unitList->unitSetCount(UNIT_DEF_MISSILE_INTERPLANET, $missile_db_row['fleet_amount']);
715
  }
716
717
718
  /**
719
   * @param $from
720
   */
721
  public function set_start_planet($from) {
722
    $this->fleet_start_planet_id = intval($from['id']) ? $from['id'] : null;
723
    $this->fleet_start_galaxy = $from['galaxy'];
724
    $this->fleet_start_system = $from['system'];
725
    $this->fleet_start_planet = $from['planet'];
726
    $this->fleet_start_type = $from['planet_type'];
727
  }
728
729
  /**
730
   * @param $to
731
   */
732
  public function set_end_planet($to) {
733
    $this->target_owner_id = intval($to['id_owner']) ? $to['id_owner'] : 0;
734
    $this->fleet_end_planet_id = intval($to['id']) ? $to['id'] : null;
735
    $this->fleet_end_galaxy = $to['galaxy'];
736
    $this->fleet_end_system = $to['system'];
737
    $this->fleet_end_planet = $to['planet'];
738
    $this->fleet_end_type = $to['planet_type'];
739
  }
740
741
  /**
742
   * @param Vector $to
743
   */
744
  public function setTargetFromVectorObject($to) {
745
    $this->_fleet_end_galaxy = $to->galaxy;
746
    $this->_fleet_end_system = $to->system;
747
    $this->_fleet_end_planet = $to->planet;
748
    $this->_fleet_end_type = $to->type;
749
  }
750
751
  /**
752
   * @param array $db_row
753
   */
754
  protected function ownerExtract(array &$db_row) {
755
    $player = new Player();
756
    $player->dbLoad($db_row['fleet_owner']);
757
    $this->setLocatedAt($player);
758
  }
759
760
  /**
761
   * @param array $db_row
762
   */
763
  protected function ownerInject(array &$db_row) {
764
    $db_row['fleet_owner'] = $this->getPlayerOwnerId();
765
  }
766
767
768
769
770
  // UnitList/Ships access ***************************************************************************************************
771
772
  // TODO - перекрывать пожже - для миссайл-флотов и дефенс-флотов
773
  protected function isShip($unit_id) {
774
    return UnitShip::is_in_group($unit_id);
775
  }
776
777
  /**
778
   * Set unit count of $unit_id to $unit_count
779
   * If there is no $unit_id - it will be created and saved to DB on dbSave
780
   *
781
   * @param int $unit_id
782
   * @param int $unit_count
783
   */
784
  public function shipSetCount($unit_id, $unit_count = 0) {
785
    $this->shipAdjustCount($unit_id, $unit_count, true);
786
  }
787
788
  /**
789
   * Adjust unit count of $unit_id by $unit_count - or just replace value
790
   * If there is no $unit_id - it will be created and saved to DB on dbSave
791
   *
792
   * @param int  $unit_id
793
   * @param int  $unit_count
794
   * @param bool $replace_value
795
   */
796
  public function shipAdjustCount($unit_id, $unit_count = 0, $replace_value = false) {
797
    $this->unitList->unitAdjustCount($unit_id, $unit_count, $replace_value);
798
  }
799
800
  public function shipGetCount($unit_id) {
801
    return $this->unitList->unitGetCount($unit_id);
802
  }
803
804
  public function shipsCountApplyLossMultiplier($ships_lost_multiplier) {
805
    $this->unitList->unitsCountApplyLossMultiplier($ships_lost_multiplier);
806
  }
807
808
  /**
809
   * Returns ship list in fleet
810
   */
811
  public function shipsGetArray() {
812
    return $this->unitList->unitsGetArray();
813
  }
814
815
  public function shipsGetTotal() {
816
    return $this->unitList->unitsCount();
817
  }
818
819
  public function shipsGetCapacity() {
820
    return $this->unitList->shipsCapacity();
821
  }
822
823
  public function shipsGetHoldFree() {
824
    return max(0, $this->shipsGetCapacity() - $this->resourcesGetTotal());
825
  }
826
827
  /**
828
   * Get count of ships with $ship_id
829
   *
830
   * @param int $ship_id
831
   *
832
   * @return int
833
   */
834
  public function shipsGetTotalById($ship_id) {
835
    return $this->unitList->unitsCountById($ship_id);
836
  }
837
838
  /**
839
   * Возвращает ёмкость переработчиков во флоте
840
   *
841
   * @param array $recycler_info
842
   *
843
   * @return int
844
   *
845
   * @version 41a6.86
846
   */
847
  public function shipsGetCapacityRecyclers(array $recycler_info) {
848
    $recyclers_incoming_capacity = 0;
849
    $fleet_data = $this->shipsGetArray();
850
    foreach ($recycler_info as $recycler_id => $recycler_data) {
851
      $recyclers_incoming_capacity += $fleet_data[$recycler_id] * $recycler_data['capacity'];
852
    }
853
854
    return $recyclers_incoming_capacity;
855
  }
856
857
  /**
858
   * Restores fleet or resources to planet
859
   *
860
   * @param bool $start
861
   * @param int  $result
862
   *
863
   * @return int
864
   */
865
  // TODO - split to functions
866
  public function shipsLand($start = true, &$result = CACHE_NOTHING) {
867
    sn_db_transaction_check(true);
868
869
    // Если флот уже обработан - не существует или возращается - тогда ничего не делаем
870
    if ($this->isEmpty()) {
871
      return $result;
872
    }
873
874
    $coordinates = $start ? $this->launch_coordinates_typed() : $this->target_coordinates_typed();
875
876
    // Поскольку эта функция может быть вызвана не из обработчика флотов - нам надо всё заблокировать вроде бы НЕ МОЖЕТ!!!
877
    // TODO Проверить от многократного срабатывания !!!
878
    // Тут не блокируем пока - сначала надо заблокировать пользователя, что бы не было дедлока
879
    // TODO поменять на владельца планеты - когда его будут возвращать всегда !!!
880
881
    // Узнаем ИД владельца планеты.
882
    // С блокировкой, поскольку эта функция может быть вызвана только из менеджера летящих флотов.
883
    // А там уже всё заблокировано как надо и повторная блокировка не вызовет дедлок.
884
    $planet_arrival = db_planet_by_vector($coordinates, '', true);
885
    // Блокируем пользователя
886
    // TODO - вообще-то нам уже известен пользователь в МЛФ - так что можно просто передать его сюда
887
    $user = db_user_by_id($planet_arrival['id_owner'], true);
888
889
    // TODO - Проверка, что планета всё еще существует на указанных координатах, а не телепортировалась, не удалена хозяином, не уничтожена врагом
890
    // Флот, который возвращается на захваченную планету, пропадает
891
    // Ship landing is possible only to fleet owner's planet
892
    if ($this->getPlayerOwnerId() == $planet_arrival['id_owner']) {
893
      $db_changeset = array();
894
895
      $fleet_array = $this->shipsGetArray();
896
      foreach ($fleet_array as $ship_id => $ship_count) {
897
        if ($ship_count) {
898
          $db_changeset['unit'][] = sn_db_unit_changeset_prepare($ship_id, $ship_count, $user, $planet_arrival['id']);
899
        }
900
      }
901
902
      // Adjusting ship amount on planet
903
      if (!empty($db_changeset)) {
904
        db_changeset_apply($db_changeset);
905
      }
906
907
      // Restoring resources to planet
908
      $this->resourcesUnload($start, $result);
909
    }
910
911
    $result = CACHE_FLEET | ($start ? CACHE_PLANET_SRC : CACHE_PLANET_DST);
912
913
    $result = RestoreFleetToPlanet($this, $start, $result);
914
915
    $this->dbDelete();
916
917
    return $result;
918
  }
919
920
921
  // Resources access ***************************************************************************************************
922
923
  /**
924
   * Extracts resources value from db_row
925
   *
926
   * @param array $db_row
927
   *
928
   * @internal param Fleet $that
929
   * @version 41a6.86
930
   */
931
  protected function resourcesExtract(array &$db_row) {
932
    $this->resource_list = array(
933
      RES_METAL     => !empty($db_row['fleet_resource_metal']) ? floor($db_row['fleet_resource_metal']) : 0,
934
      RES_CRYSTAL   => !empty($db_row['fleet_resource_crystal']) ? floor($db_row['fleet_resource_crystal']) : 0,
935
      RES_DEUTERIUM => !empty($db_row['fleet_resource_deuterium']) ? floor($db_row['fleet_resource_deuterium']) : 0,
936
    );
937
  }
938
939
  protected function resourcesInject(array &$db_row) {
940
    $db_row['fleet_resource_metal'] = $this->resource_list[RES_METAL];
941
    $db_row['fleet_resource_crystal'] = $this->resource_list[RES_CRYSTAL];
942
    $db_row['fleet_resource_deuterium'] = $this->resource_list[RES_DEUTERIUM];
943
  }
944
945
  /**
946
   * Set current resource list from array of units
947
   *
948
   * @param array $resource_list
949
   */
950
  public function resourcesSet($resource_list) {
951
    if (!empty($this->propertiesAdjusted['resource_list'])) {
952
      throw new PropertyAccessException('Property "resource_list" already was adjusted so no SET is possible until dbSave in ' . get_called_class() . '::unitSetResourceList', ERR_ERROR);
953
    }
954
    $this->resourcesAdjust($resource_list, true);
955
  }
956
957
  /**
958
   * Updates fleet resource list with deltas
959
   *
960
   * @param array $resource_delta_list
961
   * @param bool  $replace_value
962
   *
963
   * @throws Exception
964
   */
965
  public function resourcesAdjust($resource_delta_list, $replace_value = false) {
966
    !is_array($resource_delta_list) ? $resource_delta_list = array() : false;
967
968
    foreach ($resource_delta_list as $resource_id => $unit_delta) {
969
      if (!UnitResourceLoot::is_in_group($resource_id) || !($unit_delta = floor($unit_delta))) {
970
        // Not a resource or no resources - continuing
971
        continue;
972
      }
973
974
      if ($replace_value) {
975
        $this->resource_list[$resource_id] = $unit_delta;
976
      } else {
977
        $this->resource_list[$resource_id] += $unit_delta;
978
        // Preparing changes
979
        $this->resource_delta[$resource_id] += $unit_delta;
980
        $this->propertiesAdjusted['resource_list'] = 1;
981
      }
982
983
      // Check for negative unit value
984
      if ($this->resource_list[$resource_id] < 0) {
985
        // TODO
986
        throw new Exception('Resource ' . $resource_id . ' will become negative in ' . get_called_class() . '::unitAdjustResourceList', ERR_ERROR);
987
      }
988
    }
989
  }
990
991
  public function resourcesGetTotal() {
992
    return empty($this->resource_list) || !is_array($this->resource_list) ? 0 : array_sum($this->resource_list);
993
  }
994
995
  /**
996
   * @param array $rate
997
   *
998
   * @return float
999
   */
1000
  public function resourcesGetTotalInMetal(array $rate) {
1001
    return
1002
      $this->resource_list[RES_METAL] * $rate[RES_METAL]
1003
      + $this->resource_list[RES_CRYSTAL] * $rate[RES_CRYSTAL] / $rate[RES_METAL]
1004
      + $this->resource_list[RES_DEUTERIUM] * $rate[RES_DEUTERIUM] / $rate[RES_METAL];
1005
  }
1006
1007
  /**
1008
   * Returns resource list in fleet
1009
   */
1010
  // TODO
1011
  public function resourcesGetList() {
1012
    return $this->resource_list;
1013
  }
1014
1015
  public function resourcesReset() {
1016
    $this->resourcesSet(array(
1017
      RES_METAL     => 0,
1018
      RES_CRYSTAL   => 0,
1019
      RES_DEUTERIUM => 0,
1020
    ));
1021
  }
1022
1023
  /**
1024
   * Restores fleet or resources to planet
1025
   *
1026
   * @param bool $start
1027
   * @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...
1028
   * @param int  $result
1029
   *
1030
   * @return int
1031
   */
1032
  public function resourcesUnload($start = true, &$result = CACHE_NOTHING) {
1033
    sn_db_transaction_check(true);
1034
1035
    // Если флот уже обработан - не существует или возращается - тогда ничего не делаем
1036
    if (!$this->resourcesGetTotal()) {
1037
      return $result;
1038
    }
1039
1040
    $coordinates = $start ? $this->launch_coordinates_typed() : $this->target_coordinates_typed();
1041
1042
    // Поскольку эта функция может быть вызвана не из обработчика флотов - нам надо всё заблокировать вроде бы НЕ МОЖЕТ!!!
1043
    // TODO Проверить от многократного срабатывания !!!
1044
    // Тут не блокируем пока - сначала надо заблокировать пользователя, что бы не было дедлока
1045
    // TODO поменять на владельца планеты - когда его будут возвращать всегда !!!
1046
1047
1048
    // Узнаем ИД владельца планеты.
1049
    // С блокировкой, поскольку эта функция может быть вызвана только из менеджера летящих флотов.
1050
    // А там уже всё заблокировано как надо и повторная блокировка не вызовет дедлок.
1051
    $planet_arrival = db_planet_by_vector($coordinates, '', true);
1052
1053
    // TODO - Проверка, что планета всё еще существует на указанных координатах, а не телепортировалась, не удалена хозяином, не уничтожена врагом
1054
1055
    // Restoring resources to planet
1056
    if ($this->resourcesGetTotal()) {
1057
      $fleet_resources = $this->resourcesGetList();
1058
      db_planet_set_by_id($planet_arrival['id'],
1059
        "`metal` = `metal` + '{$fleet_resources[RES_METAL]}', `crystal` = `crystal` + '{$fleet_resources[RES_CRYSTAL]}', `deuterium` = `deuterium` + '{$fleet_resources[RES_DEUTERIUM]}'");
1060
    }
1061
1062
    $this->resourcesReset();
1063
    $this->markReturned();
1064
1065
    $result = CACHE_FLEET | ($start ? CACHE_PLANET_SRC : CACHE_PLANET_DST);
1066
1067
    return $result;
1068
  }
1069
1070
1071
  protected function isResource($unit_id) {
1072
    return UnitResourceLoot::is_in_group($unit_id);
1073
  }
1074
1075
  /**
1076
   * @param int $speed_percent
1077
   *
1078
   * @return array
1079
   */
1080
  protected function flt_travel_data($speed_percent = 10) {
1081
    $distance = $this->targetVector->distanceFromCoordinates($this->dbSourcePlanetRow);
1082
1083
    return $this->unitList->travelData($speed_percent, $distance, $this->dbOwnerRow);
1084
  }
1085
1086
1087
  /**
1088
   * @param array  $dbPlayerRow
1089
   * @param array  $dbPlanetRow
1090
   * @param Vector $targetVector
1091
   *
1092
   */
1093
  public function initDefaults($dbPlayerRow, $dbPlanetRow, $targetVector, $mission, $ships, $fleet_group_mr, $oldSpeedInTens = 10, $targetedUnitId = 0) {
1094
    $objFleet5Player = new Player();
1095
    $objFleet5Player->dbRowParse($dbPlayerRow);
1096
    $this->setLocatedAt($objFleet5Player);
1097
1098
    $this->mission_type = $mission;
1099
1100
    $this->dbOwnerRow = $dbPlayerRow;
1101
1102
    $this->set_start_planet($dbPlanetRow);
1103
    $this->dbSourcePlanetRow = $dbPlanetRow;
1104
1105
    $this->setTargetFromVectorObject($targetVector);
1106
    $this->targetVector = $targetVector;
1107
1108
    $this->populateTargetPlanet();
1109
1110
    $this->unitsSetFromArray($ships);
1111
1112
    $this->_group_id = $fleet_group_mr;
1113
1114
    $this->oldSpeedInTens = $oldSpeedInTens;
1115
1116
    $this->targetedUnitId = $targetedUnitId;
1117
1118
    $this->fleetPage0Prepare();
1119
1120
  }
1121
1122
  protected function populateTargetPlanet() {
1123
    $targetPlanetCoords = $this->targetVector;
1124
    if ($this->mission_type != MT_NONE) {
1125
      $this->restrictTargetTypeByMission();
1126
1127
      // TODO - Нельзя тут просто менять тип планеты или координат!
1128
      // If current planet type is not allowed on mission - switch planet type
1129
      if (empty($this->allowed_planet_types[$this->targetVector->type])) {
1130
        $targetPlanetCoords->type = reset($this->allowed_planet_types);
1131
      }
1132
    }
1133
1134
    $this->dbTargetRow = db_planet_by_vector_object($targetPlanetCoords);
1135
  }
1136
1137
  protected function restrictTargetTypeByMission() {
1138
    if ($this->_mission_type == MT_MISSILE) {
1139
      $this->allowed_planet_types = array(PT_PLANET => PT_PLANET);
1140
    } elseif ($this->_mission_type == MT_COLONIZE || $this->_mission_type == MT_EXPLORE) {
1141
      // TODO - PT_NONE
1142
      $this->allowed_planet_types = array(PT_PLANET => PT_PLANET);
1143
    } elseif ($this->_mission_type == MT_RECYCLE) {
1144
      $this->allowed_planet_types = array(PT_DEBRIS => PT_DEBRIS);
1145
    } elseif ($this->_mission_type == MT_DESTROY) {
1146
      $this->allowed_planet_types = array(PT_MOON => PT_MOON);
1147
    } else {
1148
      $this->allowed_planet_types = array(PT_PLANET => PT_PLANET, PT_MOON => PT_MOON);
1149
    }
1150
  }
1151
1152
  /**
1153
   */
1154
  public function fleetPage0Prepare() {
1155
    global $template_result;
1156
    $template_result += array(
1157
      'thisgalaxy'      => $this->dbSourcePlanetRow['galaxy'],
1158
      'thissystem'      => $this->dbSourcePlanetRow['system'],
1159
      'thisplanet'      => $this->dbSourcePlanetRow['planet'],
1160
      'thisplanet_type' => $this->dbSourcePlanetRow['planet_type'],
1161
1162
      'galaxy'         => $this->targetVector->galaxy,
1163
      'system'         => $this->targetVector->system,
1164
      'planet'         => $this->targetVector->planet,
1165
      'planet_type'    => $this->targetVector->type,
1166
      'target_mission' => $this->_mission_type,
1167
      'MISSION_NAME'   => $this->_mission_type ? classLocale::$lang['type_mission'][$this->_mission_type] : '',
1168
1169
      'MT_COLONIZE' => MT_COLONIZE,
1170
    );
1171
1172
//    pdump($this->targetVector->type);pdie();
0 ignored issues
show
Unused Code Comprehensibility introduced by
65% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
1173
  }
1174
1175
1176
  public function restrictToKnownSpace() {
1177
    if (!$this->targetVector->isInKnownSpace()) {
1178
      throw new Exception('FLIGHT_VECTOR_BEYOND_SYSTEM', FLIGHT_VECTOR_BEYOND_SYSTEM);
1179
    }
1180
  }
1181
1182
  public function restrictToTypePlanet($errorCode) {
1183
    if ($this->targetVector->type != PT_PLANET) {
1184
      throw new Exception($errorCode, $errorCode);
1185
    }
1186
  }
1187
1188
  public function restrictToNoMissiles() {
1189
    $missilesAttack = $this->unitList->unitsCountById(UNIT_DEF_MISSILE_INTERPLANET);
1190
    $missilesDefense = $this->unitList->unitsCountById(UNIT_DEF_MISSILE_INTERCEPTOR);
1191
    if ($missilesAttack > 0 || $missilesDefense > 0) {
1192
      throw new Exception('FLIGHT_SHIPS_NO_MISSILES', FLIGHT_SHIPS_NO_MISSILES);
1193
    }
1194
  }
1195
1196
  public function restrictToTargetOwn() {
1197
    if ($this->dbTargetRow['id'] != $this->getPlayerOwnerId()) {
1198
      throw new Exception('FLIGHT_VECTOR_ONLY_OWN', FLIGHT_VECTOR_ONLY_OWN);
1199
    }
1200
  }
1201
1202
  public function restrictToTargetOther() {
1203
    if ($this->dbTargetRow['id'] == $this->getPlayerOwnerId()) {
1204
      throw new Exception('FLIGHT_VECTOR_ONLY_OTHER', FLIGHT_VECTOR_ONLY_OTHER);
1205
    }
1206
  }
1207
1208
  public function restrictToNotOnlySpies() {
1209
    if ($this->unitList->unitsCountById(SHIP_SPY) == $this->shipsGetTotal()) {
1210
      throw new Exception('FLIGHT_SHIPS_NOT_ONLY_SPIES', FLIGHT_SHIPS_NOT_ONLY_SPIES);
1211
    }
1212
  }
1213
1214
  protected function restrictToUniverse() {
1215
    if (!$this->targetVector->isInUniverse()) {
1216
      throw new Exception('FLIGHT_VECTOR_BEYOND_UNIVERSE', FLIGHT_VECTOR_BEYOND_UNIVERSE);
1217
    }
1218
  }
1219
1220
  protected function restrictToMovable() {
1221
    if (!$this->unitList->unitsIsAllMovable($this->dbOwnerRow)) {
1222
      throw new Exception('FLIGHT_SHIPS_UNMOVABLE', FLIGHT_SHIPS_UNMOVABLE);
1223
    }
1224
  }
1225
1226
  protected function restrictToFleetUnits() {
1227
    if (!$this->unitList->unitsInGroup(sn_get_groups(array('fleet', 'missile')))) {
1228
      throw new Exception('FLIGHT_SHIPS_UNIT_WRONG', FLIGHT_SHIPS_UNIT_WRONG);
1229
    }
1230
  }
1231
1232
  protected function restrictToColonizer() {
1233
    // Colonization fleet should have at least one colonizer
1234
    if (!$this->unitList->unitsCountById(SHIP_COLONIZER) <= 0) {
1235
      throw new Exception('FLIGHT_SHIPS_NO_COLONIZER', FLIGHT_SHIPS_NO_COLONIZER);
1236
    }
1237
  }
1238
1239
  protected function restrictToTargetExists() {
1240
    if (empty($this->dbTargetRow) || empty($this->dbTargetRow['id'])) {
1241
      throw new Exception('FLIGHT_VECTOR_NO_TARGET', FLIGHT_VECTOR_NO_TARGET);
1242
    }
1243
  }
1244
1245
1246 View Code Duplication
  protected function restrictKnownSpaceOrMissionExplore() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
1247
    // Is it exploration - fleet sent beyond of system?
1248
    if ($this->targetVector->isInKnownSpace()) {
1249
      // No exploration beyond this point
1250
      unset($this->allowed_missions[MT_EXPLORE]);
1251
1252
      $this->restrictToKnownSpace();
1253
1254
      return;
1255
    }
1256
    $this->restrictToNotOnlySpies();
1257
    $this->restrictToNoMissiles();
1258
1259
    $this->allowed_missions = array(MT_EXPLORE => MT_EXPLORE,);
1260
1261
    throw new Exception('FLIGHT_ALLOWED', FLIGHT_ALLOWED);
1262
  }
1263
1264 View Code Duplication
  protected function restrictTargetExistsOrMissionColonize() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
1265
    // Is it colonization - fleet sent to empty place?
1266
    if (!empty($this->dbTargetRow)) {
1267
      // No colonization beyond this point
1268
      unset($this->allowed_missions[MT_COLONIZE]);
1269
1270
      $this->restrictToTargetExists();
1271
1272
      return;
1273
    }
1274
    // Only planet can be destination for colonization
1275
    $this->restrictToTypePlanet(FLIGHT_MISSION_COLONIZE_NOT_PLANET);
1276
    $this->restrictToColonizer();
1277
    $this->restrictToNoMissiles();
1278
1279
    $this->allowed_missions = array(MT_COLONIZE => MT_COLONIZE,);
1280
1281
    throw new Exception('FLIGHT_ALLOWED', FLIGHT_ALLOWED);
1282
  }
1283
1284
  protected function restrictNotDebrisOrMissionRecycle() {
1285
    if ($this->targetVector->type != PT_DEBRIS) {
1286
      // No recycling beyond this point
1287
      unset($this->allowed_missions[MT_RECYCLE]);
1288
1289
      return;
1290
    }
1291
1292
    $this->restrictToNoMissiles();
1293
1294
    // restrict to recyclers
1295
    $recyclers = 0;
1296
    foreach (sn_get_groups('flt_recyclers') as $recycler_id) {
1297
      $recyclers += $this->unitList->unitsCountById($recycler_id);
1298
    }
1299
1300
    if ($recyclers <= 0) {
1301
      throw new Exception('FLIGHT_SHIPS_NO_RECYCLERS', FLIGHT_SHIPS_NO_RECYCLERS);
1302
    }
1303
1304
    $this->allowed_missions = array(MT_RECYCLE => MT_RECYCLE,);
1305
1306
    throw new Exception('FLIGHT_ALLOWED', FLIGHT_ALLOWED);
1307
  }
1308
1309
  protected function restrictMissionMissile() {
1310
    $missilesAttack = $this->unitList->unitsCountById(UNIT_DEF_MISSILE_INTERPLANET);
1311
    if ($missilesAttack <= 0) {
1312
      // No missile attack beyond this point
1313
      unset($this->allowed_missions[MT_MISSILE]);
1314
1315
      return;
1316
    }
1317
1318
    if ($missilesAttack != $this->shipsGetTotal()) {
1319
      throw new Exception('FLIGHT_SHIPS_ONLY_MISSILES', FLIGHT_SHIPS_ONLY_MISSILES);
1320
    }
1321
1322
    $this->restrictToTypePlanet(FLIGHT_MISSION_MISSILE_ONLY_PLANET);
1323
    $this->restrictToTargetOther();
1324
1325
    $this->allowed_missions = array(MT_MISSILE => MT_MISSILE,);
1326
    throw new Exception('FLIGHT_ALLOWED', FLIGHT_ALLOWED);
1327
  }
1328
1329 View Code Duplication
  protected function restrictToNotOnlySpiesOrMissionSpy() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
1330
    if ($this->unitList->unitsCountById(SHIP_SPY) != $this->shipsGetTotal()) {
1331
//      throw new Exception('FLIGHT_SHIPS_ONLY_SPIES', FLIGHT_SHIPS_ONLY_SPIES);
0 ignored issues
show
Unused Code Comprehensibility introduced by
54% 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...
1332
      unset($this->allowed_missions[MT_SPY]);
1333
1334
      $this->restrictToNotOnlySpies();
1335
1336
      return;
1337
    }
1338
1339
    $this->allowed_missions = array(MT_SPY => MT_SPY,);
1340
    throw new Exception('FLIGHT_ALLOWED', FLIGHT_ALLOWED);
1341
  }
1342
1343
  protected function restrictMissionDestroy() {
1344
    // If target vector is not Moon - then it can't be Destroy mission
1345
    // If no Reapers (i.e. Death Star) in fleet - then mission Moon Destroy is unaccessible
1346
    if ($this->targetVector->type != PT_MOON || $this->unitList->unitsCountById(SHIP_HUGE_DEATH_STAR) <= 0) {
1347
      unset($this->allowed_missions[MT_DESTROY]);
1348
    }
1349
  }
1350
1351
  protected function restrictMissionACS() {
1352
    // If no ACS group is shown - then it can't be an ACS attack
1353
    if (empty($this->_group_id)) {
1354
      unset($this->allowed_missions[MT_ACS]);
1355
    }
1356
  }
1357
1358
  /** @throws Exception */
1359
  protected function restrictFriendOrFoe() {
1360
    // Checking target owner
1361
    if ($this->dbTargetRow['id'] == $this->getPlayerOwnerId()) {
1362
      // Spying can't be done on owner's planet/moon
1363
      unset($this->allowed_missions[MT_SPY]);
1364
      // Attack can't be done on owner's planet/moon
1365
      unset($this->allowed_missions[MT_ATTACK]);
1366
      // ACS can't be done on owner's planet/moon
1367
      unset($this->allowed_missions[MT_ACS]);
1368
      // Destroy can't be done on owner's moon
1369
      unset($this->allowed_missions[MT_DESTROY]);
1370
1371
      $this->restrictToNoMissiles();
1372
1373
      // MT_RELOCATE
1374
      // No checks
1375
      // TODO - check captain
1376
1377
      // MT_HOLD
1378
      // TODO - Check for Allies Deposit for HOLD
1379
1380
      // MT_TRANSPORT
1381
1382
    } else {
1383
      // Relocate can be done only on owner's planet/moon
1384
      unset($this->allowed_missions[MT_RELOCATE]);
1385
1386
      // TODO - check for moratorium
1387
1388
      // MT_HOLD
1389
      // TODO - Check for Allies Deposit for HOLD
1390
      // TODO - Noob protection for HOLD depends on server settings
1391
1392
      // MT_SPY
1393
      $this->restrictToNotOnlySpiesOrMissionSpy();
1394
1395
      // TODO - check noob protection
1396
1397
      // TODO - check bashing
1398
1399
      // No missions except MT_MISSILE should have any missiles in fleet
1400
      $this->restrictMissionMissile();
1401
      $this->restrictToNoMissiles();
1402
      // Beyond this point no mission can have a missile in fleet
1403
1404
      // MT_DESTROY
1405
      $this->restrictMissionDestroy();
1406
1407
      // MT_ACS
1408
      $this->restrictMissionACS();
1409
1410
      // MT_ATTACK - no checks
1411
1412
      // MT_TRANSPORT - no checks
1413
    }
1414
  }
1415
1416
  protected function restrictToNotSource() {
1417
    if ($this->targetVector->isEqualToPlanet($this->dbSourcePlanetRow)) {
1418
      throw new Exception('FLIGHT_VECTOR_SAME_SOURCE', FLIGHT_VECTOR_SAME_SOURCE);
1419
    }
1420
  }
1421
1422
  protected function restrictToNonVacationSender() {
1423
    if (!empty($this->dbOwnerRow['vacation']) && $this->dbOwnerRow['vacation'] >= SN_TIME_NOW) {
1424
      throw new Exception('FLIGHT_PLAYER_VACATION_OWN', FLIGHT_PLAYER_VACATION_OWN);
1425
    }
1426
  }
1427
1428
  protected function restrictToValidSpeedPercentOld() {
1429
    $speed_possible = array(10, 9, 8, 7, 6, 5, 4, 3, 2, 1);
1430
    if (!in_array($this->oldSpeedInTens, $speed_possible)) {
1431
      throw new Exception('FLIGHT_FLEET_SPEED_WRONG', FLIGHT_FLEET_SPEED_WRONG);
1432
    }
1433
1434
  }
1435
1436
  protected function restrict2ToAllowedMissions() {
1437
    if (empty($this->allowed_missions[$this->_mission_type])) {
1438
      throw new Exception('FLIGHT_MISSION_IMPOSSIBLE', FLIGHT_MISSION_IMPOSSIBLE);
1439
    }
1440
  }
1441
1442
  protected function restrict2ToAllowedPlanetTypes() {
1443
    if (empty($this->allowed_planet_types[$this->targetVector->type])) {
1444
      throw new Exception('FLIGHT_MISSION_IMPOSSIBLE', FLIGHT_MISSION_IMPOSSIBLE);
1445
    }
1446
  }
1447
1448
  protected function restrict2ToMaxFleets() {
1449
    if (FleetList::fleet_count_flying($this->getPlayerOwnerId()) >= GetMaxFleets($this->dbOwnerRow)) {
1450
      throw new Exception('FLIGHT_FLEET_NO_SLOTS', FLIGHT_FLEET_NO_SLOTS);
1451
    }
1452
  }
1453
1454
  protected function restrict2ToEnoughShips() {
1455
    if (!$this->unitList->shipsIsEnoughOnPlanet($this->dbSourcePlanetRow)) {
1456
      throw new Exception('FLIGHT_SHIPS_NOT_ENOUGH', FLIGHT_SHIPS_NOT_ENOUGH);
1457
    }
1458
  }
1459
1460
  protected function restrict2ToEnoughCapacity($fleetCapacity, $fleetConsumption) {
1461
    if (floor($fleetCapacity) < ceil(array_sum($this->resource_list) + $fleetConsumption)) {
1462
      throw new Exception('FLIGHT_FLEET_OVERLOAD', FLIGHT_FLEET_OVERLOAD);
1463
    }
1464
  }
1465
1466
  protected function restrict2ByResources($fleetConsumption) {
1467
    $fleetResources = $this->resource_list;
1468
    $fleetResources[RES_DEUTERIUM] = ceil($fleetResources[RES_DEUTERIUM] + $fleetConsumption);
1469
    foreach ($fleetResources as $resourceId => $resourceAmount) {
1470
      if ($fleetResources[$resourceId] < 0) {
1471
        throw new Exception('FLIGHT_RESOURCES_NEGATIVE', FLIGHT_RESOURCES_NEGATIVE);
1472
      }
1473
1474
      if (mrc_get_level($this->dbOwnerRow, $this->dbSourcePlanetRow, $resourceId) < ceil($fleetResources[$resourceId])) {
1475
        if ($resourceId == RES_DEUTERIUM) {
1476
          throw new Exception('FLIGHT_RESOURCES_FUEL_NOT_ENOUGH', FLIGHT_RESOURCES_FUEL_NOT_ENOUGH);
1477
        } else {
1478
          throw new Exception('FLIGHT_RESOURCES_NOT_ENOUGH', FLIGHT_RESOURCES_NOT_ENOUGH);
1479
        }
1480
      }
1481
    }
1482
  }
1483
1484
  /**
1485
   * Restricts mission availability internally w/o DB access
1486
   *
1487
   * @throws Exception
1488
   */
1489
  public function restrictMission() {
1490
    // Only "cheap" checks that didn't require to query DB
1491
1492
1493
    // Check for valid percent speed value
1494
    $this->restrictToValidSpeedPercentOld();
1495
1496
    // Player in Vacation can't send fleets
1497
    $this->restrictToNonVacationSender();
1498
1499
    // Fleet source and destination can't be the same
1500
    $this->restrictToNotSource();
1501
1502
    // No mission could fly beyond Universe - i.e. with wrong Galaxy and/or System coordinates
1503
    $this->restrictToUniverse();
1504
1505
    // Only ships and missiles can be sent to mission
1506
    $this->restrictToFleetUnits();
1507
    // Only units with main engines (speed >=0) can fly - no other units like satellites
1508
    $this->restrictToMovable();
1509
1510
    // No missions except MT_EXPLORE could target coordinates beyond known system
1511
    $this->restrictKnownSpaceOrMissionExplore();
1512
    // Beyond this point all mission address only known space
1513
1514
    // No missions except MT_COLONIZE could target empty coordinates
1515
    $this->restrictTargetExistsOrMissionColonize();
1516
    // Beyond this point all mission address only existing planets/moons
1517
1518
    // No missions except MT_RECYCLE could target debris
1519
    $this->restrictNotDebrisOrMissionRecycle();
1520
    // Beyond this point targets can be only PT_PLANET or PT_MOON
1521
1522
    // TODO - later then
1523
    $this->restrictFriendOrFoe();
1524
  }
1525
1526
1527
  protected function printErrorIfNoShips() {
1528
    if ($this->unitList->unitsCount() <= 0) {
1529
      message(classLocale::$lang['fl_err_no_ships'], classLocale::$lang['fl_error'], 'fleet' . DOT_PHP_EX, 5);
1530
    }
1531
  }
1532
1533
  /**
1534
   * @param array $template_result
1535
   *
1536
   * @throws Exception
1537
   */
1538
  protected function renderFleet(&$template_result) {
1539
    $this->printErrorIfNoShips();
1540
1541
    $tplShips = $this->unitList->unitsRender();
1542
    $template_result['.']['fleets'][] = array(
1543
      'START_TYPE_TEXT_SH' => classLocale::$lang['sys_planet_type_sh'][$this->dbSourcePlanetRow['planet_type']],
1544
      'START_COORDS'       => uni_render_coordinates($this->dbSourcePlanetRow),
1545
      'START_NAME'         => $this->dbSourcePlanetRow['name'],
1546
      'END_TYPE_TEXT_SH'   =>
1547
        !empty($this->targetVector->type)
1548
          ? classLocale::$lang['sys_planet_type_sh'][$this->targetVector->type]
1549
          : '',
1550
      'END_COORDS'         => uniRenderVector($this->targetVector),
1551
      'END_NAME'           => !empty($this->dbTargetRow['name']) ? $this->dbTargetRow['name'] : '',
1552
      '.'                  => array(
1553
        'ships' => $tplShips,
1554
      ),
1555
    );
1556
  }
1557
1558
  /**
1559
   * @param array $template_result
1560
   *
1561
   * @return array
1562
   */
1563
  protected function renderAllowedMissions(&$template_result) {
1564
    ksort($this->allowed_missions);
1565
    // If mission is not set - setting first mission from allowed
1566
    if (empty($this->_mission_type) && is_array($this->allowed_missions)) {
1567
      reset($this->allowed_missions);
1568
      $this->_mission_type = key($this->allowed_missions);
1569
    }
1570
    foreach ($this->allowed_missions as $key => $value) {
1571
      $template_result['.']['missions'][] = array(
1572
        'ID'   => $key,
1573
        'NAME' => classLocale::$lang['type_mission'][$key],
1574
      );
1575
    };
1576
  }
1577
1578
  /**
1579
   * @param $template_result
1580
   */
1581
  protected function renderDuration(&$template_result, $max_duration) {
1582
    if ($max_duration) {
1583
      $config_game_speed_expedition = ($this->_mission_type == MT_EXPLORE && classSupernova::$config->game_speed_expedition ? classSupernova::$config->game_speed_expedition : 1);
1584
      for ($i = 1; $i <= $max_duration; $i++) {
1585
        $template_result['.']['duration'][] = array(
1586
          'ID'   => $i,
1587
          'TIME' => pretty_time(ceil($i * 3600 / $config_game_speed_expedition)),
1588
        );
1589
      }
1590
    }
1591
  }
1592
1593
  /**
1594
   * @param array $planetResources
1595
   * @param array &$template_result
1596
   */
1597
  protected function renderPlanetResources(&$planetResources, &$template_result) {
1598
    // TODO - REDO to resource_id
1599
    $i = 0;
1600
    foreach ($planetResources as $resource_id => $resource_amount) {
1601
      $template_result['.']['resources'][] = array(
1602
        'ID'        => $i++, // $resource_id,
1603
        'ON_PLANET' => $resource_amount,
1604
        'TEXT'      => pretty_number($resource_amount),
1605
        'NAME'      => classLocale::$lang['tech'][$resource_id],
1606
      );
1607
    }
1608
  }
1609
1610
  /**
1611
   * @param $template_result
1612
   */
1613
  protected function renderAllowedPlanetTypes(&$template_result) {
1614
    foreach ($this->allowed_planet_types as $possible_planet_type_id) {
1615
      $template_result['.']['possible_planet_type_id'][] = array(
1616
        'ID'         => $possible_planet_type_id,
1617
        'NAME'       => classLocale::$lang['sys_planet_type'][$possible_planet_type_id],
1618
        'NAME_SHORT' => classLocale::$lang['sys_planet_type_sh'][$possible_planet_type_id],
1619
      );
1620
    }
1621
  }
1622
1623
  protected function renderFleet1TargetSelect(&$shortcut) {
1624
    global $note_priority_classes;
1625
1626
    $name = !empty($shortcut['title']) ? $shortcut['title'] : $shortcut['name'];
1627
1628
    $result = array(
1629
      'NAME'       => $name,
1630
      'GALAXY'     => $shortcut['galaxy'],
1631
      'SYSTEM'     => $shortcut['system'],
1632
      'PLANET'     => $shortcut['planet'],
1633
      'TYPE'       => $shortcut['planet_type'],
1634
      'TYPE_PRINT' => classLocale::$lang['fl_shrtcup'][$shortcut['planet_type']],
1635
    );
1636
1637
    if (isset($shortcut['priority'])) {
1638
      $result += array(
1639
        'PRIORITY'       => $shortcut['priority'],
1640
        'PRIORITY_CLASS' => $note_priority_classes[$shortcut['priority']],
1641
      );
1642
    }
1643
1644
    if (isset($shortcut['id'])) {
1645
      $result += array(
1646
        'ID' => $shortcut['id'],
1647
      );
1648
    }
1649
1650
    return $result;
1651
  }
1652
1653
  /**
1654
   * @param $template_result
1655
   */
1656
  protected function renderFleetShortcuts(&$template_result) {
1657
    // Building list of shortcuts
1658
    $query = db_note_list_select_by_owner_and_planet($this->dbOwnerRow);
1659
    while($row = db_fetch($query)) {
1660
      $template_result['.']['shortcut'][] = $this->renderFleet1TargetSelect($row);
1661
    }
1662
  }
1663
1664
  /**
1665
   * Building list of own planets & moons
1666
   *
1667
   * @param $template_result
1668
   */
1669
  protected function renderOwnPlanets(&$template_result) {
1670
    $colonies = db_planet_list_sorted($this->dbOwnerRow);
1671
    if (count($colonies) <= 1) {
1672
      return;
1673
    }
1674
1675
    foreach ($colonies as $row) {
1676
      if ($row['id'] == $this->dbSourcePlanetRow['id']) {
1677
        continue;
1678
      }
1679
1680
      $template_result['.']['colonies'][] = $this->renderFleet1TargetSelect($row);
1681
    }
1682
  }
1683
1684
  /**
1685
   * @param $template_result
1686
   */
1687
  protected function renderACSList(&$template_result) {
1688
    $query = db_acs_get_list();
1689
    while($row = db_fetch($query)) {
1690
      $members = explode(',', $row['eingeladen']);
1691
      foreach ($members as $a => $b) {
1692
        if ($b == $this->dbOwnerRow['id']) {
1693
          $template_result['.']['acss'][] = $this->renderFleet1TargetSelect($row);
1694
        }
1695
      }
1696
    }
1697
  }
1698
1699
  /**
1700
   * @param $template_result
1701
   */
1702
  protected function renderShipSortOptions(&$template_result) {
1703
    foreach (classLocale::$lang['player_option_fleet_ship_sort'] as $sort_id => $sort_text) {
1704
      $template_result['.']['ship_sort_list'][] = array(
1705
        'VALUE' => $sort_id,
1706
        'TEXT'  => $sort_text,
1707
      );
1708
    }
1709
    $template_result += array(
1710
      'FLEET_SHIP_SORT'         => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_SORT],
1711
      'FLEET_SHIP_SORT_INVERSE' => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_SORT_INVERSE],
1712
    );
1713
  }
1714
1715
  /**
1716
   */
1717
  public function fleetPage0() {
1718
    global $template_result;
1719
1720
    lng_include('overview');
1721
1722
    if (empty($this->dbSourcePlanetRow)) {
1723
      message(classLocale::$lang['fl_noplanetrow'], classLocale::$lang['fl_error']);
1724
    }
1725
1726
    // TODO - redo to unitlist render/unit render
1727
    $this->renderAvailableShips($template_result, $this->dbOwnerRow, $this->dbSourcePlanetRow);
1728
1729
    $this->renderShipSortOptions($template_result);
1730
1731
    /**
1732
     * @var Player $playerOwner
1733
     */
1734
    $playerOwner = $this->getLocatedAt();
1735
1736
    $template_result += array(
1737
      'FLYING_FLEETS'      => $playerOwner->fleetsFlying(),
1738
      'MAX_FLEETS'         => $playerOwner->fleetsMax(),
1739
      'FREE_FLEETS'        => $playerOwner->fleetsMax() - $playerOwner->fleetsFlying(),
1740
      'FLYING_EXPEDITIONS' => $playerOwner->expeditionsFlying(),
1741
      'MAX_EXPEDITIONS'    => $playerOwner->expeditionsMax(),
1742
      'FREE_EXPEDITIONS'   => $playerOwner->expeditionsMax() - $playerOwner->expeditionsFlying(),
1743
      'COLONIES_CURRENT'   => $playerOwner->coloniesCurrent(),
1744
      'COLONIES_MAX'       => $playerOwner->coloniesMax(),
1745
1746
      'TYPE_NAME' => classLocale::$lang['fl_planettype'][$this->targetVector->type],
1747
1748
      'speed_factor' => flt_server_flight_speed_multiplier(),
1749
1750
      'PLANET_RESOURCES' => pretty_number($this->dbSourcePlanetRow['metal'] + $this->dbSourcePlanetRow['crystal'] + $this->dbSourcePlanetRow['deuterium']),
1751
      'PLANET_DEUTERIUM' => pretty_number($this->dbSourcePlanetRow['deuterium']),
1752
1753
      'PLAYER_OPTION_FLEET_SHIP_SELECT_OLD'       => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_SELECT_OLD],
1754
      'PLAYER_OPTION_FLEET_SHIP_HIDE_SPEED'       => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_HIDE_SPEED],
1755
      'PLAYER_OPTION_FLEET_SHIP_HIDE_CAPACITY'    => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_HIDE_CAPACITY],
1756
      'PLAYER_OPTION_FLEET_SHIP_HIDE_CONSUMPTION' => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_HIDE_CONSUMPTION],
1757
    );
1758
1759
    $template = gettemplate('fleet0', true);
1760
    $template->assign_recursive($template_result);
1761
    display($template, classLocale::$lang['fl_title']);
1762
  }
1763
1764
  public function fleetPage1() {
1765
    global $template_result;
1766
1767
    $this->renderFleet($template_result);
1768
1769
    $this->renderAllowedPlanetTypes($template_result);
1770
1771
    $this->renderOwnPlanets($template_result);
1772
1773
    $this->renderFleetShortcuts($template_result);
1774
1775
    $this->renderACSList($template_result);
1776
1777
    $template_result += array(
1778
      'speed_factor' => flt_server_flight_speed_multiplier(),
1779
1780
      'fleet_speed'    => flt_fleet_speed($this->dbOwnerRow, $this->shipsGetArray()),
1781
      'fleet_capacity' => $this->shipsGetCapacity(),
1782
1783
      'PLANET_DEUTERIUM' => pretty_number($this->dbSourcePlanetRow['deuterium']),
1784
1785
      'PAGE_HINT' => classLocale::$lang['fl_page1_hint'],
1786
    );
1787
1788
    $template = gettemplate('fleet1', true);
1789
    $template->assign_recursive($template_result);
1790
    display($template, classLocale::$lang['fl_title']);
1791
  }
1792
1793
  public function fleetPage2() {
1794
    global $template_result;
1795
1796
    try {
1797
      $this->restrictMission();
1798
    } catch (Exception $e) {
1799
      // TODO - MESSAGE BOX
1800 View Code Duplication
      if ($e->getCode() != FLIGHT_ALLOWED) {
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...
1801
        pdie(classLocale::$lang['fl_attack_error'][$e->getCode()]);
1802
      } else {
1803
        pdump('FLIGHT_ALLOWED', FLIGHT_ALLOWED);
1804
      }
1805
    }
1806
1807
    $this->renderAllowedMissions($template_result);
1808
    $this->renderFleet($template_result);
1809
1810
    $max_duration = $this->_mission_type == MT_EXPLORE ? get_player_max_expedition_duration($this->dbOwnerRow) :
1811
      (isset($this->allowed_missions[MT_HOLD]) ? 12 : 0);
1812
    $this->renderDuration($template_result, $max_duration);
1813
1814
    $travel_data = $this->flt_travel_data($this->oldSpeedInTens);
1815
1816
    $sn_group_resources = sn_get_groups('resources_loot');
1817
    $planetResources = array();
1818
    foreach ($sn_group_resources as $resource_id) {
1819
      $planetResources[$resource_id] = floor(mrc_get_level($this->dbOwnerRow, $this->dbSourcePlanetRow, $resource_id) - ($resource_id == RES_DEUTERIUM ? $travel_data['consumption'] : 0));
1820
    }
1821
    $this->renderPlanetResources($planetResources, $template_result);
1822
1823
    if (sn_module::$sn_module['unit_captain']->manifest['active'] && ($captain = sn_module::$sn_module['unit_captain']->unit_captain_get($this->dbSourcePlanetRow['id'])) && $captain['unit_location_type'] == LOC_PLANET) {
1824
      $template_result += array(
1825
        'CAPTAIN_ID'     => $captain['unit_id'],
1826
        'CAPTAIN_LEVEL'  => $captain['captain_level'],
1827
        'CAPTAIN_SHIELD' => $captain['captain_shield'],
1828
        'CAPTAIN_ARMOR'  => $captain['captain_armor'],
1829
        'CAPTAIN_ATTACK' => $captain['captain_attack'],
1830
      );
1831
    }
1832
1833
    $template_result += array(
1834
      'planet_metal'     => $planetResources[RES_METAL],
1835
      'planet_crystal'   => $planetResources[RES_CRYSTAL],
1836
      'planet_deuterium' => $planetResources[RES_DEUTERIUM],
1837
1838
      'fleet_capacity' => $this->shipsGetCapacity() - $travel_data['consumption'],
1839
      'speed'          => $this->oldSpeedInTens,
1840
      'fleet_group'    => $this->_group_id,
1841
1842
      'MAX_DURATION'          => $max_duration,
1843
1844
      // 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...
1845
//      'IS_TRANSPORT_MISSIONS' => !empty($this->allowed_missions[$this->_mission_type]['transport']),
1846
      'IS_TRANSPORT_MISSIONS' => true,
1847
1848
      'PLAYER_COLONIES_CURRENT' => get_player_current_colonies($this->dbOwnerRow),
1849
      'PLAYER_COLONIES_MAX'     => get_player_max_colonies($this->dbOwnerRow),
1850
    );
1851
1852
    $template = gettemplate('fleet2', true);
1853
    $template->assign_recursive($template_result);
1854
    display($template, classLocale::$lang['fl_title']);
1855
  }
1856
1857
1858
  public function restrict2MissionTransportWithResources($fleetResources) {
1859
    if ($this->_mission_type != MT_TRANSPORT) {
1860
      return;
1861
    }
1862
1863
    if (array_sum($fleetResources) <= 0) {
1864
      throw new Exception('FLIGHT_RESOURCES_EMPTY', FLIGHT_RESOURCES_EMPTY);
1865
    }
1866
  }
1867
1868
  protected function restrict2MissionExploreAvailable() {
1869
    if ($this->_mission_type != MT_EXPLORE) {
1870
      return;
1871
    }
1872
1873
    if (($expeditionsMax = get_player_max_expeditons($this->dbOwnerRow)) <= 0) {
1874
      throw new Exception('FLIGHT_MISSION_EXPLORE_NO_ASTROTECH', FLIGHT_MISSION_EXPLORE_NO_ASTROTECH);
1875
    }
1876
    if (FleetList::fleet_count_flying($this->getPlayerOwnerId(), MT_EXPLORE) >= $expeditionsMax) {
1877
      throw new Exception('FLIGHT_MISSION_EXPLORE_NO_SLOTS', FLIGHT_MISSION_EXPLORE_NO_SLOTS);
1878
    }
1879
1880
    $this->restrictToNotOnlySpies();
1881
    $this->restrictToNoMissiles();
1882
1883
    throw new Exception('FLIGHT_ALLOWED', FLIGHT_ALLOWED);
1884
  }
1885
1886
1887
  public function fleetPage3($time_to_travel) {
1888
    global $target_mission, $fleetarray, $planetrow;
1889
    global $galaxy, $system, $planet, $TargetPlanet, $consumption, $template_result;
1890
    global $errorlist, $planet_type, $MaxExpeditions, $FlyingExpeditions;
1891
    global $speed_percent, $distance, $fleet_speed, $user, $debug;
1892
1893
    $classLocale = classLocale::$lang;
1894
1895
    $this->isRealFlight = true;
1896
1897
    sn_db_transaction_start();
1898
1899
    db_user_lock_with_target_owner($this->dbOwnerRow, $this->dbTargetRow);
1900
1901
    $this->dbOwnerRow = db_user_by_id($this->dbOwnerRow['id'], true);
0 ignored issues
show
Documentation Bug introduced by
It seems like db_user_by_id($this->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...
1902
    $this->dbSourcePlanetRow = db_planet_by_id($this->dbSourcePlanetRow['id'], true);
1903
    if (!empty($this->dbTargetRow['id'])) {
1904
      $this->dbTargetRow = db_planet_by_id($this->dbTargetRow['id'], true);
1905
    }
1906
    if (!empty($this->dbTargetRow['id_owner'])) {
1907
      $this->dbTargetOwnerRow = db_planet_by_id($this->dbTargetRow['id_owner'], true);
1908
    }
1909
1910
    $this->resource_list = array(
1911
      RES_METAL     => max(0, floor(sys_get_param_float('resource0'))),
1912
      RES_CRYSTAL   => max(0, floor(sys_get_param_float('resource1'))),
1913
      RES_DEUTERIUM => max(0, floor(sys_get_param_float('resource2'))),
1914
    );
1915
1916
    $checklist = sn_get_groups('mission_checks');
1917
1918
    $this->travelData = $this->flt_travel_data($this->oldSpeedInTens);
1919
1920
    try {
1921
      $this->checkMissionRestrictions($checklist);
1922
1923
      // Do the restrictMission checks
1924
1925
      // TODO - Кое-какие проверки дают FLIGHT_ALLOWED - ЧТО НЕПРАВДА В ДАННОМ СЛУЧАЕ!!!
1926
      // На странице 1 некоторые проверки ДОЛЖНЫ БЫТЬ опущены - иначе будет некрасиво
1927
      // А вот здесь надо проверять много дополнительной хуйни
1928
      try {
1929
        // TODO  - ALL OF THE ABOVE!
1930
        $this->restrictMission();
1931
      } catch (Exception $e) {
1932
        // If mission is restricted - rethrow exception
1933
        if ($e->getCode() != FLIGHT_ALLOWED) {
1934
          throw new Exception($e->getMessage(), $e->getCode());
1935
        }
1936
      }
1937
1938
      // TODO - later then
1939
1940
      // 2nd level restrictions
1941
      // Still cheap
1942
      $this->restrict2ToAllowedMissions();
1943
      $this->restrict2ToAllowedPlanetTypes();
1944
1945
      // TODO - REWRITE TO LEVEL 2
1946
      $this->restrict2MissionExploreAvailable();
1947
      $this->restrictTargetExistsOrMissionColonize();
1948
      $this->restrictNotDebrisOrMissionRecycle();
1949
1950
1951
      //
1952
      //
1953
      //
1954
      //
1955
      //
1956
      //
1957
      //
1958
      //
1959
      //
1960
      //
1961
      //
1962
      //
1963
      //
1964
      //
1965
      //
1966
      //
1967
      //
1968
      //
1969
1970
1971
//      $this->restrict2MissionTransportWithResources($fleetResources);
0 ignored issues
show
Unused Code Comprehensibility introduced by
75% 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...
1972
    } catch (Exception $e) {
1973
      // TODO - MESSAGE BOX
1974 View Code Duplication
      if ($e->getCode() != FLIGHT_ALLOWED) {
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...
1975
        sn_db_transaction_rollback();
1976
        pdie(classLocale::$lang['fl_attack_error'][$e->getCode()]);
1977
      } else {
1978
        pdump('FLIGHT_ALLOWED', FLIGHT_ALLOWED);
1979
      }
1980
    }
1981
1982
1983
    // TODO check for empty mission AKA mission allowed
1984
1985
    $errorlist = '';
1986
1987
    $errorlist .= !is_array($fleetarray) ? classLocale::$lang['fl_no_fleetarray'] : '';
1988
1989
    $TransMetal = max(0, floor(sys_get_param_float('resource0')));
1990
    $TransCrystal = max(0, floor(sys_get_param_float('resource1')));
1991
    $TransDeuterium = max(0, floor(sys_get_param_float('resource2')));
1992
    $StorageNeeded = $TransMetal + $TransCrystal + $TransDeuterium;
1993
1994
    if (!$StorageNeeded && $target_mission == MT_TRANSPORT) {
1995
      $errorlist .= classLocale::$lang['fl_noenoughtgoods'];
1996
    }
1997
1998
1999
    if ($target_mission == MT_EXPLORE) {
2000
      if ($MaxExpeditions == 0) {
2001
        $errorlist .= classLocale::$lang['fl_expe_notech'];
2002
      } elseif ($FlyingExpeditions >= $MaxExpeditions) {
2003
        $errorlist .= classLocale::$lang['fl_expe_max'];
2004
      }
2005
    } else {
2006
      if ($TargetPlanet['id_owner']) {
2007
        if ($target_mission == MT_COLONIZE) {
2008
          $errorlist .= classLocale::$lang['fl_colonized'];
2009
        }
2010
2011
        if ($TargetPlanet['id_owner'] == $planetrow['id_owner']) {
2012
          if ($target_mission == MT_ATTACK) {
2013
            $errorlist .= classLocale::$lang['fl_no_self_attack'];
2014
          }
2015
2016
          if ($target_mission == MT_SPY) {
2017
            $errorlist .= classLocale::$lang['fl_no_self_spy'];
2018
          }
2019
        } else {
2020
          if ($target_mission == MT_RELOCATE) {
2021
            $errorlist .= classLocale::$lang['fl_only_stay_at_home'];
2022
          }
2023
        }
2024
      } else {
2025
        if ($target_mission < MT_COLONIZE) {
2026
          $errorlist .= classLocale::$lang['fl_unknow_target'];
2027
        } else {
2028
//          if($target_mission == MT_DESTROY) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
47% 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...
2029
//            $errorlist .= classLocale::$lang['fl_nomoon'];
2030
//          }
2031
2032
          if ($target_mission == MT_RECYCLE) {
2033
            if ($TargetPlanet['debris_metal'] + $TargetPlanet['debris_crystal'] == 0) {
2034
              $errorlist .= classLocale::$lang['fl_nodebris'];
2035
            }
2036
          }
2037
        }
2038
      }
2039
    }
2040
2041
2042
    if (sn_module::$sn_module['unit_captain']->manifest['active'] && $captain_id = sys_get_param_id('captain_id')) {
2043
      $captain = sn_module::$sn_module['unit_captain']->unit_captain_get($planetrow['id']);
2044
      if (!$captain) {
2045
        $errorlist .= classLocale::$lang['module_unit_captain_error_no_captain'];
2046
      } elseif ($captain['unit_location_type'] == LOC_PLANET) {
2047
        if ($target_mission == MT_RELOCATE && ($arriving_captain = mrc_get_level($user, $TargetPlanet, UNIT_CAPTAIN, true))) {
2048
          $errorlist .= classLocale::$lang['module_unit_captain_error_captain_already_bound'];
2049
        }
2050
      } else {
2051
        $errorlist .= classLocale::$lang['module_unit_captain_error_captain_flying'];
2052
      }
2053
    }
2054
2055
    if ($errorlist) {
2056
      sn_db_transaction_rollback();
2057
      message("<span class='error'><ul>{$errorlist}</ul></span>", classLocale::$lang['fl_error'], 'fleet' . DOT_PHP_EX, false);
0 ignored issues
show
Documentation introduced by
false is of type boolean, but the function expects a integer.

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

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

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

function acceptsInteger($int) { }

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

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
2058
    }
2059
2060
    //Normally... unless its acs...
2061
    $aks = 0;
2062
    $fleet_group = sys_get_param_int('fleet_group');
2063
    //But is it acs??
2064
    //Well all acs fleets must have a fleet code.
2065
    //The co-ords must be the same as where the acs fleet is going.
2066
    if ($fleet_group && sys_get_param_str('acs_target_mr') == "g{$galaxy}s{$system}p{$planet}t{$planet_type}") {
2067
      //ACS attack must exist (if acs fleet has arrived this will also return false (2 checks in 1!!!)
2068
      $aks = db_acs_get_by_group_id($fleet_group);
2069
      if (!$aks) {
2070
        $fleet_group = 0;
2071
      } else {
2072
        //Also it must be mission type 2
2073
        $target_mission = MT_ACS;
2074
2075
        $galaxy = $aks['galaxy'];
2076
        $system = $aks['system'];
2077
        $planet = $aks['planet'];
2078
        $planet_type = $aks['planet_type'];
2079
      }
2080
    } elseif ($target_mission == MT_ACS) {
2081
      //Check that a failed acs attack isn't being sent, if it is, make it an attack fleet.
2082
      $target_mission = MT_ATTACK;
2083
    }
2084
2085
    if ($target_mission == MT_COLONIZE || $target_mission == MT_EXPLORE) {
2086
      $TargetPlanet = array('galaxy' => $galaxy, 'system' => $system, 'planet' => $planet, 'id_owner' => 0);
2087
    }
2088
    $options = array('fleet_speed_percent' => $speed_percent, 'fleet_group' => $fleet_group, 'resources' => $StorageNeeded);
2089
    $cant_attack = flt_can_attack($planetrow, $TargetPlanet, $fleetarray, $target_mission, $options);
0 ignored issues
show
Documentation introduced by
$options is of type array<string,integer|dou...,"resources":"double"}>, but the function expects a boolean.

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

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

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

function acceptsInteger($int) { }

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

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
2090
2091
    if ($cant_attack !== FLIGHT_ALLOWED) {
2092
      message("<span class='error'><b>{$classLocale['fl_attack_error'][$cant_attack]}</b></span>", classLocale::$lang['fl_error'], 'fleet' . DOT_PHP_EX, 99);
2093
    }
2094
2095
    $mission_time_in_seconds = 0;
2096
    $arrival_time = SN_TIME_NOW + $time_to_travel;
2097
    if ($target_mission == MT_ACS && $aks) {
2098
//    if($fleet_start_time > $aks['ankunft']) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
65% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
2099
      if ($arrival_time > $aks['ankunft']) {
2100
        message(classLocale::$lang['fl_aks_too_slow'] . 'Fleet arrival: ' . date(FMT_DATE_TIME, $arrival_time) . " AKS arrival: " . date(FMT_DATE_TIME, $aks['ankunft']), classLocale::$lang['fl_error']);
2101
      }
2102
      $group_sync_delta_time = $aks['ankunft'] - $arrival_time;
2103
      // Set arrival time to ACS arrival time
2104
      $arrival_time = $aks['ankunft'];
2105
      // Set return time to ACS return time + fleet's time to travel
2106
      $return_time = $aks['ankunft'] + $time_to_travel;
2107
    } else {
2108
      if ($target_mission == MT_EXPLORE || $target_mission == MT_HOLD) {
2109
        $max_duration = $target_mission == MT_EXPLORE ? get_player_max_expedition_duration($user) : ($target_mission == MT_HOLD ? 12 : 0);
2110
        if ($max_duration) {
2111
          $mission_time_in_hours = sys_get_param_id('missiontime');
2112
          if ($mission_time_in_hours > $max_duration || $mission_time_in_hours < 1) {
2113
            $debug->warning('Supplying wrong mission time', 'Hack attempt', 302, array('base_dump' => true));
2114
            die();
2115
          }
2116
          $mission_time_in_seconds = ceil($mission_time_in_hours * 3600 / ($target_mission == MT_EXPLORE && classSupernova::$config->game_speed_expedition ? classSupernova::$config->game_speed_expedition : 1));
2117
        }
2118
      }
2119
      $return_time = $arrival_time + $mission_time_in_seconds + $time_to_travel;
2120
      $group_sync_delta_time = 0;
2121
    }
2122
2123
//    $FleetStorage = 0;
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...
2124
2125
    $db_changeset = array();
2126
    foreach ($fleetarray as $Ship => $Count) {
2127
//      $FleetStorage += get_unit_param($Ship, P_CAPACITY) * $Count;
0 ignored issues
show
Unused Code Comprehensibility introduced by
39% 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...
2128
      $db_changeset['unit'][] = sn_db_unit_changeset_prepare($Ship, -$Count, $user, $planetrow['id']);
2129
    }
2130
//    $FleetStorage -= $consumption;
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...
2131
2132
//    if($StorageNeeded > $FleetStorage) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
52% 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...
2133
//      message("<span class='error'><b>" . classLocale::$lang['fl_nostoragespa'] . pretty_number($StorageNeeded - $FleetStorage) . "</b></span>", classLocale::$lang['fl_error'], 'fleet' . DOT_PHP_EX, 2);
2134
//    }
2135
//    if($planetrow['deuterium'] < $TransDeuterium + $consumption) {
2136
//      message("<font color=\"red\"><b>" . classLocale::$lang['fl_no_deuterium'] . pretty_number($TransDeuterium + $consumption - $planetrow['deuterium']) . "</b></font>", classLocale::$lang['fl_error'], 'fleet' . DOT_PHP_EX, 2);
2137
//    }
2138
//    if(($planetrow['metal'] < $TransMetal) || ($planetrow['crystal'] < $TransCrystal)) {
2139
//      message("<font color=\"red\"><b>" . classLocale::$lang['fl_no_resources'] . "</b></font>", classLocale::$lang['fl_error'], 'fleet' . DOT_PHP_EX, 2);
2140
//    }
2141
2142
2143
    //
2144
    //
2145
    //
2146
    //
2147
    //
2148
    //
2149
    //
2150
    //
2151
    // ---------------- END OF CHECKS ------------------------------------------------------
2152
2153
    $fleetarray[RES_METAL] = $TransMetal;
2154
    $fleetarray[RES_CRYSTAL] = $TransCrystal;
2155
    $fleetarray[RES_DEUTERIUM] = $TransDeuterium;
2156
2157
    $objFleet = new Fleet();
2158
    $objFleet->set_times($time_to_travel, $mission_time_in_seconds, $group_sync_delta_time);
2159
    $objFleet->unitsSetFromArray($fleetarray);
2160
    $objFleet->mission_type = $target_mission;
2161
    $objFleet->set_start_planet($planetrow);
2162
    $objFleet->set_end_planet(array(
2163
      'id'          => !empty($TargetPlanet['id']) ? $TargetPlanet['id'] : null,
2164
      'galaxy'      => !empty($galaxy) ? $galaxy : 0,
2165
      'system'      => !empty($system) ? $system : 0,
2166
      'planet'      => !empty($planet) ? $planet : 0,
2167
      'planet_type' => !empty($planet_type) ? $planet_type : 0,
2168
      'id_owner'    => $TargetPlanet['id_owner'],
2169
    ));
2170
    $objFleet->playerOwnerId = $user['id'];
2171
    $objFleet->group_id = $fleet_group;
2172
    $objFleet->dbInsert();
2173
2174
    db_planet_set_by_id($planetrow['id'], "`metal` = `metal` - {$TransMetal}, `crystal` = `crystal` - {$TransCrystal}, `deuterium` = `deuterium` - {$TransDeuterium} - {$consumption}");
2175
    db_changeset_apply($db_changeset);
2176
2177
    $template = gettemplate('fleet3', true);
2178
2179
    if (is_array($captain)) {
2180
      db_unit_set_by_id($captain['unit_id'], "`unit_location_type` = " . LOC_FLEET . ", `unit_location_id` = {$objFleet->dbId}");
0 ignored issues
show
Bug introduced by
The variable $captain does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
2181
    }
2182
2183
    $template_route = array(
2184
      'ID'                 => 1,
2185
      'START_TYPE_TEXT_SH' => classLocale::$lang['sys_planet_type_sh'][$planetrow['planet_type']],
2186
      'START_COORDS'       => uni_render_coordinates($planetrow),
2187
      'START_NAME'         => $planetrow['name'],
2188
      'START_TIME_TEXT'    => date(FMT_DATE_TIME, $return_time + SN_CLIENT_TIME_DIFF),
2189
      'START_LEFT'         => floor($return_time + 1 - SN_TIME_NOW),
2190
    );
2191
    if (!empty($TargetPlanet)) {
2192
      $template_route += array(
2193
        'END_TYPE_TEXT_SH' => classLocale::$lang['sys_planet_type_sh'][$TargetPlanet['planet_type']],
2194
        'END_COORDS'       => uni_render_coordinates($TargetPlanet),
2195
        'END_NAME'         => $TargetPlanet['name'],
2196
        'END_TIME_TEXT'    => date(FMT_DATE_TIME, $arrival_time + SN_CLIENT_TIME_DIFF),
2197
        'END_LEFT'         => floor($arrival_time + 1 - SN_TIME_NOW),
2198
      );
2199
    }
2200
2201
    $template->assign_block_vars('fleets', $template_route);
2202
2203
    $sn_groups_fleet = sn_get_groups('fleet');
2204
    foreach ($fleetarray as $ship_id => $ship_count) {
2205
      if (in_array($ship_id, $sn_groups_fleet) && $ship_count) {
2206
//      $ship_base_data = get_ship_data($ship_id, $user);
0 ignored issues
show
Unused Code Comprehensibility introduced by
54% 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...
2207
        $template->assign_block_vars('fleets.ships', array(
2208
          'ID'          => $ship_id,
2209
          'AMOUNT'      => $ship_count,
2210
          'AMOUNT_TEXT' => pretty_number($ship_count),
2211
//        'CONSUMPTION' => $ship_base_data['consumption'],
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...
2212
//        'SPEED'       => $ship_base_data['speed'],
2213
          'NAME'        => classLocale::$lang['tech'][$ship_id],
2214
        ));
2215
      }
2216
    }
2217
2218
    $template->assign_vars(array(
2219
      'mission'         => classLocale::$lang['type_mission'][$target_mission] . ($target_mission == MT_EXPLORE || $target_mission == MT_HOLD ? ' ' . pretty_time($mission_time_in_seconds) : ''),
2220
      'dist'            => pretty_number($distance),
2221
      'speed'           => pretty_number($fleet_speed),
2222
      'deute_need'      => pretty_number($consumption),
2223
      'from'            => "{$planetrow['galaxy']}:{$planetrow['system']}:{$planetrow['planet']}",
2224
      'time_go'         => date(FMT_DATE_TIME, $arrival_time),
2225
      'time_go_local'   => date(FMT_DATE_TIME, $arrival_time + SN_CLIENT_TIME_DIFF),
2226
      'time_back'       => date(FMT_DATE_TIME, $return_time),
2227
      'time_back_local' => date(FMT_DATE_TIME, $return_time + SN_CLIENT_TIME_DIFF),
2228
    ));
2229
2230
    pdie('Stop for debug');
2231
2232
    sn_db_transaction_commit();
2233
    $planetrow = db_planet_by_id($planetrow['id']);
2234
    $template->assign_recursive($template_result);
2235
    display($template, classLocale::$lang['fl_title']);
2236
  }
2237
2238
2239
  /**
2240
   * @param array $checklist
2241
   *
2242
   * @throws Exception
2243
   */
2244
  public function checkMissionRestrictions($checklist) {
2245
    foreach ($checklist as $condition => $action) {
2246
      $checkResult = call_user_func(array($this, $condition));
2247
2248
      if (is_array($action) && !empty($action[$checkResult])) {
2249
        $action = $action[$checkResult];
2250
      }
2251
2252
      if (is_array($action)) {
2253
        $this->checkMissionRestrictions($action);
2254
      } elseif (!$checkResult) {
2255
        throw new Exception($action, $action);
2256
      }
2257
    }
2258
  }
2259
2260
  protected function checkSpeedPercentOld() {
2261
    return in_array($this->oldSpeedInTens, array(10, 9, 8, 7, 6, 5, 4, 3, 2, 1));
2262
  }
2263
2264
  protected function checkSenderNoVacation() {
2265
    return empty($this->dbOwnerRow['vacation']) || $this->dbOwnerRow['vacation'] >= SN_TIME_NOW;
2266
  }
2267
2268
  protected function checkTargetNoVacation() {
2269
    return empty($this->dbTargetOwnerRow['vacation']) || $this->dbTargetOwnerRow['vacation'] >= SN_TIME_NOW;
2270
  }
2271
2272
  protected function checkMultiAccount() {
2273
    return sys_is_multiaccount($this->dbOwnerRow, $this->dbTargetOwnerRow);
2274
  }
2275
2276
  protected function checkFleetNotEmpty() {
2277
    return $this->unitList->unitsCount() >= 1;
2278
  }
2279
2280
  protected function checkTargetNotSource() {
2281
    return !$this->targetVector->isEqualToPlanet($this->dbSourcePlanetRow);
2282
  }
2283
2284
  protected function checkTargetInUniverse() {
2285
    return $this->targetVector->isInUniverse();
2286
  }
2287
2288
  protected function checkUnitsPositive() {
2289
    return $this->unitList->unitsPositive();
2290
  }
2291
2292
  protected function checkOnlyFleetUnits() {
2293
    return $this->unitList->unitsInGroup(sn_get_groups(array('fleet', 'missile')));
2294
  }
2295
2296
  protected function checkOnlyFlyingUnits() {
2297
    return $this->unitList->unitsIsAllMovable($this->dbOwnerRow);
2298
  }
2299
2300
  protected function checkEnoughFleetSlots() {
2301
    return FleetList::fleet_count_flying($this->getPlayerOwnerId()) < GetMaxFleets($this->dbOwnerRow);
2302
  }
2303
2304
  protected function checkSourceEnoughShips() {
2305
    return $this->unitList->shipsIsEnoughOnPlanet($this->dbSourcePlanetRow);
2306
  }
2307
2308
  protected function checkEnoughCapacity($includeResources = true) {
2309
    $checkVia = $this->travelData['consumption'];
2310
    $checkVia = ceil(($includeResources ? array_sum($this->resource_list) : 0) + $checkVia);
2311
2312
    return
2313
      !empty($this->travelData) &&
2314
      is_array($this->travelData) &&
2315
      floor($this->travelData['capacity']) >= $checkVia;
2316
  }
2317
2318
  protected function checkNotTooFar() {
2319
    return $this->checkEnoughCapacity(false);
2320
  }
2321
2322
  protected function checkDebrisExists() {
2323
    return is_array($this->dbTargetRow) && ($this->dbTargetRow['debris_metal'] + $this->dbTargetRow['debris_crystal'] > 0);
2324
  }
2325
2326
  protected function checkResourcesPositive() {
2327
    foreach ($this->resource_list as $resourceId => $resourceAmount) {
2328
      if ($resourceAmount < 0) {
2329
        return false;
2330
      }
2331
    }
2332
2333
    return true;
2334
  }
2335
2336
  protected function checkCargo() {
2337
    return array_sum($this->resource_list) >= 1;
2338
  }
2339
2340
  protected function checkSourceEnoughFuel() {
2341
    $deuteriumOnPlanet = mrc_get_level($this->dbOwnerRow, $this->dbSourcePlanetRow, RES_DEUTERIUM);
2342
2343
    return $deuteriumOnPlanet < ceil($this->travelData['consumption']);
2344
  }
2345
2346
2347
  protected function checkSourceEnoughResources() {
2348
    $fleetResources = $this->resource_list;
2349
    $fleetResources[RES_DEUTERIUM] = ceil($fleetResources[RES_DEUTERIUM] + $this->travelData['consumption']);
2350
    foreach ($fleetResources as $resourceId => $resourceAmount) {
2351
      if (mrc_get_level($this->dbOwnerRow, $this->dbSourcePlanetRow, $resourceId) < ceil($fleetResources[$resourceId])) {
2352
        return false;
2353
      }
2354
    }
2355
2356
    return true;
2357
  }
2358
2359
  protected function checkKnownSpace() {
2360
    return $this->targetVector->isInKnownSpace();
2361
  }
2362
2363
  protected function checkNotOnlySpies() {
2364
    return $this->unitList->unitsCountById(SHIP_SPY) < $this->shipsGetTotal();
2365
  }
2366
2367
  public function checkNoMissiles() {
2368
    return
2369
      $this->unitList->unitsCountById(UNIT_DEF_MISSILE_INTERPLANET) == 0
2370
      &&
2371
      $this->unitList->unitsCountById(UNIT_DEF_MISSILE_INTERCEPTOR) == 0;
2372
  }
2373
2374
2375
  protected function checkTargetExists() {
2376
    return !empty($this->dbTargetRow['id']);
2377
  }
2378
2379
  protected function checkHaveColonizer() {
2380
    // Colonization fleet should have at least one colonizer
2381
    return $this->unitList->unitsCountById(SHIP_COLONIZER) >= 1;
2382
  }
2383
2384
  protected function checkTargetIsPlanet() {
2385
    return $this->targetVector->type == PT_PLANET;
2386
  }
2387
2388
  protected function checkTargetIsDebris() {
2389
    return $this->targetVector->type == PT_DEBRIS;
2390
  }
2391
2392
  protected function checkHaveRecyclers() {
2393
    $recyclers = 0;
2394
    foreach (sn_get_groups('flt_recyclers') as $recycler_id) {
2395
      $recyclers += $this->unitList->unitsCountById($recycler_id);
2396
    }
2397
2398
    return $recyclers >= 1;
2399
  }
2400
2401
2402
  /**
2403
   * @return bool
2404
   */
2405
  protected function checkTargetOwn() {
2406
    return $this->dbTargetRow['id_owner'] == $this->dbSourcePlanetRow['id_owner'];
2407
  }
2408
2409
  /**
2410
   * @return bool
2411
   */
2412
  protected function checkTargetOther() {
2413
    return !$this->checkTargetOwn();
2414
  }
2415
2416
  /**
2417
   * @return bool
2418
   */
2419
  protected function forceTargetOwn() {
2420
    if ($result = $this->checkTargetOwn()) {
2421
      // Spying can't be done on owner's planet/moon
2422
      unset($this->allowed_missions[MT_SPY]);
2423
      // Attack can't be done on owner's planet/moon
2424
      unset($this->allowed_missions[MT_ATTACK]);
2425
      // ACS can't be done on owner's planet/moon
2426
      unset($this->allowed_missions[MT_ACS]);
2427
      // Destroy can't be done on owner's moon
2428
      unset($this->allowed_missions[MT_DESTROY]);
2429
      unset($this->allowed_missions[MT_MISSILE]);
2430
2431
      // MT_RELOCATE
2432
      // No checks
2433
      // TODO - check captain
2434
2435
      // MT_HOLD
2436
      // TODO - Check for Allies Deposit for HOLD
2437
2438
      // MT_TRANSPORT
2439
2440
    } else {
2441
      // Relocate can be done only on owner's planet/moon
2442
      unset($this->allowed_missions[MT_RELOCATE]);
2443
2444
    }
2445
2446
    return $result; // this->getPlayerOwnerId();
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...
2447
  }
2448
2449
2450
  protected function alwaysFalse() {
2451
    return false;
2452
  }
2453
2454
2455
  protected function checkSpiesOnly() {
2456
    return $this->unitList->unitsCountById(SHIP_SPY) == $this->shipsGetTotal();
2457
  }
2458
2459
  protected function checkTargetAllyDeposit() {
2460
    $result = mrc_get_level($this->dbTargetOwnerRow, $this->dbTargetRow, STRUC_ALLY_DEPOSIT) >= 1;
2461
    if (!$result) {
2462
      unset($this->allowed_missions[MT_HOLD]);
2463
    }
2464
2465
    return $result;
2466
  }
2467
2468
2469
  /**
2470
   * Forces missions that can flight to OWN planets
2471
   *
2472
   * @return bool
2473
   */
2474
  protected function forceMissionsOwn() {
2475
    $result =
2476
      !$this->_mission_type
2477
      ||
2478
      in_array($this->_mission_type, array(
2479
        MT_HOLD,
2480
        MT_RECYCLE,
2481
        MT_RELOCATE,
2482
        MT_TRANSPORT,
2483
      ));
2484
2485
    unset($this->allowed_missions[MT_ATTACK]);
2486
    unset($this->allowed_missions[MT_COLONIZE]);
2487
    unset($this->allowed_missions[MT_EXPLORE]);
2488
    unset($this->allowed_missions[MT_ACS]);
2489
    unset($this->allowed_missions[MT_SPY]);
2490
    unset($this->allowed_missions[MT_DESTROY]);
2491
    unset($this->allowed_missions[MT_MISSILE]);
2492
2493
    return $result;
2494
  }
2495
2496
  /**
2497
   * Check mission type OR no mission - and limits available missions to this type if positive
2498
   *
2499
   * @param int $missionType
2500
   *
2501
   * @return bool
2502
   */
2503
  protected function forceMission($missionType) {
2504
    $result = !$this->_mission_type || $this->_mission_type == $missionType;
2505
    if ($result) {
2506
      $this->allowed_missions = array(
2507
        $missionType => $this->exists_missions[$missionType],
2508
      );
2509
    } else {
2510
      unset($this->allowed_missions[$missionType]);
2511
    }
2512
2513
    return $result;
2514
  }
2515
2516
  protected function forceMissionExplore() {
2517
    return $this->forceMission(MT_EXPLORE);
2518
  }
2519
2520
  protected function forceMissionColonize() {
2521
    return $this->forceMission(MT_COLONIZE);
2522
  }
2523
2524
  protected function forceMissionRecycle() {
2525
    return $this->forceMission(MT_RECYCLE);
2526
  }
2527
2528
  protected function forceMissionMissile() {
2529
    return $this->forceMission(MT_MISSILE);
2530
  }
2531
2532
  /**
2533
   * Just checks mission type
2534
   *
2535
   * @param int $missionType
2536
   *
2537
   * @return bool
2538
   */
2539
  protected function checkMissionNonRestrict($missionType) {
2540
    return $this->_mission_type == $missionType;
2541
  }
2542
2543
2544
  protected function checkNotEmptyMission() {
2545
    return !empty($this->_mission_type);
2546
  }
2547
2548
  protected function checkMissionRelocate() {
2549
    return $this->checkMissionNonRestrict(MT_RELOCATE);
2550
  }
2551
2552
  protected function checkMissionHoldNonUnique() {
2553
    $result = $this->checkMissionNonRestrict(MT_HOLD);
2554
2555
    return $result;
2556
  }
2557
2558
  protected function checkMissionTransport() {
2559
    return $this->checkMissionNonRestrict(MT_TRANSPORT);
2560
  }
2561
2562
  protected function checkMissionTransportReal() {
2563
    return
2564
      $this->checkRealFlight()
2565
      &&
2566
      $this->checkMissionTransport();
2567
  }
2568
2569
2570
  protected function forceMissionSpy() {
2571
    return $this->forceMission(MT_SPY);
2572
  }
2573
2574
  /**
2575
   * @return bool
2576
   */
2577
  protected function unsetMissionSpyComplex() {
2578
    unset($this->allowed_missions[MT_SPY]);
2579
    if($this->_mission_type == MT_SPY) {
2580
      if($this->checkRealFlight()) {
2581
        return false;
2582
      }
2583
      $this->_mission_type = MT_NONE;
2584
    }
2585
2586
    return true;
2587
  }
2588
2589
2590
  protected function checkRealFlight() {
2591
    return $this->isRealFlight;
2592
  }
2593
2594
  /**
2595
   * @return bool
2596
   */
2597
  protected function checkMissionExists() {
2598
    return !empty($this->exists_missions[$this->_mission_type]);
2599
  }
2600
2601
  /**
2602
   * @return bool
2603
   */
2604
  protected function checkPlayerInactiveOrNotNoob() {
2605
    return
2606
      $this->checkTargetNotActive()
2607
      ||
2608
      $this->checkTargetNotNoob();
2609
  }
2610
2611
  /**
2612
   * @return bool
2613
   */
2614
  protected function checkTargetActive() {
2615
    return
2616
      empty($this->dbTargetOwnerRow['onlinetime'])
2617
      ||
2618
      SN_TIME_NOW - $this->dbTargetOwnerRow['onlinetime'] >= PLAYER_TIME_ACTIVE_SECONDS;
2619
  }
2620
2621
  // TODO - REDO MAIN FUNCTION
2622
  protected function checkTargetNotActive() {
2623
    return !$this->checkTargetActive();
2624
  }
2625
2626
2627
  /**
2628
   * @return bool
2629
   */
2630
  protected function checkSameAlly() {
2631
    return !empty($this->dbTargetOwnerRow['ally_id']) && $this->dbTargetOwnerRow['ally_id'] == $this->dbOwnerRow['ally_id'];
2632
  }
2633
2634
  /**
2635
   * @return bool
2636
   */
2637
  protected function checkTargetNoob() {
2638
    $user_points = $this->dbTargetOwnerRow['total_points'];
2639
    $enemy_points = $this->dbTargetOwnerRow['total_points'];
2640
2641
    return
2642
      // Target is under Noob Protection but Fleet owner is not
2643
      (
2644
        classSupernova::$config->game_noob_points
2645
        &&
2646
        $enemy_points <= classSupernova::$config->game_noob_points
2647
        &&
2648
        $user_points > classSupernova::$config->game_noob_points
2649
      ) || (
2650
        classSupernova::$config->game_noob_factor
2651
        &&
2652
        $user_points > $enemy_points * classSupernova::$config->game_noob_factor
2653
      );
2654
  }
2655
2656
  // TODO - REDO MAIN FUNCTION
2657
  protected function checkTargetNotNoob() {
2658
    return !$this->checkTargetNoob();
2659
  }
2660
2661
2662
  protected function checkMissionHoldReal() {
2663
    return
2664
      $this->checkRealFlight()
2665
      &&
2666
      $this->checkMissionHoldNonUnique();
2667
  }
2668
2669
2670
  protected function checkMissionHoldOnNotNoob() {
2671
    return
2672
      $this->checkTargetNotActive()
2673
      ||
2674
      ($this->checkSameAlly() && classSupernova::$config->ally_help_weak)
2675
      ||
2676
      $this->checkTargetNotNoob();
2677
  }
2678
2679
2680
  protected function checkOnlyAttackMissiles() {
2681
    $missilesAttack = $this->unitList->unitsCountById(UNIT_DEF_MISSILE_INTERPLANET);
2682
2683
    return $missilesAttack != 0 && $missilesAttack == $this->shipsGetTotal();
2684
  }
2685
2686
  protected function checkSiloLevel() {
2687
    $sn_data_mip = get_unit_param(UNIT_DEF_MISSILE_INTERPLANET);
2688
2689
    return mrc_get_level($this->dbOwnerRow, $this->dbSourcePlanetRow, STRUC_SILO) >= $sn_data_mip[P_REQUIRE][STRUC_SILO];
2690
  }
2691
2692
  protected function checkSameGalaxy() {
2693
    return $this->targetVector->galaxy == $this->dbSourcePlanetRow['galaxy'];
2694
  }
2695
2696
  protected function checkMissileDistance() {
2697
    return abs($this->dbSourcePlanetRow['system'] - $this->targetVector->system) <= flt_get_missile_range($this->dbOwnerRow);
2698
  }
2699
2700
  protected function checkMissileTarget() {
2701
    return empty($this->targetedUnitId) || in_array($this->targetedUnitId, sn_get_groups('defense_active'));
2702
  }
2703
2704
}
2705