Completed
Push — work-fleets ( 6d7489...ab257a )
by SuperNova.WS
05:48
created

Fleet::set_end_planet()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 8
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 8
rs 9.4285
cc 3
eloc 7
nc 4
nop 1
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
34
  // DBRow inheritance *************************************************************************************************
35
36
  /**
37
   * Table name in DB
38
   *
39
   * @var string
40
   */
41
  protected static $_table = 'fleets';
42
  /**
43
   * Name of ID field in DB
44
   *
45
   * @var string
46
   */
47
  protected static $_dbIdFieldName = 'fleet_id';
48
  /**
49
   * DB_ROW to Class translation scheme
50
   *
51
   * @var array
52
   */
53
  protected static $_properties = array(
54
    'dbId'          => array(
55
      P_DB_FIELD => 'fleet_id',
56
    ),
57
    'playerOwnerId' => array(
58
      P_METHOD_EXTRACT => 'ownerExtract',
59
      P_METHOD_INJECT  => 'ownerInject',
60
//      P_DB_FIELD => 'fleet_owner',
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
61
    ),
62
    'mission_type'  => array(
63
      P_DB_FIELD   => 'fleet_mission',
64
      P_FUNC_INPUT => 'intval',
65
    ),
66
67
    'target_owner_id' => array(
68
      P_DB_FIELD => 'fleet_target_owner',
69
    ),
70
    'group_id'        => array(
71
      P_DB_FIELD => 'fleet_group',
72
    ),
73
    'is_returning'    => array(
74
      P_DB_FIELD   => 'fleet_mess',
75
      P_FUNC_INPUT => 'intval',
76
    ),
77
78
    'shipCount' => array(
79
      P_DB_FIELD  => 'fleet_amount',
80
// TODO - CHECK !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
0 ignored issues
show
Unused Code Comprehensibility introduced by
80% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
81
//      P_FUNC_OUTPUT => 'get_ship_count',
82
//      P_DB_FIELDS_LINKED => array(
83
//        'fleet_amount',
84
//      ),
85
      P_READ_ONLY => true,
86
    ),
87
88
    'time_launch' => array(
89
      P_DB_FIELD => 'start_time',
90
    ),
91
92
    'time_arrive_to_target'     => array(
93
      P_DB_FIELD => 'fleet_start_time',
94
    ),
95
    'time_mission_job_complete' => array(
96
      P_DB_FIELD => 'fleet_end_stay',
97
    ),
98
    'time_return_to_source'     => array(
99
      P_DB_FIELD => 'fleet_end_time',
100
    ),
101
102
    'fleet_start_planet_id' => array(
103
      P_DB_FIELD   => 'fleet_start_planet_id',
104
      P_FUNC_INPUT => 'nullIfEmpty',
105
    ),
106
107
    'fleet_start_galaxy' => array(
108
      P_DB_FIELD => 'fleet_start_galaxy',
109
    ),
110
    'fleet_start_system' => array(
111
      P_DB_FIELD => 'fleet_start_system',
112
    ),
113
    'fleet_start_planet' => array(
114
      P_DB_FIELD => 'fleet_start_planet',
115
    ),
116
    'fleet_start_type'   => array(
117
      P_DB_FIELD => 'fleet_start_type',
118
    ),
119
120
    'fleet_end_planet_id' => array(
121
      P_DB_FIELD   => 'fleet_end_planet_id',
122
      P_FUNC_INPUT => 'nullIfEmpty',
123
    ),
124
    'fleet_end_galaxy'    => array(
125
      P_DB_FIELD => 'fleet_end_galaxy',
126
    ),
127
    'fleet_end_system'    => array(
128
      P_DB_FIELD => 'fleet_end_system',
129
    ),
130
    'fleet_end_planet'    => array(
131
      P_DB_FIELD => 'fleet_end_planet',
132
    ),
133
    'fleet_end_type'      => array(
134
      P_DB_FIELD => 'fleet_end_type',
135
    ),
136
137
    'resource_list' => array(
138
      P_METHOD_EXTRACT   => 'resourcesExtract',
139
      P_METHOD_INJECT    => 'resourcesInject',
140
      P_DB_FIELDS_LINKED => array(
141
        'fleet_resource_metal',
142
        'fleet_resource_crystal',
143
        'fleet_resource_deuterium',
144
      ),
145
    ),
146
  );
147
148
149
  // UnitContainer inheritance *****************************************************************************************
150
  /**
151
   * Type of this location
152
   *
153
   * @var int $locationType
154
   */
155
  protected static $locationType = LOC_FLEET;
156
157
158
  // New properties ****************************************************************************************************
159
  /**
160
   * `fleet_owner`
161
   *
162
   * @var int
163
   */
164
  protected $_playerOwnerId = 0;
165
  /**
166
   * `fleet_group`
167
   *
168
   * @var int
169
   */
170
  protected $_group_id = 0;
171
172
  /**
173
   * `fleet_mission`
174
   *
175
   * @var int
176
   */
177
  protected $_mission_type = 0;
178
179
  /**
180
   * `fleet_target_owner`
181
   *
182
   * @var int
183
   */
184
  protected $_target_owner_id = null;
185
186
  /**
187
   * @var array
188
   */
189
  protected $resource_list = array(
190
    RES_METAL     => 0,
191
    RES_CRYSTAL   => 0,
192
    RES_DEUTERIUM => 0,
193
  );
194
195
196
  /**
197
   * `fleet__mess` - Флаг возвращающегося флота
198
   *
199
   * @var int
200
   */
201
  protected $_is_returning = 0;
202
  /**
203
   * `start_time` - Время отправления - таймштамп взлёта флота из точки отправления
204
   *
205
   * @var int $_time_launch
206
   */
207
  protected $_time_launch = 0; // `start_time` = SN_TIME_NOW
208
  /**
209
   * `fleet_start_time` - Время прибытия в точку миссии/время начала выполнения миссии
210
   *
211
   * @var int $_time_arrive_to_target
212
   */
213
  protected $_time_arrive_to_target = 0; // `fleet_start_time` = SN_TIME_NOW + $time_travel
214
  /**
215
   * `fleet_end_stay` - Время окончания миссии в точке назначения
216
   *
217
   * @var int $_time_mission_job_complete
218
   */
219
  protected $_time_mission_job_complete = 0; // `fleet_end_stay`
220
  /**
221
   * `fleet_end_time` - Время возвращения флота после окончания миссии
222
   *
223
   * @var int $_time_return_to_source
224
   */
225
  protected $_time_return_to_source = 0; // `fleet_end_time`
226
227
228
  protected $_fleet_start_planet_id = null;
229
  protected $_fleet_start_galaxy = 0;
230
  protected $_fleet_start_system = 0;
231
  protected $_fleet_start_planet = 0;
232
  protected $_fleet_start_type = PT_ALL;
233
234
  protected $_fleet_end_planet_id = null;
235
  protected $_fleet_end_galaxy = 0;
236
  protected $_fleet_end_system = 0;
237
  protected $_fleet_end_planet = 0;
238
  protected $_fleet_end_type = PT_ALL;
239
240
  // Missile properties
241
  public $missile_target = 0;
242
243
  // Fleet event properties
244
  public $fleet_start_name = '';
245
  public $fleet_end_name = '';
246
  public $ov_label = '';
247
  public $ov_this_planet = '';
248
  public $event_time = 0;
249
250
  protected $resource_delta = array();
251
  protected $resource_replace = array();
252
253
254
//
255
256
257
  protected $allowed_missions = array();
258
  protected $allowed_planet_types = array(
259
    // PT_NONE => PT_NONE,
260
    PT_PLANET => PT_PLANET,
261
    PT_MOON   => PT_MOON,
262
    PT_DEBRIS => PT_DEBRIS
263
  );
264
265
  // TODO - Move to Player
266
  public $dbOwnerRow = array();
267
  public $dbSourcePlanetRow = array();
268
269
  /**
270
   * GSPT coordinates of target
271
   *
272
   * @var Vector
273
   */
274
  public $targetVector = array();
275
  /**
276
   * Target planet row
277
   *
278
   * @var array
279
   */
280
  public $dbTargetRow = array();
281
  public $dbTargetOwnerRow = array();
282
283
  /**
284
   * Fleet speed - old in 1/10 of 100%
285
   *
286
   * @var int
287
   */
288
  public $oldSpeedInTens = 0;
289
290
  public $tempPlayerMaxFleets = 0;
291
292
  /**
293
   * Fleet constructor.
294
   */
295
  public function __construct() {
296
    parent::__construct();
297
    $this->allowed_missions = sn_get_groups('missions');
0 ignored issues
show
Documentation Bug introduced by
It seems like sn_get_groups('missions') of type * is incompatible with the declared type array of property $allowed_missions.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

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

Loading history...
298
  }
299
300
  /**
301
   * @param array $template_result
302
   * @param array $playerRow
303
   * @param array $planetRow
304
   */
305
  // TODO - redo to unit/unitlist renderer
306
  public function renderAvailableShips(&$template_result, $playerRow, $planetRow) {
307
    $record_index = 0;
308
    $ship_list = array();
309
    foreach(sn_get_groups('fleet') as $n => $unit_id) {
310
      $unit_level = mrc_get_level($playerRow, $planetRow, $unit_id, false, true);
311
      if($unit_level <= 0) {
312
        continue;
313
      }
314
      $ship_data = get_ship_data($unit_id, $playerRow);
315
      $ship_list[$unit_id] = array(
316
        '__INDEX'          => $record_index++,
317
        'ID'               => $unit_id,
318
        'NAME'             => classLocale::$lang['tech'][$unit_id],
319
        'AMOUNT'           => $unit_level,
320
        'AMOUNT_TEXT'      => pretty_number($unit_level),
321
        'CONSUMPTION'      => $ship_data['consumption'],
322
        'CONSUMPTION_TEXT' => pretty_number($ship_data['consumption']),
323
        'SPEED'            => $ship_data['speed'],
324
        'SPEED_TEXT'       => pretty_number($ship_data['speed']),
325
        'CAPACITY'         => $ship_data['capacity'],
326
        'CAPACITY_TEXT'    => pretty_number($ship_data['capacity']),
327
      );
328
    }
329
330
    sortUnitRenderedList($ship_list, classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_SORT], classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_SORT_INVERSE]);
331
332
    foreach($ship_list as $ship_data) {
333
      $template_result['.']['ships'][] = $ship_data;
334
    }
335
  }
336
337
  public function isEmpty() {
338
    return !$this->resourcesGetTotal() && !$this->shipsGetTotal();
339
  }
340
341
//  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...
342
//    return $this->playerOwnerId;
343
//  }
344
345
  /**
346
   * Initializes Fleet from user params and posts it to DB
347
   */
348
  public function dbInsert() {
349
    // WARNING! MISSION TIMES MUST BE SET WITH set_times() method!
350
    // TODO - more checks!
351
    if(empty($this->_time_launch)) {
352
      die('Fleet time not set!');
353
    }
354
355
    parent::dbInsert();
356
  }
357
358
359
  /* FLEET DB ACCESS =================================================================================================*/
360
361
  /**
362
   * LOCK - Lock all records which can be used with mission
363
   *
364
   * @param $mission_data
365
   * @param $fleet_id
366
   *
367
   * @return array|bool|mysqli_result|null
368
   */
369
  public function dbLockFlying(&$mission_data) {
370
    // Тупо лочим всех юзеров, чьи флоты летят или улетают с координат отбытия/прибытия $fleet_row
371
    // Что бы делать это умно - надо учитывать fleet__mess во $fleet_row и в таблице fleets
372
373
    $fleet_id_safe = idval($this->_dbId);
374
375
    return doquery(
376
    // Блокировка самого флота
377
      "SELECT 1 FROM {{fleets}} AS f " .
378
379
      // Блокировка всех юнитов, принадлежащих этому флоту
380
      "LEFT JOIN {{unit}} as unit ON unit.unit_location_type = " . static::$locationType . " AND unit.unit_location_id = f.fleet_id " .
381
382
      // Блокировка всех прилетающих и улетающих флотов, если нужно
383
      // TODO - lock fleets by COORDINATES
384
      ($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 " : '') .
385
      // Блокировка всех юнитов, принадлежащих прилетающим и улетающим флотам - ufd = unit_fleet_destination
386
      ($mission_data['dst_fleets'] ? "LEFT JOIN {{unit}} AS ufd ON ufd.unit_location_type = " . static::$locationType . " AND ufd.unit_location_id = fd.fleet_id " : '') .
387
388
      ($mission_data['dst_user'] || $mission_data['dst_planet'] ? "LEFT JOIN {{users}} AS ud ON ud.id = f.fleet_target_owner " : '') .
389
      // Блокировка всех юнитов, принадлежащих владельцу планеты-цели
390
      ($mission_data['dst_user'] || $mission_data['dst_planet'] ? "LEFT JOIN {{unit}} AS unit_player_dest ON unit_player_dest.unit_player_id = ud.id " : '') .
391
      // Блокировка планеты-цели
392
      ($mission_data['dst_planet'] ? "LEFT JOIN {{planets}} AS pd ON pd.id = f.fleet_end_planet_id " : '') .
393
      // Блокировка всех юнитов, принадлежащих планете-цели - НЕ НУЖНО. Уже залочили ранее, как принадлежащие игроку-цели
394
//      ($mission_data['dst_planet'] ? "LEFT JOIN {{unit}} AS upd ON upd.unit_location_type = " . LOC_PLANET . " AND upd.unit_location_id = pd.id " : '') .
395
396
397
      ($mission_data['src_user'] || $mission_data['src_planet'] ? "LEFT JOIN {{users}} AS us ON us.id = f.fleet_owner " : '') .
398
      // Блокировка всех юнитов, принадлежащих владельцу флота
399
      ($mission_data['src_user'] || $mission_data['src_planet'] ? "LEFT JOIN {{unit}} AS unit_player_src ON unit_player_src.unit_player_id = us.id " : '') .
400
      // Блокировка планеты отправления
401
      ($mission_data['src_planet'] ? "LEFT JOIN {{planets}} AS ps ON ps.id = f.fleet_start_planet_id " : '') .
402
      // Блокировка всех юнитов, принадлежащих планете с которой юниты были отправлены - НЕ НУЖНО. Уже залочили ранее, как принадлежащие владельцу флота
403
//      ($mission_data['src_planet'] ? "LEFT JOIN {{unit}} AS ups ON ups.unit_location_type = " . LOC_PLANET . " AND ups.unit_location_id = ps.id " : '') .
404
405
      "WHERE f.fleet_id = {$fleet_id_safe} GROUP BY 1 FOR UPDATE"
406
    );
407
  }
408
409
  /**
410
   * Lock all fields that belongs to operation
411
   *
412
   * @param $dbId
413
   *
414
   * @internal param DBLock $dbRow - Object that accumulates locks
415
   *
416
   */
417
  // TODO = make static
418
  public function dbGetLockById($dbId) {
419
    doquery(
420
    // Блокировка самого флота
421
      "SELECT 1 FROM {{fleets}} AS FLEET0 " .
422
      // Lock fleet owner
423
      "LEFT JOIN {{users}} as USER0 on USER0.id = FLEET0.fleet_owner " .
424
      // Блокировка всех юнитов, принадлежащих этому флоту
425
      "LEFT JOIN {{unit}} as UNIT0 ON UNIT0.unit_location_type = " . LOC_FLEET . " AND UNIT0.unit_location_id = FLEET0.fleet_id " .
426
427
      // Без предварительной выборки неизвестно - куда летит этот флот.
428
      // Поэтому надо выбирать флоты, чьи координаты прибытия ИЛИ отбытия совпадают с координатами прибытия ИЛИ отбытия текущего флота.
429
      // Получаем матрицу 2х2 - т.е. 4 подзапроса.
430
      // При блокировке всегда нужно выбирать И лпанету, И луну - поскольку при бое на орбите луны обломки падают на орбиту планеты.
431
      // Поэтому тип планеты не указывается
432
433
      // Lock fleet heading to destination planet. Only if FLEET0.fleet_mess == 0
434
      "LEFT JOIN {{fleets}} AS FLEET1 ON
435
        FLEET1.fleet_mess = 0 AND FLEET0.fleet_mess = 0 AND
436
        FLEET1.fleet_end_galaxy = FLEET0.fleet_end_galaxy AND
437
        FLEET1.fleet_end_system = FLEET0.fleet_end_system AND
438
        FLEET1.fleet_end_planet = FLEET0.fleet_end_planet
439
      " .
440
      // Блокировка всех юнитов, принадлежащих этим флотам
441
      "LEFT JOIN {{unit}} as UNIT1 ON UNIT1.unit_location_type = " . LOC_FLEET . " AND UNIT1.unit_location_id = FLEET1.fleet_id " .
442
      // Lock fleet owner
443
      "LEFT JOIN {{users}} as USER1 on USER1.id = FLEET1.fleet_owner " .
444
445
      "LEFT JOIN {{fleets}} AS FLEET2 ON
446
        FLEET2.fleet_mess = 1   AND FLEET0.fleet_mess = 0 AND
447
        FLEET2.fleet_start_galaxy = FLEET0.fleet_end_galaxy AND
448
        FLEET2.fleet_start_system = FLEET0.fleet_end_system AND
449
        FLEET2.fleet_start_planet = FLEET0.fleet_end_planet
450
      " .
451
      // Блокировка всех юнитов, принадлежащих этим флотам
452
      "LEFT JOIN {{unit}} as UNIT2 ON
453
        UNIT2.unit_location_type = " . LOC_FLEET . " AND
454
        UNIT2.unit_location_id = FLEET2.fleet_id
455
      " .
456
      // Lock fleet owner
457
      "LEFT JOIN {{users}} as USER2 on
458
        USER2.id = FLEET2.fleet_owner
459
      " .
460
461
      // Lock fleet heading to source planet. Only if FLEET0.fleet_mess == 1
462
      "LEFT JOIN {{fleets}} AS FLEET3 ON
463
        FLEET3.fleet_mess = 0 AND FLEET0.fleet_mess = 1 AND
464
        FLEET3.fleet_end_galaxy = FLEET0.fleet_start_galaxy AND
465
        FLEET3.fleet_end_system = FLEET0.fleet_start_system AND
466
        FLEET3.fleet_end_planet = FLEET0.fleet_start_planet
467
      " .
468
      // Блокировка всех юнитов, принадлежащих этим флотам
469
      "LEFT JOIN {{unit}} as UNIT3 ON
470
        UNIT3.unit_location_type = " . LOC_FLEET . " AND
471
        UNIT3.unit_location_id = FLEET3.fleet_id
472
      " .
473
      // Lock fleet owner
474
      "LEFT JOIN {{users}} as USER3 on USER3.id = FLEET3.fleet_owner " .
475
476
      "LEFT JOIN {{fleets}} AS FLEET4 ON
477
        FLEET4.fleet_mess = 1   AND FLEET0.fleet_mess = 1 AND
478
        FLEET4.fleet_start_galaxy = FLEET0.fleet_start_galaxy AND
479
        FLEET4.fleet_start_system = FLEET0.fleet_start_system AND
480
        FLEET4.fleet_start_planet = FLEET0.fleet_start_planet
481
      " .
482
      // Блокировка всех юнитов, принадлежащих этим флотам
483
      "LEFT JOIN {{unit}} as UNIT4 ON
484
        UNIT4.unit_location_type = " . LOC_FLEET . " AND
485
        UNIT4.unit_location_id = FLEET4.fleet_id
486
      " .
487
      // Lock fleet owner
488
      "LEFT JOIN {{users}} as USER4 on
489
        USER4.id = FLEET4.fleet_owner
490
      " .
491
492
493
      // Locking start planet
494
      "LEFT JOIN {{planets}} AS PLANETS5 ON
495
        FLEET0.fleet_mess = 1 AND
496
        PLANETS5.galaxy = FLEET0.fleet_start_galaxy AND
497
        PLANETS5.system = FLEET0.fleet_start_system AND
498
        PLANETS5.planet = FLEET0.fleet_start_planet
499
      " .
500
      // Lock planet owner
501
      "LEFT JOIN {{users}} as USER5 on
502
        USER5.id = PLANETS5.id_owner
503
      " .
504
      // Блокировка всех юнитов, принадлежащих этой планете
505
      "LEFT JOIN {{unit}} as UNIT5 ON
506
        UNIT5.unit_location_type = " . LOC_PLANET . " AND
507
        UNIT5.unit_location_id = PLANETS5.id
508
      " .
509
510
511
      // Locking destination planet
512
      "LEFT JOIN {{planets}} AS PLANETS6 ON
513
        FLEET0.fleet_mess = 0 AND
514
        PLANETS6.galaxy = FLEET0.fleet_end_galaxy AND
515
        PLANETS6.system = FLEET0.fleet_end_system AND
516
        PLANETS6.planet = FLEET0.fleet_end_planet
517
      " .
518
      // Lock planet owner
519
      "LEFT JOIN {{users}} as USER6 on
520
        USER6.id = PLANETS6.id_owner
521
      " .
522
      // Блокировка всех юнитов, принадлежащих этой планете
523
      "LEFT JOIN {{unit}} as UNIT6 ON
524
        UNIT6.unit_location_type = " . LOC_PLANET . " AND
525
        UNIT6.unit_location_id = PLANETS6.id
526
      " .
527
      "WHERE FLEET0.fleet_id = {$dbId} GROUP BY 1 FOR UPDATE"
528
    );
529
  }
530
531
532
  public function dbRowParse($db_row) {
533
    parent::dbRowParse($db_row); // TODO: Change the autogenerated stub
534
    $player = new Player();
535
    $player->dbLoad($db_row['fleet_owner']);
536
    $this->setLocatedAt($player);
537
  }
538
539
  /* FLEET HELPERS =====================================================================================================*/
540
  /**
541
   * Forcibly returns fleet before time outs
542
   */
543
  public function commandReturn() {
544
    $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;
545
546
    $this->markReturned();
547
548
    // Считаем, что флот уже долетел TODO
549
    $this->time_arrive_to_target = SN_TIME_NOW;
550
    // Убираем флот из группы
551
    $this->group_id = 0;
552
    // Отменяем работу в точке назначения
553
    $this->time_mission_job_complete = 0;
554
    // TODO - правильно вычслять время возвращения - по проделанному пути, а не по старому времени возвращения
555
    $this->time_return_to_source = $ReturnFlyingTime;
556
557
    // Записываем изменения в БД
558
    $this->dbSave();
559
560
    if($this->_group_id) {
561
      // TODO: Make here to delete only one AKS - by adding aks_fleet_count to AKS table
562
      db_fleet_aks_purge();
563
    }
564
  }
565
566
567
  /**
568
   * @return array
569
   */
570
  public function target_coordinates_without_type() {
571
    return array(
572
      'galaxy' => $this->_fleet_end_galaxy,
573
      'system' => $this->_fleet_end_system,
574
      'planet' => $this->_fleet_end_planet,
575
    );
576
  }
577
578
  /**
579
   * @return array
580
   */
581
  public function target_coordinates_typed() {
582
    return array(
583
      'galaxy' => $this->_fleet_end_galaxy,
584
      'system' => $this->_fleet_end_system,
585
      'planet' => $this->_fleet_end_planet,
586
      'type'   => $this->_fleet_end_type,
587
    );
588
  }
589
590
  /**
591
   * @return array
592
   */
593
  public function launch_coordinates_typed() {
594
    return array(
595
      'galaxy' => $this->_fleet_start_galaxy,
596
      'system' => $this->_fleet_start_system,
597
      'planet' => $this->_fleet_start_planet,
598
      'type'   => $this->_fleet_start_type,
599
    );
600
  }
601
602
603
  /**
604
   * Sets object fields for fleet return
605
   */
606
  public function markReturned() {
607
    // TODO - Проверка - а не возвращается ли уже флот?
608
    $this->is_returning = 1;
609
  }
610
611
  public function isReturning() {
612
    return 1 == $this->_is_returning;
613
  }
614
615
  public function markReturnedAndSave() {
616
    $this->markReturned();
617
    $this->dbSave();
618
  }
619
620
  /**
621
   * Parses extended unit_array which can include not only ships but resources, captains etc
622
   *
623
   * @param $unit_array
624
   */
625
  // TODO - separate shipList and unitList
626
  public function unitsSetFromArray($unit_array) {
627
    if(empty($unit_array) || !is_array($unit_array)) {
628
      return;
629
    }
630
    foreach($unit_array as $unit_id => $unit_count) {
631
      $unit_count = floatval($unit_count);
632
      if(!$unit_count) {
633
        continue;
634
      }
635
636
      if($this->isShip($unit_id)) {
637
        $this->unitList->unitSetCount($unit_id, $unit_count);
638
      } elseif($this->isResource($unit_id)) {
639
        $this->resource_list[$unit_id] = $unit_count;
640
      } else {
641
        throw new Exception('Trying to pass to fleet non-resource and non-ship ' . var_export($unit_array, true), ERR_ERROR);
642
      }
643
    }
644
  }
645
646
647
  /**
648
   * Sets fleet timers based on flight duration, time on mission (HOLD/EXPLORE) and fleet departure time.
649
   *
650
   * @param int $time_to_travel - flight duration in seconds
651
   * @param int $time_on_mission - time on mission in seconds
652
   * @param int $group_sync_delta_time - delta time to adjust fleet arrival time if fleet is a part of group (i.e. ACS)
653
   * @param int $flight_departure - fleet departure from source planet timestamp. Allows to send fleet in future or in past
654
   */
655
  public function set_times($time_to_travel, $time_on_mission = 0, $group_sync_delta_time = 0, $flight_departure = SN_TIME_NOW) {
656
    $this->_time_launch = $flight_departure;
657
658
    $this->_time_arrive_to_target = $this->_time_launch + $time_to_travel + $group_sync_delta_time;
659
    $this->_time_mission_job_complete = $time_on_mission ? $this->_time_arrive_to_target + $time_on_mission : 0;
660
    $this->_time_return_to_source = ($this->_time_mission_job_complete ? $this->_time_mission_job_complete : $this->_time_arrive_to_target) + $time_to_travel;
661
  }
662
663
664
  public function parse_missile_db_row($missile_db_row) {
665
//    $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...
666
667
    if(empty($missile_db_row) || !is_array($missile_db_row)) {
668
      return;
669
    }
670
671
//      $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...
672
//      $irak_original['fleet_start_name'] = $planet_start['name'];
673
    $this->missile_target = $missile_db_row['primaer'];
674
675
    $this->_dbId = -$missile_db_row['id'];
676
    $this->_playerOwnerId = $missile_db_row['fleet_owner'];
677
    $this->_mission_type = MT_MISSILE;
678
679
    $this->_target_owner_id = $missile_db_row['fleet_target_owner'];
680
681
    $this->_group_id = 0;
682
    $this->_is_returning = 0;
683
684
    $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...
685
    $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...
686
    $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...
687
    $this->_time_return_to_source = $missile_db_row['fleet_end_time'];
688
689
    $this->_fleet_start_planet_id = !empty($missile_db_row['fleet_start_planet_id']) ? $missile_db_row['fleet_start_planet_id'] : null;
690
    $this->_fleet_start_galaxy = $missile_db_row['fleet_start_galaxy'];
691
    $this->_fleet_start_system = $missile_db_row['fleet_start_system'];
692
    $this->_fleet_start_planet = $missile_db_row['fleet_start_planet'];
693
    $this->_fleet_start_type = $missile_db_row['fleet_start_type'];
694
695
    $this->_fleet_end_planet_id = !empty($missile_db_row['fleet_end_planet_id']) ? $missile_db_row['fleet_end_planet_id'] : null;
696
    $this->_fleet_end_galaxy = $missile_db_row['fleet_end_galaxy'];
697
    $this->_fleet_end_system = $missile_db_row['fleet_end_system'];
698
    $this->_fleet_end_planet = $missile_db_row['fleet_end_planet'];
699
    $this->_fleet_end_type = $missile_db_row['fleet_end_type'];
700
701
    $this->unitList->unitSetCount(UNIT_DEF_MISSILE_INTERPLANET, $missile_db_row['fleet_amount']);
702
  }
703
704
705
  /**
706
   * @param $from
707
   */
708
  public function set_start_planet($from) {
709
    $this->fleet_start_planet_id = intval($from['id']) ? $from['id'] : null;
710
    $this->fleet_start_galaxy = $from['galaxy'];
711
    $this->fleet_start_system = $from['system'];
712
    $this->fleet_start_planet = $from['planet'];
713
    $this->fleet_start_type = $from['planet_type'];
714
  }
715
716
  /**
717
   * @param $to
718
   */
719
  public function set_end_planet($to) {
720
    $this->target_owner_id = intval($to['id_owner']) ? $to['id_owner'] : 0;
721
    $this->fleet_end_planet_id = intval($to['id']) ? $to['id'] : null;
722
    $this->fleet_end_galaxy = $to['galaxy'];
723
    $this->fleet_end_system = $to['system'];
724
    $this->fleet_end_planet = $to['planet'];
725
    $this->fleet_end_type = $to['planet_type'];
726
  }
727
728
  /**
729
   * @param Vector $to
730
   */
731
  public function setTargetFromVectorObject($to) {
732
    $this->_fleet_end_galaxy = $to->galaxy;
733
    $this->_fleet_end_system = $to->system;
734
    $this->_fleet_end_planet = $to->planet;
735
    $this->_fleet_end_type = $to->type;
736
  }
737
738
  /**
739
   * @param array $db_row
740
   */
741
  protected function ownerExtract(array &$db_row) {
742
    $player = new Player();
743
    $player->dbLoad($db_row['fleet_owner']);
744
    $this->setLocatedAt($player);
745
  }
746
747
  /**
748
   * @param array $db_row
749
   */
750
  protected function ownerInject(array &$db_row) {
751
    $db_row['fleet_owner'] = $this->getPlayerOwnerId();
752
  }
753
754
755
756
757
  // UnitList/Ships access ***************************************************************************************************
758
759
  // TODO - перекрывать пожже - для миссайл-флотов и дефенс-флотов
760
  protected function isShip($unit_id) {
761
    return UnitShip::is_in_group($unit_id);
762
  }
763
764
  /**
765
   * Set unit count of $unit_id to $unit_count
766
   * If there is no $unit_id - it will be created and saved to DB on dbSave
767
   *
768
   * @param int $unit_id
769
   * @param int $unit_count
770
   */
771
  public function shipSetCount($unit_id, $unit_count = 0) {
772
    $this->shipAdjustCount($unit_id, $unit_count, true);
773
  }
774
775
  /**
776
   * Adjust unit count of $unit_id by $unit_count - or just replace value
777
   * If there is no $unit_id - it will be created and saved to DB on dbSave
778
   *
779
   * @param int  $unit_id
780
   * @param int  $unit_count
781
   * @param bool $replace_value
782
   */
783
  public function shipAdjustCount($unit_id, $unit_count = 0, $replace_value = false) {
784
    $this->unitList->unitAdjustCount($unit_id, $unit_count, $replace_value);
785
  }
786
787
  public function shipGetCount($unit_id) {
788
    return $this->unitList->unitGetCount($unit_id);
789
  }
790
791
  public function shipsCountApplyLossMultiplier($ships_lost_multiplier) {
792
    $this->unitList->unitsCountApplyLossMultiplier($ships_lost_multiplier);
793
  }
794
795
  /**
796
   * Returns ship list in fleet
797
   */
798
  public function shipsGetArray() {
799
    return $this->unitList->unitsGetArray();
800
  }
801
802
  public function shipsGetTotal() {
803
    return $this->unitList->unitsCount();
804
  }
805
806
  public function shipsGetCapacity() {
807
    return $this->unitList->shipsCapacity();
808
  }
809
810
  public function shipsGetHoldFree() {
811
    return max(0, $this->shipsGetCapacity() - $this->resourcesGetTotal());
812
  }
813
814
  public function shipsGetTotalById($ship_id) {
815
    return $this->unitList->unitsCountById($ship_id);
816
  }
817
818
  /**
819
   * Возвращает ёмкость переработчиков во флоте
820
   *
821
   * @param array $recycler_info
822
   *
823
   * @return int
824
   *
825
   * @version 41a6.79
826
   */
827
  public function shipsGetCapacityRecyclers(array $recycler_info) {
828
    $recyclers_incoming_capacity = 0;
829
    $fleet_data = $this->shipsGetArray();
830
    foreach($recycler_info as $recycler_id => $recycler_data) {
831
      $recyclers_incoming_capacity += $fleet_data[$recycler_id] * $recycler_data['capacity'];
832
    }
833
834
    return $recyclers_incoming_capacity;
835
  }
836
837
  /**
838
   * Restores fleet or resources to planet
839
   *
840
   * @param bool $start
841
   * @param int  $result
842
   *
843
   * @return int
844
   */
845
  // TODO - split to functions
846
  public function shipsLand($start = true, &$result = CACHE_NOTHING) {
847
    sn_db_transaction_check(true);
848
849
    // Если флот уже обработан - не существует или возращается - тогда ничего не делаем
850
    if($this->isEmpty()) {
851
      return $result;
852
    }
853
854
    $coordinates = $start ? $this->launch_coordinates_typed() : $this->target_coordinates_typed();
855
856
    // Поскольку эта функция может быть вызвана не из обработчика флотов - нам надо всё заблокировать вроде бы НЕ МОЖЕТ!!!
857
    // TODO Проверить от многократного срабатывания !!!
858
    // Тут не блокируем пока - сначала надо заблокировать пользователя, что бы не было дедлока
859
    // TODO поменять на владельца планеты - когда его будут возвращать всегда !!!
860
861
    // Узнаем ИД владельца планеты.
862
    // С блокировкой, поскольку эта функция может быть вызвана только из менеджера летящих флотов.
863
    // А там уже всё заблокировано как надо и повторная блокировка не вызовет дедлок.
864
    $planet_arrival = db_planet_by_vector($coordinates, '', true);
865
    // Блокируем пользователя
866
    // TODO - вообще-то нам уже известен пользователь в МЛФ - так что можно просто передать его сюда
867
    $user = db_user_by_id($planet_arrival['id_owner'], true);
868
869
    // TODO - Проверка, что планета всё еще существует на указанных координатах, а не телепортировалась, не удалена хозяином, не уничтожена врагом
870
    // Флот, который возвращается на захваченную планету, пропадает
871
    // Ship landing is possible only to fleet owner's planet
872
    if($this->getPlayerOwnerId() == $planet_arrival['id_owner']) {
873
      $db_changeset = array();
874
875
      $fleet_array = $this->shipsGetArray();
876
      foreach($fleet_array as $ship_id => $ship_count) {
877
        if($ship_count) {
878
          $db_changeset['unit'][] = sn_db_unit_changeset_prepare($ship_id, $ship_count, $user, $planet_arrival['id']);
879
        }
880
      }
881
882
      // Adjusting ship amount on planet
883
      if(!empty($db_changeset)) {
884
        db_changeset_apply($db_changeset);
885
      }
886
887
      // Restoring resources to planet
888
      $this->resourcesUnload($start, $result);
889
    }
890
891
    $result = CACHE_FLEET | ($start ? CACHE_PLANET_SRC : CACHE_PLANET_DST);
892
893
    $result = RestoreFleetToPlanet($this, $start, $result);
894
895
    $this->dbDelete();
896
897
    return $result;
898
  }
899
900
901
  // Resources access ***************************************************************************************************
902
903
  /**
904
   * Extracts resources value from db_row
905
   *
906
   * @param array $db_row
907
   *
908
   * @internal param Fleet $that
909
   * @version 41a6.79
910
   */
911
  protected function resourcesExtract(array &$db_row) {
912
    $this->resource_list = array(
913
      RES_METAL     => !empty($db_row['fleet_resource_metal']) ? floor($db_row['fleet_resource_metal']) : 0,
914
      RES_CRYSTAL   => !empty($db_row['fleet_resource_crystal']) ? floor($db_row['fleet_resource_crystal']) : 0,
915
      RES_DEUTERIUM => !empty($db_row['fleet_resource_deuterium']) ? floor($db_row['fleet_resource_deuterium']) : 0,
916
    );
917
  }
918
919
  protected function resourcesInject(array &$db_row) {
920
    $db_row['fleet_resource_metal'] = $this->resource_list[RES_METAL];
921
    $db_row['fleet_resource_crystal'] = $this->resource_list[RES_CRYSTAL];
922
    $db_row['fleet_resource_deuterium'] = $this->resource_list[RES_DEUTERIUM];
923
  }
924
925
  /**
926
   * Set current resource list from array of units
927
   *
928
   * @param array $resource_list
929
   */
930
  public function resourcesSet($resource_list) {
931
    if(!empty($this->propertiesAdjusted['resource_list'])) {
932
      throw new PropertyAccessException('Property "resource_list" already was adjusted so no SET is possible until dbSave in ' . get_called_class() . '::unitSetResourceList', ERR_ERROR);
933
    }
934
    $this->resourcesAdjust($resource_list, true);
935
  }
936
937
  /**
938
   * Updates fleet resource list with deltas
939
   *
940
   * @param $resource_delta_list
941
   */
942
  public function resourcesAdjust($resource_delta_list, $replace_value = false) {
943
    !is_array($resource_delta_list) ? $resource_delta_list = array() : false;
944
945
    foreach($resource_delta_list as $resource_id => $unit_delta) {
946
      if(!UnitResourceLoot::is_in_group($resource_id) || !($unit_delta = floor($unit_delta))) {
947
        // Not a resource or no resources - continuing
948
        continue;
949
      }
950
951
      if($replace_value) {
952
        $this->resource_list[$resource_id] = $unit_delta;
953
      } else {
954
        $this->resource_list[$resource_id] += $unit_delta;
955
        // Preparing changes
956
        $this->resource_delta[$resource_id] += $unit_delta;
957
        $this->propertiesAdjusted['resource_list'] = 1;
958
      }
959
960
      // Check for negative unit value
961
      if($this->resource_list[$resource_id] < 0) {
962
        // TODO
963
        throw new Exception('Resource ' . $resource_id . ' will become negative in ' . get_called_class() . '::unitAdjustResourceList', ERR_ERROR);
964
      }
965
    }
966
  }
967
968
  public function resourcesGetTotal() {
969
    return empty($this->resource_list) || !is_array($this->resource_list) ? 0 : array_sum($this->resource_list);
970
  }
971
972
  /**
973
   * @param array $rate
974
   *
975
   * @return float
976
   */
977
  public function resourcesGetTotalInMetal(array $rate) {
978
    return
979
      $this->resource_list[RES_METAL] * $rate[RES_METAL]
980
      + $this->resource_list[RES_CRYSTAL] * $rate[RES_CRYSTAL] / $rate[RES_METAL]
981
      + $this->resource_list[RES_DEUTERIUM] * $rate[RES_DEUTERIUM] / $rate[RES_METAL];
982
  }
983
984
  /**
985
   * Returns resource list in fleet
986
   */
987
  // TODO
988
  public function resourcesGetList() {
989
    return $this->resource_list;
990
  }
991
992
  public function resourcesReset() {
993
    $this->resourcesSet(array(
994
      RES_METAL     => 0,
995
      RES_CRYSTAL   => 0,
996
      RES_DEUTERIUM => 0,
997
    ));
998
  }
999
1000
  /**
1001
   * Restores fleet or resources to planet
1002
   *
1003
   * @param bool $start
1004
   * @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...
1005
   * @param int  $result
1006
   *
1007
   * @return int
1008
   */
1009
  public function resourcesUnload($start = true, &$result = CACHE_NOTHING) {
1010
    sn_db_transaction_check(true);
1011
1012
    // Если флот уже обработан - не существует или возращается - тогда ничего не делаем
1013
    if(!$this->resourcesGetTotal()) {
1014
      return $result;
1015
    }
1016
1017
    $coordinates = $start ? $this->launch_coordinates_typed() : $this->target_coordinates_typed();
1018
1019
    // Поскольку эта функция может быть вызвана не из обработчика флотов - нам надо всё заблокировать вроде бы НЕ МОЖЕТ!!!
1020
    // TODO Проверить от многократного срабатывания !!!
1021
    // Тут не блокируем пока - сначала надо заблокировать пользователя, что бы не было дедлока
1022
    // TODO поменять на владельца планеты - когда его будут возвращать всегда !!!
1023
1024
1025
    // Узнаем ИД владельца планеты.
1026
    // С блокировкой, поскольку эта функция может быть вызвана только из менеджера летящих флотов.
1027
    // А там уже всё заблокировано как надо и повторная блокировка не вызовет дедлок.
1028
    $planet_arrival = db_planet_by_vector($coordinates, '', true);
1029
1030
    // TODO - Проверка, что планета всё еще существует на указанных координатах, а не телепортировалась, не удалена хозяином, не уничтожена врагом
1031
1032
    // Restoring resources to planet
1033
    if($this->resourcesGetTotal()) {
1034
      $fleet_resources = $this->resourcesGetList();
1035
      db_planet_set_by_id($planet_arrival['id'],
1036
        "`metal` = `metal` + '{$fleet_resources[RES_METAL]}', `crystal` = `crystal` + '{$fleet_resources[RES_CRYSTAL]}', `deuterium` = `deuterium` + '{$fleet_resources[RES_DEUTERIUM]}'");
1037
    }
1038
1039
    $this->resourcesReset();
1040
    $this->markReturned();
1041
1042
    $result = CACHE_FLEET | ($start ? CACHE_PLANET_SRC : CACHE_PLANET_DST);
1043
1044
    return $result;
1045
  }
1046
1047
1048
  protected function isResource($unit_id) {
1049
    return UnitResourceLoot::is_in_group($unit_id);
1050
  }
1051
1052
  /**
1053
   * @param int $speed_percent
1054
   *
1055
   * @return array
1056
   */
1057
  protected function flt_travel_data($speed_percent = 10) {
1058
    $distance = $this->targetVector->distanceFromCoordinates($this->dbSourcePlanetRow);
1059
1060
    return $this->unitList->travelData($speed_percent, $distance, $this->dbOwnerRow);
1061
  }
1062
1063
1064
  /**
1065
   * @param array  $dbPlayerRow
1066
   * @param array  $dbPlanetRow
1067
   * @param Vector $targetVector
1068
   *
1069
   */
1070
  public function initDefaults($dbPlayerRow, $dbPlanetRow, $targetVector, $mission, $ships, $fleet_group_mr, $oldSpeedInTens) {
1071
    $objFleet5Player = new Player();
1072
    $objFleet5Player->dbRowParse($dbPlayerRow);
1073
    $this->setLocatedAt($objFleet5Player);
1074
1075
    $this->mission_type = $mission;
1076
1077
    $this->dbOwnerRow = $dbPlayerRow;
1078
1079
    $this->set_start_planet($dbPlanetRow);
1080
    $this->dbSourcePlanetRow = $dbPlanetRow;
1081
1082
    $this->setTargetFromVectorObject($targetVector);
1083
    $this->targetVector = $targetVector;
1084
1085
    $this->populateTargetPlanet();
1086
1087
    $this->unitsSetFromArray($ships);
1088
1089
    $this->_group_id = $fleet_group_mr;
1090
1091
    $this->oldSpeedInTens = $oldSpeedInTens;
1092
1093
    $this->fleetPage0Prepare();
1094
1095
  }
1096
1097
  protected function populateTargetPlanet() {
1098
    $targetPlanetCoords = $this->targetVector;
1099
    if($this->mission_type != MT_NONE) {
1100
      $this->restrictTargetTypeByMission();
1101
1102
      // TODO - Нельзя тут просто менять тип планеты или координат!
1103
      // If current planet type is not allowed on mission - switch planet type
1104
      if(empty($this->allowed_planet_types[$this->targetVector->type])) {
1105
        $targetPlanetCoords->type = reset($this->allowed_planet_types);
1106
      }
1107
    }
1108
1109
    $this->dbTargetRow = db_planet_by_vector_object($targetPlanetCoords);
1110
  }
1111
1112
  protected function restrictTargetTypeByMission() {
1113
    if($this->_mission_type == MT_MISSILE) {
1114
      $this->allowed_planet_types = array(PT_PLANET => PT_PLANET);
1115
    } elseif($this->_mission_type == MT_COLONIZE || $this->_mission_type == MT_EXPLORE) {
1116
      // TODO - PT_NONE
1117
      $this->allowed_planet_types = array(PT_PLANET => PT_PLANET);
1118
    } elseif($this->_mission_type == MT_RECYCLE) {
1119
      $this->allowed_planet_types = array(PT_DEBRIS => PT_DEBRIS);
1120
    } elseif($this->_mission_type == MT_DESTROY) {
1121
      $this->allowed_planet_types = array(PT_MOON => PT_MOON);
1122
    } else {
1123
      $this->allowed_planet_types = array(PT_PLANET => PT_PLANET, PT_MOON => PT_MOON);
1124
    }
1125
  }
1126
1127
  /**
1128
   */
1129
  public function fleetPage0Prepare() {
1130
    global $template_result;
1131
    $template_result += array(
1132
      'thisgalaxy'      => $this->dbSourcePlanetRow['galaxy'],
1133
      'thissystem'      => $this->dbSourcePlanetRow['system'],
1134
      'thisplanet'      => $this->dbSourcePlanetRow['planet'],
1135
      'thisplanet_type' => $this->dbSourcePlanetRow['planet_type'],
1136
1137
      'galaxy'         => $this->targetVector->galaxy,
1138
      'system'         => $this->targetVector->system,
1139
      'planet'         => $this->targetVector->planet,
1140
      'planet_type'    => $this->targetVector->type,
1141
      'target_mission' => $this->_mission_type,
1142
      'MISSION_NAME'   => $this->_mission_type ? classLocale::$lang['type_mission'][$this->_mission_type] : '',
1143
1144
      'MT_COLONIZE' => MT_COLONIZE,
1145
    );
1146
1147
//    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...
1148
  }
1149
1150
1151
  public function restrictToKnownSpace() {
1152
    if(!$this->targetVector->isInKnownSpace()) {
1153
      throw new Exception('FLIGHT_VECTOR_BEYOND_SYSTEM', FLIGHT_VECTOR_BEYOND_SYSTEM);
1154
    }
1155
  }
1156
1157
  public function restrictToTypePlanet($errorCode) {
1158
    if($this->targetVector->type != PT_PLANET) {
1159
      throw new Exception($errorCode, $errorCode);
1160
    }
1161
  }
1162
1163
  public function restrictToNoMissiles() {
1164
    $missilesAttack = $this->unitList->unitsCountById(UNIT_DEF_MISSILE_INTERPLANET);
1165
    $missilesDefense = $this->unitList->unitsCountById(UNIT_DEF_MISSILE_INTERCEPTOR);
1166
    if($missilesAttack > 0 || $missilesDefense > 0) {
1167
      throw new Exception('FLIGHT_SHIPS_NO_MISSILES', FLIGHT_SHIPS_NO_MISSILES);
1168
    }
1169
  }
1170
1171
  public function restrictToTargetOwn() {
1172
    if($this->dbTargetRow['id'] != $this->getPlayerOwnerId()) {
1173
      throw new Exception('FLIGHT_VECTOR_ONLY_OWN', FLIGHT_VECTOR_ONLY_OWN);
1174
    }
1175
  }
1176
1177
  public function restrictToTargetOther() {
1178
    if($this->dbTargetRow['id'] == $this->getPlayerOwnerId()) {
1179
      throw new Exception('FLIGHT_VECTOR_ONLY_OTHER', FLIGHT_VECTOR_ONLY_OTHER);
1180
    }
1181
  }
1182
1183
  public function restrictToNotOnlySpies() {
1184
    if($this->unitList->unitsCountById(SHIP_SPY) == $this->shipsGetTotal()) {
1185
      throw new Exception('FLIGHT_SHIPS_NOT_ONLY_SPIES', FLIGHT_SHIPS_NOT_ONLY_SPIES);
1186
    }
1187
  }
1188
1189
  protected function restrictToUniverse() {
1190
    if(!$this->targetVector->isInUniverse()) {
1191
      throw new Exception('FLIGHT_VECTOR_BEYOND_UNIVERSE', FLIGHT_VECTOR_BEYOND_UNIVERSE);
1192
    }
1193
  }
1194
1195
  protected function restrictToMovable() {
1196
    if(!$this->unitList->unitsIsAllMovable($this->dbOwnerRow)) {
1197
      throw new Exception('FLIGHT_SHIPS_UNMOVABLE', FLIGHT_SHIPS_UNMOVABLE);
1198
    }
1199
  }
1200
1201
  protected function restrictToFleetUnits() {
1202
    if(!$this->unitList->unitsInGroup(sn_get_groups(array('fleet', 'missile')))) {
1203
      throw new Exception('FLIGHT_SHIPS_UNIT_WRONG', FLIGHT_SHIPS_UNIT_WRONG);
1204
    }
1205
  }
1206
1207
  protected function restrictToColonizer() {
1208
    // Colonization fleet should have at least one colonizer
1209
    if(!$this->unitList->unitsCountById(SHIP_COLONIZER) <= 0) {
1210
      throw new Exception('FLIGHT_SHIPS_NO_COLONIZER', FLIGHT_SHIPS_NO_COLONIZER);
1211
    }
1212
  }
1213
1214
  protected function restrictToTargetExists() {
1215
    if(empty($this->dbTargetRow) || empty($this->dbTargetRow['id'])) {
1216
      throw new Exception('FLIGHT_VECTOR_NO_TARGET', FLIGHT_VECTOR_NO_TARGET);
1217
    }
1218
  }
1219
1220
1221 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...
1222
    // Is it exploration - fleet sent beyond of system?
1223
    if($this->targetVector->isInKnownSpace()) {
1224
      // No exploration beyond this point
1225
      unset($this->allowed_missions[MT_EXPLORE]);
1226
1227
      $this->restrictToKnownSpace();
1228
1229
      return;
1230
    }
1231
    $this->restrictToNotOnlySpies();
1232
    $this->restrictToNoMissiles();
1233
1234
    $this->allowed_missions = array(MT_EXPLORE => MT_EXPLORE,);
1235
1236
    throw new Exception('FLIGHT_ALLOWED', FLIGHT_ALLOWED);
1237
  }
1238
1239 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...
1240
    // Is it colonization - fleet sent to empty place?
1241
    if(!empty($this->dbTargetRow)) {
1242
      // No colonization beyond this point
1243
      unset($this->allowed_missions[MT_COLONIZE]);
1244
1245
      $this->restrictToTargetExists();
1246
1247
      return;
1248
    }
1249
    // Only planet can be destination for colonization
1250
    $this->restrictToTypePlanet(FLIGHT_MISSION_COLONIZE_NOT_PLANET);
1251
    $this->restrictToColonizer();
1252
    $this->restrictToNoMissiles();
1253
1254
    $this->allowed_missions = array(MT_COLONIZE => MT_COLONIZE,);
1255
1256
    throw new Exception('FLIGHT_ALLOWED', FLIGHT_ALLOWED);
1257
  }
1258
1259
  protected function restrictNotDebrisOrMissionRecycle() {
1260
    if($this->targetVector->type != PT_DEBRIS) {
1261
      // No recycling beyond this point
1262
      unset($this->allowed_missions[MT_RECYCLE]);
1263
1264
      return;
1265
    }
1266
1267
    $this->restrictToNoMissiles();
1268
1269
    // restrict to recyclers
1270
    $recyclers = 0;
1271
    foreach(sn_get_groups('flt_recyclers') as $recycler_id) {
1272
      $recyclers += $this->unitList->unitsCountById($recycler_id);
1273
    }
1274
1275
    if($recyclers <= 0) {
1276
      throw new Exception('FLIGHT_SHIPS_NO_RECYCLERS', FLIGHT_SHIPS_NO_RECYCLERS);
1277
    }
1278
1279
    $this->allowed_missions = array(MT_RECYCLE => MT_RECYCLE,);
1280
1281
    throw new Exception('FLIGHT_ALLOWED', FLIGHT_ALLOWED);
1282
  }
1283
1284
  protected function restrictMissionMissile() {
1285
    $missilesAttack = $this->unitList->unitsCountById(UNIT_DEF_MISSILE_INTERPLANET);
1286
    if($missilesAttack <= 0) {
1287
      // No missile attack beyond this point
1288
      unset($this->allowed_missions[MT_MISSILE]);
1289
1290
      return;
1291
    }
1292
1293
    if($missilesAttack != $this->shipsGetTotal()) {
1294
      throw new Exception('FLIGHT_SHIPS_ONLY_MISSILES', FLIGHT_SHIPS_ONLY_MISSILES);
1295
    }
1296
1297
    $this->restrictToTypePlanet(FLIGHT_MISSION_MISSILE_ONLY_PLANET);
1298
    $this->restrictToTargetOther();
1299
1300
    $this->allowed_missions = array(MT_MISSILE => MT_MISSILE,);
1301
    throw new Exception('FLIGHT_ALLOWED', FLIGHT_ALLOWED);
1302
  }
1303
1304 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...
1305
    if($this->unitList->unitsCountById(SHIP_SPY) != $this->shipsGetTotal()) {
1306
//      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...
1307
      unset($this->allowed_missions[MT_SPY]);
1308
1309
      $this->restrictToNotOnlySpies();
1310
1311
      return;
1312
    }
1313
1314
    $this->allowed_missions = array(MT_SPY => MT_SPY,);
1315
    throw new Exception('FLIGHT_ALLOWED', FLIGHT_ALLOWED);
1316
  }
1317
1318
  protected function restrictMissionDestroy() {
1319
    // If target vector is not Moon - then it can't be Destroy mission
1320
    // If no Reapers (i.e. Death Star) in fleet - then mission Moon Destroy is unaccessible
1321
    if($this->targetVector->type != PT_MOON || $this->unitList->unitsCountById(SHIP_HUGE_DEATH_STAR) <= 0) {
1322
      unset($this->allowed_missions[MT_DESTROY]);
1323
    }
1324
  }
1325
1326
  protected function restrictMissionACS() {
1327
    // If no ACS group is shown - then it can't be an ACS attack
1328
    if(empty($this->_group_id)) {
1329
      unset($this->allowed_missions[MT_ACS]);
1330
    }
1331
  }
1332
1333
  /** @throws Exception */
1334
  protected function restrictFriendOrFoe() {
1335
    // Checking target owner
1336 View Code Duplication
    if($this->dbTargetRow['id'] == $this->getPlayerOwnerId()) {
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...
1337
      // Spying can't be done on owner's planet/moon
1338
      unset($this->allowed_missions[MT_SPY]);
1339
      // Attack can't be done on owner's planet/moon
1340
      unset($this->allowed_missions[MT_ATTACK]);
1341
      // ACS can't be done on owner's planet/moon
1342
      unset($this->allowed_missions[MT_ACS]);
1343
      // Destroy can't be done on owner's moon
1344
      unset($this->allowed_missions[MT_DESTROY]);
1345
1346
      $this->restrictToNoMissiles();
1347
1348
      // MT_RELOCATE
1349
      // No checks
1350
      // TODO - check captain
1351
1352
      // MT_HOLD
1353
      // TODO - Check for Allies Deposit for HOLD
1354
1355
      // MT_TRANSPORT
1356
1357
    } else {
1358
      // Relocate can be done only on owner's planet/moon
1359
      unset($this->allowed_missions[MT_RELOCATE]);
1360
1361
      // TODO - check for moratorium
1362
1363
      // MT_HOLD
1364
      // TODO - Check for Allies Deposit for HOLD
1365
      // TODO - Noob protection for HOLD depends on server settings
1366
1367
      // MT_SPY
1368
      $this->restrictToNotOnlySpiesOrMissionSpy();
1369
1370
      // TODO - check noob protection
1371
1372
      // TODO - check bashing
1373
1374
      // No missions except MT_MISSILE should have any missiles in fleet
1375
      $this->restrictMissionMissile();
1376
      $this->restrictToNoMissiles();
1377
      // Beyond this point no mission can have a missile in fleet
1378
1379
      // MT_DESTROY
1380
      $this->restrictMissionDestroy();
1381
1382
      // MT_ACS
1383
      $this->restrictMissionACS();
1384
1385
      // MT_ATTACK - no checks
1386
1387
      // MT_TRANSPORT - no checks
1388
    }
1389
  }
1390
1391
  protected function restrictToNotSource() {
1392
    if($this->targetVector->isEqualToPlanet($this->dbSourcePlanetRow)) {
1393
      throw new Exception('FLIGHT_VECTOR_SAME_SOURCE', FLIGHT_VECTOR_SAME_SOURCE);
1394
    }
1395
  }
1396
1397
  protected function restrictToNonVacationSender() {
1398
    if(!empty($this->dbOwnerRow['vacation']) && $this->dbOwnerRow['vacation'] >= SN_TIME_NOW) {
1399
      throw new Exception('FLIGHT_PLAYER_VACATION_OWN', FLIGHT_PLAYER_VACATION_OWN);
1400
    }
1401
  }
1402
1403
  protected function restrictToValidSpeedPercentOld() {
1404
    if(!$this->unitList->shipsIsEnoughOnPlanet($this->dbSourcePlanetRow)) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

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

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

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

could be turned into

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

This is much more concise to read.

Loading history...
1405
    }
1406
1407
    $speed_possible = array(10, 9, 8, 7, 6, 5, 4, 3, 2, 1);
1408
    if(!in_array($this->oldSpeedInTens, $speed_possible)) {
1409
      throw new Exception('FLIGHT_FLEET_SPEED_WRONG', FLIGHT_FLEET_SPEED_WRONG);
1410
    }
1411
1412
  }
1413
1414
  protected function restrict2ToAllowedMissions() {
1415
    if(empty($this->allowed_missions[$this->_mission_type])) {
1416
      throw new Exception('FLIGHT_MISSION_IMPOSSIBLE', FLIGHT_MISSION_IMPOSSIBLE);
1417
    }
1418
  }
1419
1420
  protected function restrict2ToAllowedPlanetTypes() {
1421
    if(empty($this->allowed_planet_types[$this->targetVector->type])) {
1422
      throw new Exception('FLIGHT_MISSION_IMPOSSIBLE', FLIGHT_MISSION_IMPOSSIBLE);
1423
    }
1424
  }
1425
1426
  protected function restrict2ToMaxFleets() {
1427
    if(FleetList::fleet_count_flying($this->getPlayerOwnerId()) >= GetMaxFleets($this->dbOwnerRow)) {
1428
      throw new Exception('FLIGHT_FLEET_NO_SLOTS', FLIGHT_FLEET_NO_SLOTS);
1429
    }
1430
  }
1431
1432
  protected function restrict2ToEnoughShips() {
1433
    if(!$this->unitList->shipsIsEnoughOnPlanet($this->dbSourcePlanetRow)) {
1434
      throw new Exception('FLIGHT_SHIPS_NOT_ENOUGH', FLIGHT_SHIPS_NOT_ENOUGH);
1435
    }
1436
  }
1437
1438
  protected function restrict2ToEnoughCapacity($fleetCapacity, $fleetConsumption, $fleetResources) {
1439
    if(floor($fleetCapacity) < ceil(array_sum($fleetResources) + $fleetConsumption)) {
1440
      throw new Exception('FLIGHT_FLEET_OVERLOAD', FLIGHT_FLEET_OVERLOAD);
1441
    }
1442
  }
1443
1444
  protected function restrict2ByResources($fleetConsumption, $fleetResources) {
1445
    $fleetResources[RES_DEUTERIUM] = ceil($fleetResources[RES_DEUTERIUM] + $fleetConsumption);
1446
    foreach($fleetResources as $resourceId => $resourceAmount) {
1447
      if($fleetResources[$resourceId] < 0) {
1448
        throw new Exception('FLIGHT_RESOURCES_NEGATIVE', FLIGHT_RESOURCES_NEGATIVE);
1449
      }
1450
1451
      if(mrc_get_level($this->dbOwnerRow, $this->dbSourcePlanetRow, $resourceId) < ceil($fleetResources[$resourceId])) {
1452
        if($resourceId == RES_DEUTERIUM) {
1453
          throw new Exception('FLIGHT_RESOURCES_FUEL_NOT_ENOUGH', FLIGHT_RESOURCES_FUEL_NOT_ENOUGH);
1454
        } else {
1455
          throw new Exception('FLIGHT_RESOURCES_NOT_ENOUGH', FLIGHT_RESOURCES_NOT_ENOUGH);
1456
        }
1457
      }
1458
    }
1459
  }
1460
1461
  /**
1462
   * Restricts mission availability internally w/o DB access
1463
   *
1464
   * @throws Exception
1465
   */
1466
  public function restrictMission() {
1467
    // Only "cheap" checks that didn't require to query DB
1468
1469
1470
    // Check for valid percent speed value
1471
    $this->restrictToValidSpeedPercentOld();
1472
1473
    // Player in Vacation can't send fleets
1474
    $this->restrictToNonVacationSender();
1475
1476
    // Fleet source and destination can't be the same
1477
    $this->restrictToNotSource();
1478
1479
    // No mission could fly beyond Universe - i.e. with wrong Galaxy and/or System coordinates
1480
    $this->restrictToUniverse();
1481
1482
    // Only ships and missiles can be sent to mission
1483
    $this->restrictToFleetUnits();
1484
    // Only units with main engines (speed >=0) can fly - no other units like satellites
1485
    $this->restrictToMovable();
1486
1487
    // No missions except MT_EXPLORE could target coordinates beyond known system
1488
    $this->restrictKnownSpaceOrMissionExplore();
1489
    // Beyond this point all mission address only known space
1490
1491
    // No missions except MT_COLONIZE could target empty coordinates
1492
    $this->restrictTargetExistsOrMissionColonize();
1493
    // Beyond this point all mission address only existing planets/moons
1494
1495
    // No missions except MT_RECYCLE could target debris
1496
    $this->restrictNotDebrisOrMissionRecycle();
1497
    // Beyond this point targets can be only PT_PLANET or PT_MOON
1498
1499
    // TODO - later then
1500
    $this->restrictFriendOrFoe();
1501
  }
1502
1503
1504
  protected function printErrorIfNoShips() {
1505
    if($this->unitList->unitsCount() <= 0) {
1506
      message(classLocale::$lang['fl_err_no_ships'], classLocale::$lang['fl_error'], 'fleet' . DOT_PHP_EX, 5);
1507
    }
1508
  }
1509
1510
  /**
1511
   * @param array $template_result
1512
   *
1513
   * @throws Exception
1514
   */
1515
  protected function renderFleet(&$template_result) {
1516
    $this->printErrorIfNoShips();
1517
1518
    $tplShips = $this->unitList->unitsRender();
1519
    $template_result['.']['fleets'][] = array(
1520
      'START_TYPE_TEXT_SH' => classLocale::$lang['sys_planet_type_sh'][$this->dbSourcePlanetRow['planet_type']],
1521
      'START_COORDS'       => uni_render_coordinates($this->dbSourcePlanetRow),
1522
      'START_NAME'         => $this->dbSourcePlanetRow['name'],
1523
      'END_TYPE_TEXT_SH'   =>
1524
        !empty($this->targetVector->type)
1525
          ? classLocale::$lang['sys_planet_type_sh'][$this->targetVector->type]
1526
          : '',
1527
      'END_COORDS'         => uniRenderVector($this->targetVector),
1528
      'END_NAME'           => !empty($this->dbTargetRow['name']) ? $this->dbTargetRow['name'] : '',
1529
      '.'                  => array(
1530
        'ships' => $tplShips,
1531
      ),
1532
    );
1533
  }
1534
1535
  /**
1536
   * @param array $template_result
1537
   *
1538
   * @return array
1539
   */
1540
  protected function renderAllowedMissions(&$template_result) {
1541
    ksort($this->allowed_missions);
1542
    // If mission is not set - setting first mission from allowed
1543
    if(empty($this->_mission_type) && is_array($this->allowed_missions)) {
1544
      $this->_mission_type = reset($this->allowed_missions);
1545
    }
1546
    foreach($this->allowed_missions as $key => $value) {
1547
      $template_result['.']['missions'][] = array(
1548
        'ID'   => $key,
1549
        'NAME' => classLocale::$lang['type_mission'][$key],
1550
      );
1551
    };
1552
  }
1553
1554
  /**
1555
   * @param $template_result
1556
   */
1557
  protected function renderDuration(&$template_result, $max_duration) {
1558
    if($max_duration) {
1559
      $config_game_speed_expedition = ($this->_mission_type == MT_EXPLORE && classSupernova::$config->game_speed_expedition ? classSupernova::$config->game_speed_expedition : 1);
1560
      for($i = 1; $i <= $max_duration; $i++) {
1561
        $template_result['.']['duration'][] = array(
1562
          'ID'   => $i,
1563
          'TIME' => pretty_time(ceil($i * 3600 / $config_game_speed_expedition)),
1564
        );
1565
      }
1566
    }
1567
  }
1568
1569
  /**
1570
   * @param array $planetResources
1571
   * @param array &$template_result
1572
   */
1573
  protected function renderPlanetResources(&$planetResources, &$template_result) {
1574
    // TODO - REDO to resource_id
1575
    $i = 0;
1576
    foreach($planetResources as $resource_id => $resource_amount) {
1577
      $template_result['.']['resources'][] = array(
1578
        'ID'        => $i++, // $resource_id,
1579
        'ON_PLANET' => $resource_amount,
1580
        'TEXT'      => pretty_number($resource_amount),
1581
        'NAME'      => classLocale::$lang['tech'][$resource_id],
1582
      );
1583
    }
1584
  }
1585
1586
  /**
1587
   * @param $template_result
1588
   */
1589
  protected function renderAllowedPlanetTypes(&$template_result) {
1590
    foreach($this->allowed_planet_types as $possible_planet_type_id) {
1591
      $template_result['.']['possible_planet_type_id'][] = array(
1592
        'ID'         => $possible_planet_type_id,
1593
        'NAME'       => classLocale::$lang['sys_planet_type'][$possible_planet_type_id],
1594
        'NAME_SHORT' => classLocale::$lang['sys_planet_type_sh'][$possible_planet_type_id],
1595
      );
1596
    }
1597
  }
1598
1599
  protected function renderFleet1TargetSelect(&$shortcut) {
1600
    global $note_priority_classes;
1601
1602
    $name = !empty($shortcut['title']) ? $shortcut['title'] : $shortcut['name'];
1603
1604
    $result = array(
1605
      'NAME'       => $name,
1606
      'GALAXY'     => $shortcut['galaxy'],
1607
      'SYSTEM'     => $shortcut['system'],
1608
      'PLANET'     => $shortcut['planet'],
1609
      'TYPE'       => $shortcut['planet_type'],
1610
      'TYPE_PRINT' => classLocale::$lang['fl_shrtcup'][$shortcut['planet_type']],
1611
    );
1612
1613
    if(isset($shortcut['priority'])) {
1614
      $result += array(
1615
        'PRIORITY'       => $shortcut['priority'],
1616
        'PRIORITY_CLASS' => $note_priority_classes[$shortcut['priority']],
1617
      );
1618
    }
1619
1620
    if(isset($shortcut['id'])) {
1621
      $result += array(
1622
        'ID' => $shortcut['id'],
1623
      );
1624
    }
1625
1626
    return $result;
1627
  }
1628
1629
  /**
1630
   * @param $template_result
1631
   */
1632
  protected function renderFleetShortcuts(&$template_result) {
1633
    // Building list of shortcuts
1634
    $query = db_note_list_select_by_owner_and_planet($this->dbOwnerRow);
1635
    while($row = db_fetch($query)) {
1636
      $template_result['.']['shortcut'][] = $this->renderFleet1TargetSelect($row);
1637
    }
1638
  }
1639
1640
  /**
1641
   * Building list of own planets & moons
1642
   *
1643
   * @param $template_result
1644
   */
1645
  protected function renderOwnPlanets(&$template_result) {
1646
    $colonies = db_planet_list_sorted($this->dbOwnerRow);
1647
    if(count($colonies) <= 1) {
1648
      return;
1649
    }
1650
1651
    foreach($colonies as $row) {
1652
      if($row['id'] == $this->dbSourcePlanetRow['id']) {
1653
        continue;
1654
      }
1655
1656
      $template_result['.']['colonies'][] = $this->renderFleet1TargetSelect($row);
1657
    }
1658
  }
1659
1660
  /**
1661
   * @param $template_result
1662
   */
1663
  protected function renderACSList(&$template_result) {
1664
    $query = db_acs_get_list();
1665
    while($row = db_fetch($query)) {
1666
      $members = explode(',', $row['eingeladen']);
1667
      foreach($members as $a => $b) {
1668
        if($b == $this->dbOwnerRow['id']) {
1669
          $template_result['.']['acss'][] = $this->renderFleet1TargetSelect($row);
1670
        }
1671
      }
1672
    }
1673
  }
1674
1675
  /**
1676
   * @param $template_result
1677
   */
1678
  protected function renderShipSortOptions(&$template_result) {
1679
    foreach(classLocale::$lang['player_option_fleet_ship_sort'] as $sort_id => $sort_text) {
1680
      $template_result['.']['ship_sort_list'][] = array(
1681
        'VALUE' => $sort_id,
1682
        'TEXT'  => $sort_text,
1683
      );
1684
    }
1685
    $template_result += array(
1686
      'FLEET_SHIP_SORT'         => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_SORT],
1687
      'FLEET_SHIP_SORT_INVERSE' => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_SORT_INVERSE],
1688
    );
1689
  }
1690
1691
  /**
1692
   */
1693
  public function fleetPage0() {
1694
    global $template_result;
1695
1696
    lng_include('overview');
1697
1698
    if(empty($this->dbSourcePlanetRow)) {
1699
      message(classLocale::$lang['fl_noplanetrow'], classLocale::$lang['fl_error']);
1700
    }
1701
1702
    // TODO - redo to unitlist render/unit render
1703
    $this->renderAvailableShips($template_result, $this->dbOwnerRow, $this->dbSourcePlanetRow);
1704
1705
    $this->renderShipSortOptions($template_result);
1706
1707
    /**
1708
     * @var Player $playerOwner
1709
     */
1710
    $playerOwner = $this->getLocatedAt();
1711
1712
    $template_result += array(
1713
      'FLYING_FLEETS'      => $playerOwner->fleetsFlying(),
1714
      'MAX_FLEETS'         => $playerOwner->fleetsMax(),
1715
      'FREE_FLEETS'        => $playerOwner->fleetsMax() - $playerOwner->fleetsFlying(),
1716
      'FLYING_EXPEDITIONS' => $playerOwner->expeditionsFlying(),
1717
      'MAX_EXPEDITIONS'    => $playerOwner->expeditionsMax(),
1718
      'FREE_EXPEDITIONS'   => $playerOwner->expeditionsMax() - $playerOwner->expeditionsFlying(),
1719
      'COLONIES_CURRENT'   => $playerOwner->coloniesCurrent(),
1720
      'COLONIES_MAX'       => $playerOwner->coloniesMax(),
1721
1722
      'TYPE_NAME' => classLocale::$lang['fl_planettype'][$this->targetVector->type],
1723
1724
      'speed_factor' => flt_server_flight_speed_multiplier(),
1725
1726
      'PLANET_RESOURCES' => pretty_number($this->dbSourcePlanetRow['metal'] + $this->dbSourcePlanetRow['crystal'] + $this->dbSourcePlanetRow['deuterium']),
1727
      'PLANET_DEUTERIUM' => pretty_number($this->dbSourcePlanetRow['deuterium']),
1728
1729
      'PLAYER_OPTION_FLEET_SHIP_SELECT_OLD'       => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_SELECT_OLD],
1730
      'PLAYER_OPTION_FLEET_SHIP_HIDE_SPEED'       => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_HIDE_SPEED],
1731
      'PLAYER_OPTION_FLEET_SHIP_HIDE_CAPACITY'    => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_HIDE_CAPACITY],
1732
      'PLAYER_OPTION_FLEET_SHIP_HIDE_CONSUMPTION' => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_HIDE_CONSUMPTION],
1733
    );
1734
1735
    $template = gettemplate('fleet0', true);
1736
    $template->assign_recursive($template_result);
1737
    display($template, classLocale::$lang['fl_title']);
1738
  }
1739
1740
  public function fleetPage1() {
1741
    global $template_result;
1742
1743
    $this->renderFleet($template_result);
1744
1745
    $this->renderAllowedPlanetTypes($template_result);
1746
1747
    $this->renderOwnPlanets($template_result);
1748
1749
    $this->renderFleetShortcuts($template_result);
1750
1751
    $this->renderACSList($template_result);
1752
1753
    $template_result += array(
1754
      'speed_factor' => flt_server_flight_speed_multiplier(),
1755
1756
      'fleet_speed'    => flt_fleet_speed($this->dbOwnerRow, $this->shipsGetArray()),
1757
      'fleet_capacity' => $this->shipsGetCapacity(),
1758
1759
      'PLANET_DEUTERIUM' => pretty_number($this->dbSourcePlanetRow['deuterium']),
1760
1761
      'PAGE_HINT' => classLocale::$lang['fl_page1_hint'],
1762
    );
1763
1764
    $template = gettemplate('fleet1', true);
1765
    $template->assign_recursive($template_result);
1766
    display($template, classLocale::$lang['fl_title']);
1767
  }
1768
1769
  public function fleetPage2() {
1770
    global $template_result;
1771
1772
    try {
1773
      $this->restrictMission();
1774
    } catch(Exception $e) {
1775
      // TODO - MESSAGE BOX
1776 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...
1777
        pdie(classLocale::$lang['fl_attack_error'][$e->getCode()]);
1778
      } else {
1779
        pdump('FLIGHT_ALLOWED', FLIGHT_ALLOWED);
1780
      }
1781
    }
1782
1783
    $this->renderAllowedMissions($template_result);
1784
    $this->renderFleet($template_result);
1785
1786
    $max_duration = $this->_mission_type == MT_EXPLORE ? get_player_max_expedition_duration($this->dbOwnerRow) :
1787
      (isset($this->allowed_missions[MT_HOLD]) ? 12 : 0);
1788
    $this->renderDuration($template_result, $max_duration);
1789
1790
    $travel_data = $this->flt_travel_data($this->oldSpeedInTens);
1791
1792
    $sn_group_resources = sn_get_groups('resources_loot');
1793
    $planetResources = array();
1794
    foreach($sn_group_resources as $resource_id) {
1795
      $planetResources[$resource_id] = floor(mrc_get_level($this->dbOwnerRow, $this->dbSourcePlanetRow, $resource_id) - ($resource_id == RES_DEUTERIUM ? $travel_data['consumption'] : 0));
1796
    }
1797
    $this->renderPlanetResources($planetResources, $template_result);
1798
1799
    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) {
1800
      $template_result += array(
1801
        'CAPTAIN_ID'     => $captain['unit_id'],
1802
        'CAPTAIN_LEVEL'  => $captain['captain_level'],
1803
        'CAPTAIN_SHIELD' => $captain['captain_shield'],
1804
        'CAPTAIN_ARMOR'  => $captain['captain_armor'],
1805
        'CAPTAIN_ATTACK' => $captain['captain_attack'],
1806
      );
1807
    }
1808
1809
    $template_result += array(
1810
      'planet_metal'     => $planetResources[RES_METAL],
1811
      'planet_crystal'   => $planetResources[RES_CRYSTAL],
1812
      'planet_deuterium' => $planetResources[RES_DEUTERIUM],
1813
1814
      'fleet_capacity' => $this->shipsGetCapacity() - $travel_data['consumption'],
1815
      'speed'          => $this->oldSpeedInTens,
1816
      'fleet_group'    => $this->_group_id,
1817
1818
      'MAX_DURATION'          => $max_duration,
1819
1820
      // 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...
1821
//      'IS_TRANSPORT_MISSIONS' => !empty($this->allowed_missions[$this->_mission_type]['transport']),
1822
      'IS_TRANSPORT_MISSIONS' => true,
1823
1824
      'PLAYER_COLONIES_CURRENT' => get_player_current_colonies($this->dbOwnerRow),
1825
      'PLAYER_COLONIES_MAX'     => get_player_max_colonies($this->dbOwnerRow),
1826
    );
1827
1828
    $template = gettemplate('fleet2', true);
1829
    $template->assign_recursive($template_result);
1830
    display($template, classLocale::$lang['fl_title']);
1831
  }
1832
1833
1834
  public function restrict2MissionTransportWithResources($fleetResources) {
1835
    if($this->_mission_type != MT_TRANSPORT ) {
1836
      return;
1837
    }
1838
1839
    if(array_sum($fleetResources) <= 0) {
1840
      throw new Exception('FLIGHT_RESOURCES_EMPTY', FLIGHT_RESOURCES_EMPTY);
1841
    }
1842
  }
1843
1844
  protected function restrict2MissionExploreAvailable() {
1845
    if($this->_mission_type != MT_EXPLORE) {
1846
      return;
1847
    }
1848
1849
    if(($expeditionsMax = get_player_max_expeditons($this->dbOwnerRow)) <= 0) {
1850
      throw new Exception('FLIGHT_MISSION_EXPLORE_NO_ASTROTECH', FLIGHT_MISSION_EXPLORE_NO_ASTROTECH);
1851
    }
1852
    if(FleetList::fleet_count_flying($this->getPlayerOwnerId(), MT_EXPLORE) >= $expeditionsMax) {
1853
      throw new Exception('FLIGHT_MISSION_EXPLORE_NO_SLOTS', FLIGHT_MISSION_EXPLORE_NO_SLOTS);
1854
    }
1855
1856
    $this->restrictToNotOnlySpies();
1857
    $this->restrictToNoMissiles();
1858
1859
    throw new Exception('FLIGHT_ALLOWED', FLIGHT_ALLOWED);
1860
  }
1861
1862
1863
  public function fleetPage3($time_to_travel) {
1864
    global $target_mission, $fleetarray, $planetrow;
1865
    global $galaxy, $system, $planet, $TargetPlanet, $consumption, $template_result;
1866
    global $errorlist, $planet_type, $MaxExpeditions, $FlyingExpeditions;
1867
    global $speed_percent, $distance, $fleet_speed, $user, $debug;
1868
1869
    $classLocale = classLocale::$lang;
1870
1871
    sn_db_transaction_start();
1872
1873
    db_user_lock_with_target_owner($this->dbOwnerRow, $this->dbTargetRow);
1874
1875
    $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...
1876
    $this->dbSourcePlanetRow = db_planet_by_id($this->dbSourcePlanetRow['id'], true);
1877
    if(!empty($this->dbTargetRow['id'])) {
1878
      $this->dbTargetRow = db_planet_by_id($this->dbTargetRow['id'], true);
1879
    }
1880
    if(!empty($this->dbTargetRow['id_owner'])) {
1881
      $this->dbTargetOwnerRow = db_planet_by_id($this->dbTargetRow['id_owner'], true);
1882
    }
1883
1884
    try {
1885
1886
1887
      // Do the restrictMission checks
1888
1889
      // TODO - Кое-какие проверки дают FLIGHT_ALLOWED - ЧТО НЕПРАВДА В ДАННОМ СЛУЧАЕ!!!
1890
      // На странице 1 некоторые проверки ДОЛЖНЫ БЫТЬ опущены - иначе будет некрасиво
1891
      // А вот здесь надо проверять много дополнительной хуйни
1892
      try {
1893
        $this->restrictToNonVacationSender();
1894
1895
        $this->restrictToNotSource();
1896
1897
        // No mission could fly beyond Universe - i.e. with wrong Galaxy and/or System coordinates
1898
        $this->restrictToUniverse();
1899
1900
        // Only ships and missiles can be sent to mission
1901
        $this->restrictToFleetUnits();
1902
        // Only units with main engines (speed >=0) can fly - no other units like satellites
1903
        $this->restrictToMovable();
1904
1905
        // No missions except MT_EXPLORE could target coordinates beyond known system
1906
        $this->restrictKnownSpaceOrMissionExplore();
1907
        // Beyond this point all mission address only known space
1908
1909
        // No missions except MT_COLONIZE could target empty coordinates
1910
        $this->restrictTargetExistsOrMissionColonize();
1911
        // Beyond this point all mission address only existing planets/moons
1912
1913
        // No missions except MT_RECYCLE could target debris
1914
        $this->restrictNotDebrisOrMissionRecycle();
1915
        // Beyond this point targets can be only PT_PLANET or PT_MOON
1916
1917
1918
        // TODO  - ALL OF THE ABOVE!
1919
        $this->restrictMission();
1920
      } catch(Exception $e) {
1921
        // If mission is restricted - rethrow exception
1922
        if($e->getCode() != FLIGHT_ALLOWED) {
1923
          throw new Exception($e->getMessage(), $e->getCode());
1924
        }
1925
      }
1926
1927
      // TODO - later then
1928
1929
      // 2nd level restrictions
1930
      $this->restrict2ToAllowedMissions();
1931
      $this->restrict2ToAllowedPlanetTypes();
1932
1933
1934
      $this->restrict2ToMaxFleets();
1935
1936
1937
      $fleetResources = array(
1938
        RES_METAL     => max(0, floor(sys_get_param_float('resource0'))),
1939
        RES_CRYSTAL   => max(0, floor(sys_get_param_float('resource1'))),
1940
        RES_DEUTERIUM => max(0, floor(sys_get_param_float('resource2'))),
1941
      );
1942
1943
      $travelData = $this->flt_travel_data($this->oldSpeedInTens);
1944
      $fleetCapacity = $travelData['capacity'];
1945
      $fleetConsumption = $travelData['consumption'];
1946
      /*
1947
        fleet_speed
1948
        distance
1949
        duration
1950
        consumption
1951
        capacity
1952
        hold                   = capacity - consumption,
1953
        transport_effectivness = consumption ? capacity / consumption : 0,
1954
       */
1955
1956
      $this->restrict2ToEnoughCapacity($fleetCapacity, $fleetConsumption, $fleetResources);
1957
1958
      $this->restrict2ByResources($fleetConsumption, $fleetResources);
1959
1960
      $this->restrict2ToEnoughShips();
1961
1962
      // TODO - REWRITE TO LEVEL 2
1963
      $this->restrict2MissionExploreAvailable();
1964
      $this->restrictTargetExistsOrMissionColonize();
1965
      $this->restrictNotDebrisOrMissionRecycle();
1966
      // TODO - START $this->restrictFriendOrFoe();
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...
1967 View Code Duplication
      if($this->dbTargetRow['id'] == $this->getPlayerOwnerId()) {
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...
1968
        // Spying can't be done on owner's planet/moon
1969
        unset($this->allowed_missions[MT_SPY]);
1970
        // Attack can't be done on owner's planet/moon
1971
        unset($this->allowed_missions[MT_ATTACK]);
1972
        // ACS can't be done on owner's planet/moon
1973
        unset($this->allowed_missions[MT_ACS]);
1974
        // Destroy can't be done on owner's moon
1975
        unset($this->allowed_missions[MT_DESTROY]);
1976
1977
        $this->restrictToNoMissiles();
1978
1979
        // MT_RELOCATE
1980
        // No checks
1981
        // TODO - check captain
1982
1983
        // MT_HOLD
1984
        // TODO - Check for Allies Deposit for HOLD
1985
1986
        // MT_TRANSPORT
1987
1988
      } else {
1989
        // Relocate can be done only on owner's planet/moon
1990
        unset($this->allowed_missions[MT_RELOCATE]);
1991
1992
        // TODO - check for moratorium
1993
1994
        // MT_HOLD
1995
        // TODO - Check for Allies Deposit for HOLD
1996
        // TODO - Noob protection for HOLD depends on server settings
1997
1998
        // MT_SPY
1999
        $this->restrictToNotOnlySpiesOrMissionSpy();
2000
2001
        // TODO - check noob protection
2002
2003
        // TODO - check bashing
2004
2005
        // No missions except MT_MISSILE should have any missiles in fleet
2006
        $this->restrictMissionMissile();
2007
        $this->restrictToNoMissiles();
2008
        // Beyond this point no mission can have a missile in fleet
2009
2010
        // MT_DESTROY
2011
        $this->restrictMissionDestroy();
2012
2013
        // MT_ACS
2014
        $this->restrictMissionACS();
2015
2016
        // MT_ATTACK - no checks
2017
2018
        // MT_TRANSPORT - no checks
2019
      }
2020
      // TODO - END $this->restrictFriendOrFoe();
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...
2021
2022
2023
      //
2024
      //
2025
      //
2026
      //
2027
      //
2028
      //
2029
      //
2030
      //
2031
      //
2032
      //
2033
      //
2034
      //
2035
      //
2036
      //
2037
      //
2038
      //
2039
      //
2040
      //
2041
2042
2043
      $this->restrict2MissionTransportWithResources($fleetResources);
2044
    } catch(Exception $e) {
2045
      // TODO - MESSAGE BOX
2046 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...
2047
        sn_db_transaction_rollback();
2048
        pdie(classLocale::$lang['fl_attack_error'][$e->getCode()]);
2049
      } else {
2050
        pdump('FLIGHT_ALLOWED', FLIGHT_ALLOWED);
2051
      }
2052
    }
2053
2054
    $errorlist = '';
2055
2056
    $errorlist .= !is_array($fleetarray) ? classLocale::$lang['fl_no_fleetarray'] : '';
2057
2058
    $TransMetal = max(0, floor(sys_get_param_float('resource0')));
2059
    $TransCrystal = max(0, floor(sys_get_param_float('resource1')));
2060
    $TransDeuterium = max(0, floor(sys_get_param_float('resource2')));
2061
    $StorageNeeded = $TransMetal + $TransCrystal + $TransDeuterium;
2062
2063
    if(!$StorageNeeded && $target_mission == MT_TRANSPORT) {
2064
      $errorlist .= classLocale::$lang['fl_noenoughtgoods'];
2065
    }
2066
2067
2068
2069
    if($target_mission == MT_EXPLORE) {
2070
      if($MaxExpeditions == 0) {
2071
        $errorlist .= classLocale::$lang['fl_expe_notech'];
2072
      } elseif($FlyingExpeditions >= $MaxExpeditions) {
2073
        $errorlist .= classLocale::$lang['fl_expe_max'];
2074
      }
2075
    } else {
2076
      if($TargetPlanet['id_owner']) {
2077
        if($target_mission == MT_COLONIZE) {
2078
          $errorlist .= classLocale::$lang['fl_colonized'];
2079
        }
2080
2081
        if($TargetPlanet['id_owner'] == $planetrow['id_owner']) {
2082
          if($target_mission == MT_ATTACK) {
2083
            $errorlist .= classLocale::$lang['fl_no_self_attack'];
2084
          }
2085
2086
          if($target_mission == MT_SPY) {
2087
            $errorlist .= classLocale::$lang['fl_no_self_spy'];
2088
          }
2089
        } else {
2090
          if($target_mission == MT_RELOCATE) {
2091
            $errorlist .= classLocale::$lang['fl_only_stay_at_home'];
2092
          }
2093
        }
2094
      } else {
2095
        if($target_mission < MT_COLONIZE) {
2096
          $errorlist .= classLocale::$lang['fl_unknow_target'];
2097
        } else {
2098
//          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...
2099
//            $errorlist .= classLocale::$lang['fl_nomoon'];
2100
//          }
2101
2102
          if($target_mission == MT_RECYCLE) {
2103
            if($TargetPlanet['debris_metal'] + $TargetPlanet['debris_crystal'] == 0) {
2104
              $errorlist .= classLocale::$lang['fl_nodebris'];
2105
            }
2106
          }
2107
        }
2108
      }
2109
    }
2110
2111
2112
    if(sn_module::$sn_module['unit_captain']->manifest['active'] && $captain_id = sys_get_param_id('captain_id')) {
2113
      $captain = sn_module::$sn_module['unit_captain']->unit_captain_get($planetrow['id']);
2114
      if(!$captain) {
2115
        $errorlist .= classLocale::$lang['module_unit_captain_error_no_captain'];
2116
      } elseif($captain['unit_location_type'] == LOC_PLANET) {
2117
        if($target_mission == MT_RELOCATE && ($arriving_captain = mrc_get_level($user, $TargetPlanet, UNIT_CAPTAIN, true))) {
2118
          $errorlist .= classLocale::$lang['module_unit_captain_error_captain_already_bound'];
2119
        }
2120
      } else {
2121
        $errorlist .= classLocale::$lang['module_unit_captain_error_captain_flying'];
2122
      }
2123
    }
2124
2125
    if($errorlist) {
2126
      sn_db_transaction_rollback();
2127
      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...
2128
    }
2129
2130
    //Normally... unless its acs...
2131
    $aks = 0;
2132
    $fleet_group = sys_get_param_int('fleet_group');
2133
    //But is it acs??
2134
    //Well all acs fleets must have a fleet code.
2135
    //The co-ords must be the same as where the acs fleet is going.
2136
    if($fleet_group && sys_get_param_str('acs_target_mr') == "g{$galaxy}s{$system}p{$planet}t{$planet_type}") {
2137
      //ACS attack must exist (if acs fleet has arrived this will also return false (2 checks in 1!!!)
2138
      $aks = db_acs_get_by_group_id($fleet_group);
2139
      if(!$aks) {
2140
        $fleet_group = 0;
2141
      } else {
2142
        //Also it must be mission type 2
2143
        $target_mission = MT_ACS;
2144
2145
        $galaxy = $aks['galaxy'];
2146
        $system = $aks['system'];
2147
        $planet = $aks['planet'];
2148
        $planet_type = $aks['planet_type'];
2149
      }
2150
    } elseif($target_mission == MT_ACS) {
2151
      //Check that a failed acs attack isn't being sent, if it is, make it an attack fleet.
2152
      $target_mission = MT_ATTACK;
2153
    }
2154
2155
    if($target_mission == MT_COLONIZE || $target_mission == MT_EXPLORE) {
2156
      $TargetPlanet = array('galaxy' => $galaxy, 'system' => $system, 'planet' => $planet, 'id_owner' => 0);
2157
    }
2158
    $options = array('fleet_speed_percent' => $speed_percent, 'fleet_group' => $fleet_group, 'resources' => $StorageNeeded);
2159
    $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...
2160
2161
    if($cant_attack !== FLIGHT_ALLOWED) {
2162
      message("<span class='error'><b>{$classLocale['fl_attack_error'][$cant_attack]}</b></span>", classLocale::$lang['fl_error'], 'fleet' . DOT_PHP_EX, 99);
2163
    }
2164
2165
    $mission_time_in_seconds = 0;
2166
    $arrival_time = SN_TIME_NOW + $time_to_travel;
2167
    if($target_mission == MT_ACS && $aks) {
2168
//    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...
2169
      if($arrival_time > $aks['ankunft']) {
2170
        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']);
2171
      }
2172
      $group_sync_delta_time = $aks['ankunft'] - $arrival_time;
2173
      // Set arrival time to ACS arrival time
2174
      $arrival_time = $aks['ankunft'];
2175
      // Set return time to ACS return time + fleet's time to travel
2176
      $return_time = $aks['ankunft'] + $time_to_travel;
2177
    } else {
2178
      if($target_mission == MT_EXPLORE || $target_mission == MT_HOLD) {
2179
        $max_duration = $target_mission == MT_EXPLORE ? get_player_max_expedition_duration($user) : ($target_mission == MT_HOLD ? 12 : 0);
2180
        if($max_duration) {
2181
          $mission_time_in_hours = sys_get_param_id('missiontime');
2182
          if($mission_time_in_hours > $max_duration || $mission_time_in_hours < 1) {
2183
            $debug->warning('Supplying wrong mission time', 'Hack attempt', 302, array('base_dump' => true));
2184
            die();
2185
          }
2186
          $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));
2187
        }
2188
      }
2189
      $return_time = $arrival_time + $mission_time_in_seconds + $time_to_travel;
2190
      $group_sync_delta_time = 0;
2191
    }
2192
2193
//    $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...
2194
2195
    $db_changeset = array();
2196
    foreach($fleetarray as $Ship => $Count) {
2197
//      $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...
2198
      $db_changeset['unit'][] = sn_db_unit_changeset_prepare($Ship, -$Count, $user, $planetrow['id']);
2199
    }
2200
//    $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...
2201
2202
//    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...
2203
//      message("<span class='error'><b>" . classLocale::$lang['fl_nostoragespa'] . pretty_number($StorageNeeded - $FleetStorage) . "</b></span>", classLocale::$lang['fl_error'], 'fleet' . DOT_PHP_EX, 2);
2204
//    }
2205
//    if($planetrow['deuterium'] < $TransDeuterium + $consumption) {
2206
//      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);
2207
//    }
2208
//    if(($planetrow['metal'] < $TransMetal) || ($planetrow['crystal'] < $TransCrystal)) {
2209
//      message("<font color=\"red\"><b>" . classLocale::$lang['fl_no_resources'] . "</b></font>", classLocale::$lang['fl_error'], 'fleet' . DOT_PHP_EX, 2);
2210
//    }
2211
2212
2213
    //
2214
    //
2215
    //
2216
    //
2217
    //
2218
    //
2219
    //
2220
    //
2221
    // ---------------- END OF CHECKS ------------------------------------------------------
2222
2223
    $fleetarray[RES_METAL] = $TransMetal;
2224
    $fleetarray[RES_CRYSTAL] = $TransCrystal;
2225
    $fleetarray[RES_DEUTERIUM] = $TransDeuterium;
2226
2227
    $objFleet = new Fleet();
2228
    $objFleet->set_times($time_to_travel, $mission_time_in_seconds, $group_sync_delta_time);
2229
    $objFleet->unitsSetFromArray($fleetarray);
2230
    $objFleet->mission_type = $target_mission;
2231
    $objFleet->set_start_planet($planetrow);
2232
    $objFleet->set_end_planet(array(
2233
      'id'          => !empty($TargetPlanet['id']) ? $TargetPlanet['id'] : null,
2234
      'galaxy'      => !empty($galaxy) ? $galaxy : 0,
2235
      'system'      => !empty($system) ? $system : 0,
2236
      'planet'      => !empty($planet) ? $planet : 0,
2237
      'planet_type' => !empty($planet_type) ? $planet_type : 0,
2238
      'id_owner'    => $TargetPlanet['id_owner'],
2239
    ));
2240
    $objFleet->playerOwnerId = $user['id'];
2241
    $objFleet->group_id = $fleet_group;
2242
    $objFleet->dbInsert();
2243
2244
    db_planet_set_by_id($planetrow['id'], "`metal` = `metal` - {$TransMetal}, `crystal` = `crystal` - {$TransCrystal}, `deuterium` = `deuterium` - {$TransDeuterium} - {$consumption}");
2245
    db_changeset_apply($db_changeset);
2246
2247
    $template = gettemplate('fleet3', true);
2248
2249
    if(is_array($captain)) {
2250
      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...
2251
    }
2252
2253
    $template_route = array(
2254
      'ID'                 => 1,
2255
      'START_TYPE_TEXT_SH' => classLocale::$lang['sys_planet_type_sh'][$planetrow['planet_type']],
2256
      'START_COORDS'       => uni_render_coordinates($planetrow),
2257
      'START_NAME'         => $planetrow['name'],
2258
      'START_TIME_TEXT'    => date(FMT_DATE_TIME, $return_time + SN_CLIENT_TIME_DIFF),
2259
      'START_LEFT'         => floor($return_time + 1 - SN_TIME_NOW),
2260
    );
2261
    if(!empty($TargetPlanet)) {
2262
      $template_route += array(
2263
        'END_TYPE_TEXT_SH' => classLocale::$lang['sys_planet_type_sh'][$TargetPlanet['planet_type']],
2264
        'END_COORDS'       => uni_render_coordinates($TargetPlanet),
2265
        'END_NAME'         => $TargetPlanet['name'],
2266
        'END_TIME_TEXT'    => date(FMT_DATE_TIME, $arrival_time + SN_CLIENT_TIME_DIFF),
2267
        'END_LEFT'         => floor($arrival_time + 1 - SN_TIME_NOW),
2268
      );
2269
    }
2270
2271
    $template->assign_block_vars('fleets', $template_route);
2272
2273
    $sn_groups_fleet = sn_get_groups('fleet');
2274
    foreach($fleetarray as $ship_id => $ship_count) {
2275
      if(in_array($ship_id, $sn_groups_fleet) && $ship_count) {
2276
//      $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...
2277
        $template->assign_block_vars('fleets.ships', array(
2278
          'ID'          => $ship_id,
2279
          'AMOUNT'      => $ship_count,
2280
          'AMOUNT_TEXT' => pretty_number($ship_count),
2281
//        '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...
2282
//        'SPEED'       => $ship_base_data['speed'],
2283
          'NAME'        => classLocale::$lang['tech'][$ship_id],
2284
        ));
2285
      }
2286
    }
2287
2288
    $template->assign_vars(array(
2289
      'mission'         => classLocale::$lang['type_mission'][$target_mission] . ($target_mission == MT_EXPLORE || $target_mission == MT_HOLD ? ' ' . pretty_time($mission_time_in_seconds) : ''),
2290
      'dist'            => pretty_number($distance),
2291
      'speed'           => pretty_number($fleet_speed),
2292
      'deute_need'      => pretty_number($consumption),
2293
      'from'            => "{$planetrow['galaxy']}:{$planetrow['system']}:{$planetrow['planet']}",
2294
      'time_go'         => date(FMT_DATE_TIME, $arrival_time),
2295
      'time_go_local'   => date(FMT_DATE_TIME, $arrival_time + SN_CLIENT_TIME_DIFF),
2296
      'time_back'       => date(FMT_DATE_TIME, $return_time),
2297
      'time_back_local' => date(FMT_DATE_TIME, $return_time + SN_CLIENT_TIME_DIFF),
2298
    ));
2299
2300
    pdie('Stop for debug');
2301
2302
    sn_db_transaction_commit();
2303
    $planetrow = db_planet_by_id($planetrow['id']);
2304
    $template->assign_recursive($template_result);
2305
    display($template, classLocale::$lang['fl_title']);
2306
  }
2307
2308
}
2309