Completed
Push — work-fleets ( 03d1ea...77506a )
by SuperNova.WS
05:17
created

Fleet::checkOnlyAttackMissiles()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 5
rs 9.4285
cc 2
eloc 3
nc 2
nop 0
1
<?php
2
3
/**
4
 * Class Fleet
5
 *
6
 * @property int dbId
7
 * @property int playerOwnerId
8
 * @property int group_id
9
 * @property int mission_type
10
 * @property int target_owner_id
11
 * @property int is_returning
12
 *
13
 * @property int time_launch
14
 * @property int time_arrive_to_target
15
 * @property int time_mission_job_complete
16
 * @property int time_return_to_source
17
 *
18
 * @property int fleet_start_planet_id
19
 * @property int fleet_start_galaxy
20
 * @property int fleet_start_system
21
 * @property int fleet_start_planet
22
 * @property int fleet_start_type
23
 *
24
 * @property int fleet_end_planet_id
25
 * @property int fleet_end_galaxy
26
 * @property int fleet_end_system
27
 * @property int fleet_end_planet
28
 * @property int fleet_end_type
29
 *
30
 */
31
class Fleet extends UnitContainer {
32
33
  // DBRow inheritance *************************************************************************************************
34
35
  /**
36
   * Table name in DB
37
   *
38
   * @var string
39
   */
40
  protected static $_table = 'fleets';
41
  /**
42
   * Name of ID field in DB
43
   *
44
   * @var string
45
   */
46
  protected static $_dbIdFieldName = 'fleet_id';
47
  /**
48
   * DB_ROW to Class translation scheme
49
   *
50
   * @var array
51
   */
52
  protected static $_properties = array(
53
    'dbId'          => array(
54
      P_DB_FIELD => 'fleet_id',
55
    ),
56
    'playerOwnerId' => array(
57
      P_METHOD_EXTRACT => 'ownerExtract',
58
      P_METHOD_INJECT  => 'ownerInject',
59
//      P_DB_FIELD => 'fleet_owner',
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

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

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

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

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

Loading history...
80
//      P_FUNC_OUTPUT => 'get_ship_count',
81
//      P_DB_FIELDS_LINKED => array(
82
//        'fleet_amount',
83
//      ),
84
      P_READ_ONLY => true,
85
    ),
86
87
    'time_launch' => array(
88
      P_DB_FIELD => 'start_time',
89
    ),
90
91
    'time_arrive_to_target'     => array(
92
      P_DB_FIELD => 'fleet_start_time',
93
    ),
94
    'time_mission_job_complete' => array(
95
      P_DB_FIELD => 'fleet_end_stay',
96
    ),
97
    'time_return_to_source'     => array(
98
      P_DB_FIELD => 'fleet_end_time',
99
    ),
100
101
    'fleet_start_planet_id' => array(
102
      P_DB_FIELD   => 'fleet_start_planet_id',
103
      P_FUNC_INPUT => 'nullIfEmpty',
104
    ),
105
106
    'fleet_start_galaxy' => array(
107
      P_DB_FIELD => 'fleet_start_galaxy',
108
    ),
109
    'fleet_start_system' => array(
110
      P_DB_FIELD => 'fleet_start_system',
111
    ),
112
    'fleet_start_planet' => array(
113
      P_DB_FIELD => 'fleet_start_planet',
114
    ),
115
    'fleet_start_type'   => array(
116
      P_DB_FIELD => 'fleet_start_type',
117
    ),
118
119
    'fleet_end_planet_id' => array(
120
      P_DB_FIELD   => 'fleet_end_planet_id',
121
      P_FUNC_INPUT => 'nullIfEmpty',
122
    ),
123
    'fleet_end_galaxy'    => array(
124
      P_DB_FIELD => 'fleet_end_galaxy',
125
    ),
126
    'fleet_end_system'    => array(
127
      P_DB_FIELD => 'fleet_end_system',
128
    ),
129
    'fleet_end_planet'    => array(
130
      P_DB_FIELD => 'fleet_end_planet',
131
    ),
132
    'fleet_end_type'      => array(
133
      P_DB_FIELD => 'fleet_end_type',
134
    ),
135
136
    'resource_list' => array(
137
      P_METHOD_EXTRACT   => 'resourcesExtract',
138
      P_METHOD_INJECT    => 'resourcesInject',
139
      P_DB_FIELDS_LINKED => array(
140
        'fleet_resource_metal',
141
        'fleet_resource_crystal',
142
        'fleet_resource_deuterium',
143
      ),
144
    ),
145
  );
146
147
148
  // UnitContainer inheritance *****************************************************************************************
149
  /**
150
   * Type of this location
151
   *
152
   * @var int $locationType
153
   */
154
  protected static $locationType = LOC_FLEET;
155
156
157
  // New properties ****************************************************************************************************
158
  /**
159
   * `fleet_owner`
160
   *
161
   * @var int
162
   */
163
  protected $_playerOwnerId = 0;
164
  /**
165
   * `fleet_group`
166
   *
167
   * @var int
168
   */
169
  protected $_group_id = 0;
170
171
  /**
172
   * `fleet_mission`
173
   *
174
   * @var int
175
   */
176
  protected $_mission_type = 0;
177
178
  /**
179
   * `fleet_target_owner`
180
   *
181
   * @var int
182
   */
183
  protected $_target_owner_id = null;
184
185
  /**
186
   * @var array
187
   */
188
  protected $resource_list = array(
189
    RES_METAL     => 0,
190
    RES_CRYSTAL   => 0,
191
    RES_DEUTERIUM => 0,
192
  );
193
194
195
  /**
196
   * `fleet__mess` - Флаг возвращающегося флота
197
   *
198
   * @var int
199
   */
200
  protected $_is_returning = 0;
201
  /**
202
   * `start_time` - Время отправления - таймштамп взлёта флота из точки отправления
203
   *
204
   * @var int $_time_launch
205
   */
206
  protected $_time_launch = 0; // `start_time` = SN_TIME_NOW
207
  /**
208
   * `fleet_start_time` - Время прибытия в точку миссии/время начала выполнения миссии
209
   *
210
   * @var int $_time_arrive_to_target
211
   */
212
  protected $_time_arrive_to_target = 0; // `fleet_start_time` = SN_TIME_NOW + $time_travel
213
  /**
214
   * `fleet_end_stay` - Время окончания миссии в точке назначения
215
   *
216
   * @var int $_time_mission_job_complete
217
   */
218
  protected $_time_mission_job_complete = 0; // `fleet_end_stay`
219
  /**
220
   * `fleet_end_time` - Время возвращения флота после окончания миссии
221
   *
222
   * @var int $_time_return_to_source
223
   */
224
  protected $_time_return_to_source = 0; // `fleet_end_time`
225
226
227
  protected $_fleet_start_planet_id = null;
228
  protected $_fleet_start_galaxy = 0;
229
  protected $_fleet_start_system = 0;
230
  protected $_fleet_start_planet = 0;
231
  protected $_fleet_start_type = PT_ALL;
232
233
  protected $_fleet_end_planet_id = null;
234
  protected $_fleet_end_galaxy = 0;
235
  protected $_fleet_end_system = 0;
236
  protected $_fleet_end_planet = 0;
237
  protected $_fleet_end_type = PT_ALL;
238
239
  // Missile properties
240
  public $missile_target = 0;
241
242
  // Fleet event properties
243
  public $fleet_start_name = '';
244
  public $fleet_end_name = '';
245
  public $ov_label = '';
246
  public $ov_this_planet = '';
247
  public $event_time = 0;
248
249
  protected $resource_delta = array();
250
  protected $resource_replace = array();
251
252
253
//
254
255
256
  protected $allowed_missions = array();
257
  protected $exists_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
  public $travelData = array();
292
293
  protected $isRealFlight = false;
294
295
  /**
296
   * Fleet constructor.
297
   */
298
  public function __construct() {
299
    parent::__construct();
300
    $this->allowed_missions = $this->exists_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 $exists_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...
Documentation Bug introduced by
It seems like $this->exists_missions =..._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...
301
  }
302
303
  /**
304
   * @param array $template_result
305
   * @param array $playerRow
306
   * @param array $planetRow
307
   */
308
  // TODO - redo to unit/unitlist renderer
309
  public function renderAvailableShips(&$template_result, $playerRow, $planetRow) {
310
    $record_index = 0;
311
    $ship_list = array();
312
    foreach(sn_get_groups('fleet') as $n => $unit_id) {
313
      $unit_level = mrc_get_level($playerRow, $planetRow, $unit_id, false, true);
314
      if($unit_level <= 0) {
315
        continue;
316
      }
317
      $ship_data = get_ship_data($unit_id, $playerRow);
318
      $ship_list[$unit_id] = array(
319
        '__INDEX'          => $record_index++,
320
        'ID'               => $unit_id,
321
        'NAME'             => classLocale::$lang['tech'][$unit_id],
322
        'AMOUNT'           => $unit_level,
323
        'AMOUNT_TEXT'      => pretty_number($unit_level),
324
        'CONSUMPTION'      => $ship_data['consumption'],
325
        'CONSUMPTION_TEXT' => pretty_number($ship_data['consumption']),
326
        'SPEED'            => $ship_data['speed'],
327
        'SPEED_TEXT'       => pretty_number($ship_data['speed']),
328
        'CAPACITY'         => $ship_data['capacity'],
329
        'CAPACITY_TEXT'    => pretty_number($ship_data['capacity']),
330
      );
331
    }
332
333
    sortUnitRenderedList($ship_list, classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_SORT], classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_SORT_INVERSE]);
334
335
    foreach($ship_list as $ship_data) {
336
      $template_result['.']['ships'][] = $ship_data;
337
    }
338
  }
339
340
  public function isEmpty() {
341
    return !$this->resourcesGetTotal() && !$this->shipsGetTotal();
342
  }
343
344
//  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...
345
//    return $this->playerOwnerId;
346
//  }
347
348
  /**
349
   * Initializes Fleet from user params and posts it to DB
350
   */
351
  public function dbInsert() {
352
    // WARNING! MISSION TIMES MUST BE SET WITH set_times() method!
353
    // TODO - more checks!
354
    if(empty($this->_time_launch)) {
355
      die('Fleet time not set!');
356
    }
357
358
    parent::dbInsert();
359
  }
360
361
362
  /* FLEET DB ACCESS =================================================================================================*/
363
364
  /**
365
   * LOCK - Lock all records which can be used with mission
366
   *
367
   * @param $mission_data
368
   * @param $fleet_id
369
   *
370
   * @return array|bool|mysqli_result|null
371
   */
372
  public function dbLockFlying(&$mission_data) {
373
    // Тупо лочим всех юзеров, чьи флоты летят или улетают с координат отбытия/прибытия $fleet_row
374
    // Что бы делать это умно - надо учитывать fleet__mess во $fleet_row и в таблице fleets
375
376
    $fleet_id_safe = idval($this->_dbId);
377
378
    return doquery(
379
    // Блокировка самого флота
380
      "SELECT 1 FROM {{fleets}} AS f " .
381
382
      // Блокировка всех юнитов, принадлежащих этому флоту
383
      "LEFT JOIN {{unit}} as unit ON unit.unit_location_type = " . static::$locationType . " AND unit.unit_location_id = f.fleet_id " .
384
385
      // Блокировка всех прилетающих и улетающих флотов, если нужно
386
      // TODO - lock fleets by COORDINATES
387
      ($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 " : '') .
388
      // Блокировка всех юнитов, принадлежащих прилетающим и улетающим флотам - ufd = unit_fleet_destination
389
      ($mission_data['dst_fleets'] ? "LEFT JOIN {{unit}} AS ufd ON ufd.unit_location_type = " . static::$locationType . " AND ufd.unit_location_id = fd.fleet_id " : '') .
390
391
      ($mission_data['dst_user'] || $mission_data['dst_planet'] ? "LEFT JOIN {{users}} AS ud ON ud.id = f.fleet_target_owner " : '') .
392
      // Блокировка всех юнитов, принадлежащих владельцу планеты-цели
393
      ($mission_data['dst_user'] || $mission_data['dst_planet'] ? "LEFT JOIN {{unit}} AS unit_player_dest ON unit_player_dest.unit_player_id = ud.id " : '') .
394
      // Блокировка планеты-цели
395
      ($mission_data['dst_planet'] ? "LEFT JOIN {{planets}} AS pd ON pd.id = f.fleet_end_planet_id " : '') .
396
      // Блокировка всех юнитов, принадлежащих планете-цели - НЕ НУЖНО. Уже залочили ранее, как принадлежащие игроку-цели
397
//      ($mission_data['dst_planet'] ? "LEFT JOIN {{unit}} AS upd ON upd.unit_location_type = " . LOC_PLANET . " AND upd.unit_location_id = pd.id " : '') .
398
399
400
      ($mission_data['src_user'] || $mission_data['src_planet'] ? "LEFT JOIN {{users}} AS us ON us.id = f.fleet_owner " : '') .
401
      // Блокировка всех юнитов, принадлежащих владельцу флота
402
      ($mission_data['src_user'] || $mission_data['src_planet'] ? "LEFT JOIN {{unit}} AS unit_player_src ON unit_player_src.unit_player_id = us.id " : '') .
403
      // Блокировка планеты отправления
404
      ($mission_data['src_planet'] ? "LEFT JOIN {{planets}} AS ps ON ps.id = f.fleet_start_planet_id " : '') .
405
      // Блокировка всех юнитов, принадлежащих планете с которой юниты были отправлены - НЕ НУЖНО. Уже залочили ранее, как принадлежащие владельцу флота
406
//      ($mission_data['src_planet'] ? "LEFT JOIN {{unit}} AS ups ON ups.unit_location_type = " . LOC_PLANET . " AND ups.unit_location_id = ps.id " : '') .
407
408
      "WHERE f.fleet_id = {$fleet_id_safe} GROUP BY 1 FOR UPDATE"
409
    );
410
  }
411
412
  /**
413
   * Lock all fields that belongs to operation
414
   *
415
   * @param $dbId
416
   *
417
   * @internal param DBLock $dbRow - Object that accumulates locks
418
   *
419
   */
420
  // TODO = make static
421
  public function dbGetLockById($dbId) {
422
    doquery(
423
    // Блокировка самого флота
424
      "SELECT 1 FROM {{fleets}} AS FLEET0 " .
425
      // Lock fleet owner
426
      "LEFT JOIN {{users}} as USER0 on USER0.id = FLEET0.fleet_owner " .
427
      // Блокировка всех юнитов, принадлежащих этому флоту
428
      "LEFT JOIN {{unit}} as UNIT0 ON UNIT0.unit_location_type = " . LOC_FLEET . " AND UNIT0.unit_location_id = FLEET0.fleet_id " .
429
430
      // Без предварительной выборки неизвестно - куда летит этот флот.
431
      // Поэтому надо выбирать флоты, чьи координаты прибытия ИЛИ отбытия совпадают с координатами прибытия ИЛИ отбытия текущего флота.
432
      // Получаем матрицу 2х2 - т.е. 4 подзапроса.
433
      // При блокировке всегда нужно выбирать И лпанету, И луну - поскольку при бое на орбите луны обломки падают на орбиту планеты.
434
      // Поэтому тип планеты не указывается
435
436
      // Lock fleet heading to destination planet. Only if FLEET0.fleet_mess == 0
437
      "LEFT JOIN {{fleets}} AS FLEET1 ON
438
        FLEET1.fleet_mess = 0 AND FLEET0.fleet_mess = 0 AND
439
        FLEET1.fleet_end_galaxy = FLEET0.fleet_end_galaxy AND
440
        FLEET1.fleet_end_system = FLEET0.fleet_end_system AND
441
        FLEET1.fleet_end_planet = FLEET0.fleet_end_planet
442
      " .
443
      // Блокировка всех юнитов, принадлежащих этим флотам
444
      "LEFT JOIN {{unit}} as UNIT1 ON UNIT1.unit_location_type = " . LOC_FLEET . " AND UNIT1.unit_location_id = FLEET1.fleet_id " .
445
      // Lock fleet owner
446
      "LEFT JOIN {{users}} as USER1 on USER1.id = FLEET1.fleet_owner " .
447
448
      "LEFT JOIN {{fleets}} AS FLEET2 ON
449
        FLEET2.fleet_mess = 1   AND FLEET0.fleet_mess = 0 AND
450
        FLEET2.fleet_start_galaxy = FLEET0.fleet_end_galaxy AND
451
        FLEET2.fleet_start_system = FLEET0.fleet_end_system AND
452
        FLEET2.fleet_start_planet = FLEET0.fleet_end_planet
453
      " .
454
      // Блокировка всех юнитов, принадлежащих этим флотам
455
      "LEFT JOIN {{unit}} as UNIT2 ON
456
        UNIT2.unit_location_type = " . LOC_FLEET . " AND
457
        UNIT2.unit_location_id = FLEET2.fleet_id
458
      " .
459
      // Lock fleet owner
460
      "LEFT JOIN {{users}} as USER2 on
461
        USER2.id = FLEET2.fleet_owner
462
      " .
463
464
      // Lock fleet heading to source planet. Only if FLEET0.fleet_mess == 1
465
      "LEFT JOIN {{fleets}} AS FLEET3 ON
466
        FLEET3.fleet_mess = 0 AND FLEET0.fleet_mess = 1 AND
467
        FLEET3.fleet_end_galaxy = FLEET0.fleet_start_galaxy AND
468
        FLEET3.fleet_end_system = FLEET0.fleet_start_system AND
469
        FLEET3.fleet_end_planet = FLEET0.fleet_start_planet
470
      " .
471
      // Блокировка всех юнитов, принадлежащих этим флотам
472
      "LEFT JOIN {{unit}} as UNIT3 ON
473
        UNIT3.unit_location_type = " . LOC_FLEET . " AND
474
        UNIT3.unit_location_id = FLEET3.fleet_id
475
      " .
476
      // Lock fleet owner
477
      "LEFT JOIN {{users}} as USER3 on USER3.id = FLEET3.fleet_owner " .
478
479
      "LEFT JOIN {{fleets}} AS FLEET4 ON
480
        FLEET4.fleet_mess = 1   AND FLEET0.fleet_mess = 1 AND
481
        FLEET4.fleet_start_galaxy = FLEET0.fleet_start_galaxy AND
482
        FLEET4.fleet_start_system = FLEET0.fleet_start_system AND
483
        FLEET4.fleet_start_planet = FLEET0.fleet_start_planet
484
      " .
485
      // Блокировка всех юнитов, принадлежащих этим флотам
486
      "LEFT JOIN {{unit}} as UNIT4 ON
487
        UNIT4.unit_location_type = " . LOC_FLEET . " AND
488
        UNIT4.unit_location_id = FLEET4.fleet_id
489
      " .
490
      // Lock fleet owner
491
      "LEFT JOIN {{users}} as USER4 on
492
        USER4.id = FLEET4.fleet_owner
493
      " .
494
495
496
      // Locking start planet
497
      "LEFT JOIN {{planets}} AS PLANETS5 ON
498
        FLEET0.fleet_mess = 1 AND
499
        PLANETS5.galaxy = FLEET0.fleet_start_galaxy AND
500
        PLANETS5.system = FLEET0.fleet_start_system AND
501
        PLANETS5.planet = FLEET0.fleet_start_planet
502
      " .
503
      // Lock planet owner
504
      "LEFT JOIN {{users}} as USER5 on
505
        USER5.id = PLANETS5.id_owner
506
      " .
507
      // Блокировка всех юнитов, принадлежащих этой планете
508
      "LEFT JOIN {{unit}} as UNIT5 ON
509
        UNIT5.unit_location_type = " . LOC_PLANET . " AND
510
        UNIT5.unit_location_id = PLANETS5.id
511
      " .
512
513
514
      // Locking destination planet
515
      "LEFT JOIN {{planets}} AS PLANETS6 ON
516
        FLEET0.fleet_mess = 0 AND
517
        PLANETS6.galaxy = FLEET0.fleet_end_galaxy AND
518
        PLANETS6.system = FLEET0.fleet_end_system AND
519
        PLANETS6.planet = FLEET0.fleet_end_planet
520
      " .
521
      // Lock planet owner
522
      "LEFT JOIN {{users}} as USER6 on
523
        USER6.id = PLANETS6.id_owner
524
      " .
525
      // Блокировка всех юнитов, принадлежащих этой планете
526
      "LEFT JOIN {{unit}} as UNIT6 ON
527
        UNIT6.unit_location_type = " . LOC_PLANET . " AND
528
        UNIT6.unit_location_id = PLANETS6.id
529
      " .
530
      "WHERE FLEET0.fleet_id = {$dbId} GROUP BY 1 FOR UPDATE"
531
    );
532
  }
533
534
535
  public function dbRowParse($db_row) {
536
    parent::dbRowParse($db_row); // TODO: Change the autogenerated stub
537
    $player = new Player();
538
    $player->dbLoad($db_row['fleet_owner']);
539
    $this->setLocatedAt($player);
540
  }
541
542
  /* FLEET HELPERS =====================================================================================================*/
543
  /**
544
   * Forcibly returns fleet before time outs
545
   */
546
  public function commandReturn() {
547
    $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;
548
549
    $this->markReturned();
550
551
    // Считаем, что флот уже долетел TODO
552
    $this->time_arrive_to_target = SN_TIME_NOW;
553
    // Убираем флот из группы
554
    $this->group_id = 0;
555
    // Отменяем работу в точке назначения
556
    $this->time_mission_job_complete = 0;
557
    // TODO - правильно вычслять время возвращения - по проделанному пути, а не по старому времени возвращения
558
    $this->time_return_to_source = $ReturnFlyingTime;
559
560
    // Записываем изменения в БД
561
    $this->dbSave();
562
563
    if($this->_group_id) {
564
      // TODO: Make here to delete only one AKS - by adding aks_fleet_count to AKS table
565
      db_fleet_aks_purge();
566
    }
567
  }
568
569
570
  /**
571
   * @return array
572
   */
573
  public function target_coordinates_without_type() {
574
    return array(
575
      'galaxy' => $this->_fleet_end_galaxy,
576
      'system' => $this->_fleet_end_system,
577
      'planet' => $this->_fleet_end_planet,
578
    );
579
  }
580
581
  /**
582
   * @return array
583
   */
584
  public function target_coordinates_typed() {
585
    return array(
586
      'galaxy' => $this->_fleet_end_galaxy,
587
      'system' => $this->_fleet_end_system,
588
      'planet' => $this->_fleet_end_planet,
589
      'type'   => $this->_fleet_end_type,
590
    );
591
  }
592
593
  /**
594
   * @return array
595
   */
596
  public function launch_coordinates_typed() {
597
    return array(
598
      'galaxy' => $this->_fleet_start_galaxy,
599
      'system' => $this->_fleet_start_system,
600
      'planet' => $this->_fleet_start_planet,
601
      'type'   => $this->_fleet_start_type,
602
    );
603
  }
604
605
606
  /**
607
   * Sets object fields for fleet return
608
   */
609
  public function markReturned() {
610
    // TODO - Проверка - а не возвращается ли уже флот?
611
    $this->is_returning = 1;
612
  }
613
614
  public function isReturning() {
615
    return 1 == $this->_is_returning;
616
  }
617
618
  public function markReturnedAndSave() {
619
    $this->markReturned();
620
    $this->dbSave();
621
  }
622
623
  /**
624
   * Parses extended unit_array which can include not only ships but resources, captains etc
625
   *
626
   * @param $unit_array
627
   */
628
  // TODO - separate shipList and unitList
629
  public function unitsSetFromArray($unit_array) {
630
    if(empty($unit_array) || !is_array($unit_array)) {
631
      return;
632
    }
633
    foreach($unit_array as $unit_id => $unit_count) {
634
      $unit_count = floatval($unit_count);
635
      if(!$unit_count) {
636
        continue;
637
      }
638
639
      if($this->isShip($unit_id)) {
640
        $this->unitList->unitSetCount($unit_id, $unit_count);
641
      } elseif($this->isResource($unit_id)) {
642
        $this->resource_list[$unit_id] = $unit_count;
643
      } else {
644
        throw new Exception('Trying to pass to fleet non-resource and non-ship ' . var_export($unit_array, true), ERR_ERROR);
645
      }
646
    }
647
  }
648
649
650
  /**
651
   * Sets fleet timers based on flight duration, time on mission (HOLD/EXPLORE) and fleet departure time.
652
   *
653
   * @param int $time_to_travel - flight duration in seconds
654
   * @param int $time_on_mission - time on mission in seconds
655
   * @param int $group_sync_delta_time - delta time to adjust fleet arrival time if fleet is a part of group (i.e. ACS)
656
   * @param int $flight_departure - fleet departure from source planet timestamp. Allows to send fleet in future or in past
657
   */
658
  public function set_times($time_to_travel, $time_on_mission = 0, $group_sync_delta_time = 0, $flight_departure = SN_TIME_NOW) {
659
    $this->_time_launch = $flight_departure;
660
661
    $this->_time_arrive_to_target = $this->_time_launch + $time_to_travel + $group_sync_delta_time;
662
    $this->_time_mission_job_complete = $time_on_mission ? $this->_time_arrive_to_target + $time_on_mission : 0;
663
    $this->_time_return_to_source = ($this->_time_mission_job_complete ? $this->_time_mission_job_complete : $this->_time_arrive_to_target) + $time_to_travel;
664
  }
665
666
667
  public function parse_missile_db_row($missile_db_row) {
668
//    $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...
669
670
    if(empty($missile_db_row) || !is_array($missile_db_row)) {
671
      return;
672
    }
673
674
//      $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...
675
//      $irak_original['fleet_start_name'] = $planet_start['name'];
676
    $this->missile_target = $missile_db_row['primaer'];
677
678
    $this->_dbId = -$missile_db_row['id'];
679
    $this->_playerOwnerId = $missile_db_row['fleet_owner'];
680
    $this->_mission_type = MT_MISSILE;
681
682
    $this->_target_owner_id = $missile_db_row['fleet_target_owner'];
683
684
    $this->_group_id = 0;
685
    $this->_is_returning = 0;
686
687
    $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...
688
    $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...
689
    $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...
690
    $this->_time_return_to_source = $missile_db_row['fleet_end_time'];
691
692
    $this->_fleet_start_planet_id = !empty($missile_db_row['fleet_start_planet_id']) ? $missile_db_row['fleet_start_planet_id'] : null;
693
    $this->_fleet_start_galaxy = $missile_db_row['fleet_start_galaxy'];
694
    $this->_fleet_start_system = $missile_db_row['fleet_start_system'];
695
    $this->_fleet_start_planet = $missile_db_row['fleet_start_planet'];
696
    $this->_fleet_start_type = $missile_db_row['fleet_start_type'];
697
698
    $this->_fleet_end_planet_id = !empty($missile_db_row['fleet_end_planet_id']) ? $missile_db_row['fleet_end_planet_id'] : null;
699
    $this->_fleet_end_galaxy = $missile_db_row['fleet_end_galaxy'];
700
    $this->_fleet_end_system = $missile_db_row['fleet_end_system'];
701
    $this->_fleet_end_planet = $missile_db_row['fleet_end_planet'];
702
    $this->_fleet_end_type = $missile_db_row['fleet_end_type'];
703
704
    $this->unitList->unitSetCount(UNIT_DEF_MISSILE_INTERPLANET, $missile_db_row['fleet_amount']);
705
  }
706
707
708
  /**
709
   * @param $from
710
   */
711
  public function set_start_planet($from) {
712
    $this->fleet_start_planet_id = intval($from['id']) ? $from['id'] : null;
713
    $this->fleet_start_galaxy = $from['galaxy'];
714
    $this->fleet_start_system = $from['system'];
715
    $this->fleet_start_planet = $from['planet'];
716
    $this->fleet_start_type = $from['planet_type'];
717
  }
718
719
  /**
720
   * @param $to
721
   */
722
  public function set_end_planet($to) {
723
    $this->target_owner_id = intval($to['id_owner']) ? $to['id_owner'] : 0;
724
    $this->fleet_end_planet_id = intval($to['id']) ? $to['id'] : null;
725
    $this->fleet_end_galaxy = $to['galaxy'];
726
    $this->fleet_end_system = $to['system'];
727
    $this->fleet_end_planet = $to['planet'];
728
    $this->fleet_end_type = $to['planet_type'];
729
  }
730
731
  /**
732
   * @param Vector $to
733
   */
734
  public function setTargetFromVectorObject($to) {
735
    $this->_fleet_end_galaxy = $to->galaxy;
736
    $this->_fleet_end_system = $to->system;
737
    $this->_fleet_end_planet = $to->planet;
738
    $this->_fleet_end_type = $to->type;
739
  }
740
741
  /**
742
   * @param array $db_row
743
   */
744
  protected function ownerExtract(array &$db_row) {
745
    $player = new Player();
746
    $player->dbLoad($db_row['fleet_owner']);
747
    $this->setLocatedAt($player);
748
  }
749
750
  /**
751
   * @param array $db_row
752
   */
753
  protected function ownerInject(array &$db_row) {
754
    $db_row['fleet_owner'] = $this->getPlayerOwnerId();
755
  }
756
757
758
759
760
  // UnitList/Ships access ***************************************************************************************************
761
762
  // TODO - перекрывать пожже - для миссайл-флотов и дефенс-флотов
763
  protected function isShip($unit_id) {
764
    return UnitShip::is_in_group($unit_id);
765
  }
766
767
  /**
768
   * Set unit count of $unit_id to $unit_count
769
   * If there is no $unit_id - it will be created and saved to DB on dbSave
770
   *
771
   * @param int $unit_id
772
   * @param int $unit_count
773
   */
774
  public function shipSetCount($unit_id, $unit_count = 0) {
775
    $this->shipAdjustCount($unit_id, $unit_count, true);
776
  }
777
778
  /**
779
   * Adjust unit count of $unit_id by $unit_count - or just replace value
780
   * If there is no $unit_id - it will be created and saved to DB on dbSave
781
   *
782
   * @param int  $unit_id
783
   * @param int  $unit_count
784
   * @param bool $replace_value
785
   */
786
  public function shipAdjustCount($unit_id, $unit_count = 0, $replace_value = false) {
787
    $this->unitList->unitAdjustCount($unit_id, $unit_count, $replace_value);
788
  }
789
790
  public function shipGetCount($unit_id) {
791
    return $this->unitList->unitGetCount($unit_id);
792
  }
793
794
  public function shipsCountApplyLossMultiplier($ships_lost_multiplier) {
795
    $this->unitList->unitsCountApplyLossMultiplier($ships_lost_multiplier);
796
  }
797
798
  /**
799
   * Returns ship list in fleet
800
   */
801
  public function shipsGetArray() {
802
    return $this->unitList->unitsGetArray();
803
  }
804
805
  public function shipsGetTotal() {
806
    return $this->unitList->unitsCount();
807
  }
808
809
  public function shipsGetCapacity() {
810
    return $this->unitList->shipsCapacity();
811
  }
812
813
  public function shipsGetHoldFree() {
814
    return max(0, $this->shipsGetCapacity() - $this->resourcesGetTotal());
815
  }
816
817
  public function shipsGetTotalById($ship_id) {
818
    return $this->unitList->unitsCountById($ship_id);
819
  }
820
821
  /**
822
   * Возвращает ёмкость переработчиков во флоте
823
   *
824
   * @param array $recycler_info
825
   *
826
   * @return int
827
   *
828
   * @version 41a6.84
829
   */
830
  public function shipsGetCapacityRecyclers(array $recycler_info) {
831
    $recyclers_incoming_capacity = 0;
832
    $fleet_data = $this->shipsGetArray();
833
    foreach($recycler_info as $recycler_id => $recycler_data) {
834
      $recyclers_incoming_capacity += $fleet_data[$recycler_id] * $recycler_data['capacity'];
835
    }
836
837
    return $recyclers_incoming_capacity;
838
  }
839
840
  /**
841
   * Restores fleet or resources to planet
842
   *
843
   * @param bool $start
844
   * @param int  $result
845
   *
846
   * @return int
847
   */
848
  // TODO - split to functions
849
  public function shipsLand($start = true, &$result = CACHE_NOTHING) {
850
    sn_db_transaction_check(true);
851
852
    // Если флот уже обработан - не существует или возращается - тогда ничего не делаем
853
    if($this->isEmpty()) {
854
      return $result;
855
    }
856
857
    $coordinates = $start ? $this->launch_coordinates_typed() : $this->target_coordinates_typed();
858
859
    // Поскольку эта функция может быть вызвана не из обработчика флотов - нам надо всё заблокировать вроде бы НЕ МОЖЕТ!!!
860
    // TODO Проверить от многократного срабатывания !!!
861
    // Тут не блокируем пока - сначала надо заблокировать пользователя, что бы не было дедлока
862
    // TODO поменять на владельца планеты - когда его будут возвращать всегда !!!
863
864
    // Узнаем ИД владельца планеты.
865
    // С блокировкой, поскольку эта функция может быть вызвана только из менеджера летящих флотов.
866
    // А там уже всё заблокировано как надо и повторная блокировка не вызовет дедлок.
867
    $planet_arrival = db_planet_by_vector($coordinates, '', true);
868
    // Блокируем пользователя
869
    // TODO - вообще-то нам уже известен пользователь в МЛФ - так что можно просто передать его сюда
870
    $user = db_user_by_id($planet_arrival['id_owner'], true);
871
872
    // TODO - Проверка, что планета всё еще существует на указанных координатах, а не телепортировалась, не удалена хозяином, не уничтожена врагом
873
    // Флот, который возвращается на захваченную планету, пропадает
874
    // Ship landing is possible only to fleet owner's planet
875
    if($this->getPlayerOwnerId() == $planet_arrival['id_owner']) {
876
      $db_changeset = array();
877
878
      $fleet_array = $this->shipsGetArray();
879
      foreach($fleet_array as $ship_id => $ship_count) {
880
        if($ship_count) {
881
          $db_changeset['unit'][] = sn_db_unit_changeset_prepare($ship_id, $ship_count, $user, $planet_arrival['id']);
882
        }
883
      }
884
885
      // Adjusting ship amount on planet
886
      if(!empty($db_changeset)) {
887
        db_changeset_apply($db_changeset);
888
      }
889
890
      // Restoring resources to planet
891
      $this->resourcesUnload($start, $result);
892
    }
893
894
    $result = CACHE_FLEET | ($start ? CACHE_PLANET_SRC : CACHE_PLANET_DST);
895
896
    $result = RestoreFleetToPlanet($this, $start, $result);
897
898
    $this->dbDelete();
899
900
    return $result;
901
  }
902
903
904
  // Resources access ***************************************************************************************************
905
906
  /**
907
   * Extracts resources value from db_row
908
   *
909
   * @param array $db_row
910
   *
911
   * @internal param Fleet $that
912
   * @version 41a6.84
913
   */
914
  protected function resourcesExtract(array &$db_row) {
915
    $this->resource_list = array(
916
      RES_METAL     => !empty($db_row['fleet_resource_metal']) ? floor($db_row['fleet_resource_metal']) : 0,
917
      RES_CRYSTAL   => !empty($db_row['fleet_resource_crystal']) ? floor($db_row['fleet_resource_crystal']) : 0,
918
      RES_DEUTERIUM => !empty($db_row['fleet_resource_deuterium']) ? floor($db_row['fleet_resource_deuterium']) : 0,
919
    );
920
  }
921
922
  protected function resourcesInject(array &$db_row) {
923
    $db_row['fleet_resource_metal'] = $this->resource_list[RES_METAL];
924
    $db_row['fleet_resource_crystal'] = $this->resource_list[RES_CRYSTAL];
925
    $db_row['fleet_resource_deuterium'] = $this->resource_list[RES_DEUTERIUM];
926
  }
927
928
  /**
929
   * Set current resource list from array of units
930
   *
931
   * @param array $resource_list
932
   */
933
  public function resourcesSet($resource_list) {
934
    if(!empty($this->propertiesAdjusted['resource_list'])) {
935
      throw new PropertyAccessException('Property "resource_list" already was adjusted so no SET is possible until dbSave in ' . get_called_class() . '::unitSetResourceList', ERR_ERROR);
936
    }
937
    $this->resourcesAdjust($resource_list, true);
938
  }
939
940
  /**
941
   * Updates fleet resource list with deltas
942
   *
943
   * @param $resource_delta_list
944
   */
945
  public function resourcesAdjust($resource_delta_list, $replace_value = false) {
946
    !is_array($resource_delta_list) ? $resource_delta_list = array() : false;
947
948
    foreach($resource_delta_list as $resource_id => $unit_delta) {
949
      if(!UnitResourceLoot::is_in_group($resource_id) || !($unit_delta = floor($unit_delta))) {
950
        // Not a resource or no resources - continuing
951
        continue;
952
      }
953
954
      if($replace_value) {
955
        $this->resource_list[$resource_id] = $unit_delta;
956
      } else {
957
        $this->resource_list[$resource_id] += $unit_delta;
958
        // Preparing changes
959
        $this->resource_delta[$resource_id] += $unit_delta;
960
        $this->propertiesAdjusted['resource_list'] = 1;
961
      }
962
963
      // Check for negative unit value
964
      if($this->resource_list[$resource_id] < 0) {
965
        // TODO
966
        throw new Exception('Resource ' . $resource_id . ' will become negative in ' . get_called_class() . '::unitAdjustResourceList', ERR_ERROR);
967
      }
968
    }
969
  }
970
971
  public function resourcesGetTotal() {
972
    return empty($this->resource_list) || !is_array($this->resource_list) ? 0 : array_sum($this->resource_list);
973
  }
974
975
  /**
976
   * @param array $rate
977
   *
978
   * @return float
979
   */
980
  public function resourcesGetTotalInMetal(array $rate) {
981
    return
982
      $this->resource_list[RES_METAL] * $rate[RES_METAL]
983
      + $this->resource_list[RES_CRYSTAL] * $rate[RES_CRYSTAL] / $rate[RES_METAL]
984
      + $this->resource_list[RES_DEUTERIUM] * $rate[RES_DEUTERIUM] / $rate[RES_METAL];
985
  }
986
987
  /**
988
   * Returns resource list in fleet
989
   */
990
  // TODO
991
  public function resourcesGetList() {
992
    return $this->resource_list;
993
  }
994
995
  public function resourcesReset() {
996
    $this->resourcesSet(array(
997
      RES_METAL     => 0,
998
      RES_CRYSTAL   => 0,
999
      RES_DEUTERIUM => 0,
1000
    ));
1001
  }
1002
1003
  /**
1004
   * Restores fleet or resources to planet
1005
   *
1006
   * @param bool $start
1007
   * @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...
1008
   * @param int  $result
1009
   *
1010
   * @return int
1011
   */
1012
  public function resourcesUnload($start = true, &$result = CACHE_NOTHING) {
1013
    sn_db_transaction_check(true);
1014
1015
    // Если флот уже обработан - не существует или возращается - тогда ничего не делаем
1016
    if(!$this->resourcesGetTotal()) {
1017
      return $result;
1018
    }
1019
1020
    $coordinates = $start ? $this->launch_coordinates_typed() : $this->target_coordinates_typed();
1021
1022
    // Поскольку эта функция может быть вызвана не из обработчика флотов - нам надо всё заблокировать вроде бы НЕ МОЖЕТ!!!
1023
    // TODO Проверить от многократного срабатывания !!!
1024
    // Тут не блокируем пока - сначала надо заблокировать пользователя, что бы не было дедлока
1025
    // TODO поменять на владельца планеты - когда его будут возвращать всегда !!!
1026
1027
1028
    // Узнаем ИД владельца планеты.
1029
    // С блокировкой, поскольку эта функция может быть вызвана только из менеджера летящих флотов.
1030
    // А там уже всё заблокировано как надо и повторная блокировка не вызовет дедлок.
1031
    $planet_arrival = db_planet_by_vector($coordinates, '', true);
1032
1033
    // TODO - Проверка, что планета всё еще существует на указанных координатах, а не телепортировалась, не удалена хозяином, не уничтожена врагом
1034
1035
    // Restoring resources to planet
1036
    if($this->resourcesGetTotal()) {
1037
      $fleet_resources = $this->resourcesGetList();
1038
      db_planet_set_by_id($planet_arrival['id'],
1039
        "`metal` = `metal` + '{$fleet_resources[RES_METAL]}', `crystal` = `crystal` + '{$fleet_resources[RES_CRYSTAL]}', `deuterium` = `deuterium` + '{$fleet_resources[RES_DEUTERIUM]}'");
1040
    }
1041
1042
    $this->resourcesReset();
1043
    $this->markReturned();
1044
1045
    $result = CACHE_FLEET | ($start ? CACHE_PLANET_SRC : CACHE_PLANET_DST);
1046
1047
    return $result;
1048
  }
1049
1050
1051
  protected function isResource($unit_id) {
1052
    return UnitResourceLoot::is_in_group($unit_id);
1053
  }
1054
1055
  /**
1056
   * @param int $speed_percent
1057
   *
1058
   * @return array
1059
   */
1060
  protected function flt_travel_data($speed_percent = 10) {
1061
    $distance = $this->targetVector->distanceFromCoordinates($this->dbSourcePlanetRow);
1062
1063
    return $this->unitList->travelData($speed_percent, $distance, $this->dbOwnerRow);
1064
  }
1065
1066
1067
  /**
1068
   * @param array  $dbPlayerRow
1069
   * @param array  $dbPlanetRow
1070
   * @param Vector $targetVector
1071
   *
1072
   */
1073
  public function initDefaults($dbPlayerRow, $dbPlanetRow, $targetVector, $mission, $ships, $fleet_group_mr, $oldSpeedInTens) {
1074
    $objFleet5Player = new Player();
1075
    $objFleet5Player->dbRowParse($dbPlayerRow);
1076
    $this->setLocatedAt($objFleet5Player);
1077
1078
    $this->mission_type = $mission;
1079
1080
    $this->dbOwnerRow = $dbPlayerRow;
1081
1082
    $this->set_start_planet($dbPlanetRow);
1083
    $this->dbSourcePlanetRow = $dbPlanetRow;
1084
1085
    $this->setTargetFromVectorObject($targetVector);
1086
    $this->targetVector = $targetVector;
1087
1088
    $this->populateTargetPlanet();
1089
1090
    $this->unitsSetFromArray($ships);
1091
1092
    $this->_group_id = $fleet_group_mr;
1093
1094
    $this->oldSpeedInTens = $oldSpeedInTens;
1095
1096
    $this->fleetPage0Prepare();
1097
1098
  }
1099
1100
  protected function populateTargetPlanet() {
1101
    $targetPlanetCoords = $this->targetVector;
1102
    if($this->mission_type != MT_NONE) {
1103
      $this->restrictTargetTypeByMission();
1104
1105
      // TODO - Нельзя тут просто менять тип планеты или координат!
1106
      // If current planet type is not allowed on mission - switch planet type
1107
      if(empty($this->allowed_planet_types[$this->targetVector->type])) {
1108
        $targetPlanetCoords->type = reset($this->allowed_planet_types);
1109
      }
1110
    }
1111
1112
    $this->dbTargetRow = db_planet_by_vector_object($targetPlanetCoords);
1113
  }
1114
1115
  protected function restrictTargetTypeByMission() {
1116
    if($this->_mission_type == MT_MISSILE) {
1117
      $this->allowed_planet_types = array(PT_PLANET => PT_PLANET);
1118
    } elseif($this->_mission_type == MT_COLONIZE || $this->_mission_type == MT_EXPLORE) {
1119
      // TODO - PT_NONE
1120
      $this->allowed_planet_types = array(PT_PLANET => PT_PLANET);
1121
    } elseif($this->_mission_type == MT_RECYCLE) {
1122
      $this->allowed_planet_types = array(PT_DEBRIS => PT_DEBRIS);
1123
    } elseif($this->_mission_type == MT_DESTROY) {
1124
      $this->allowed_planet_types = array(PT_MOON => PT_MOON);
1125
    } else {
1126
      $this->allowed_planet_types = array(PT_PLANET => PT_PLANET, PT_MOON => PT_MOON);
1127
    }
1128
  }
1129
1130
  /**
1131
   */
1132
  public function fleetPage0Prepare() {
1133
    global $template_result;
1134
    $template_result += array(
1135
      'thisgalaxy'      => $this->dbSourcePlanetRow['galaxy'],
1136
      'thissystem'      => $this->dbSourcePlanetRow['system'],
1137
      'thisplanet'      => $this->dbSourcePlanetRow['planet'],
1138
      'thisplanet_type' => $this->dbSourcePlanetRow['planet_type'],
1139
1140
      'galaxy'         => $this->targetVector->galaxy,
1141
      'system'         => $this->targetVector->system,
1142
      'planet'         => $this->targetVector->planet,
1143
      'planet_type'    => $this->targetVector->type,
1144
      'target_mission' => $this->_mission_type,
1145
      'MISSION_NAME'   => $this->_mission_type ? classLocale::$lang['type_mission'][$this->_mission_type] : '',
1146
1147
      'MT_COLONIZE' => MT_COLONIZE,
1148
    );
1149
1150
//    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...
1151
  }
1152
1153
1154
  public function restrictToKnownSpace() {
1155
    if(!$this->targetVector->isInKnownSpace()) {
1156
      throw new Exception('FLIGHT_VECTOR_BEYOND_SYSTEM', FLIGHT_VECTOR_BEYOND_SYSTEM);
1157
    }
1158
  }
1159
1160
  public function restrictToTypePlanet($errorCode) {
1161
    if($this->targetVector->type != PT_PLANET) {
1162
      throw new Exception($errorCode, $errorCode);
1163
    }
1164
  }
1165
1166
  public function restrictToNoMissiles() {
1167
    $missilesAttack = $this->unitList->unitsCountById(UNIT_DEF_MISSILE_INTERPLANET);
1168
    $missilesDefense = $this->unitList->unitsCountById(UNIT_DEF_MISSILE_INTERCEPTOR);
1169
    if($missilesAttack > 0 || $missilesDefense > 0) {
1170
      throw new Exception('FLIGHT_SHIPS_NO_MISSILES', FLIGHT_SHIPS_NO_MISSILES);
1171
    }
1172
  }
1173
1174
  public function restrictToTargetOwn() {
1175
    if($this->dbTargetRow['id'] != $this->getPlayerOwnerId()) {
1176
      throw new Exception('FLIGHT_VECTOR_ONLY_OWN', FLIGHT_VECTOR_ONLY_OWN);
1177
    }
1178
  }
1179
1180
  public function restrictToTargetOther() {
1181
    if($this->dbTargetRow['id'] == $this->getPlayerOwnerId()) {
1182
      throw new Exception('FLIGHT_VECTOR_ONLY_OTHER', FLIGHT_VECTOR_ONLY_OTHER);
1183
    }
1184
  }
1185
1186
  public function restrictToNotOnlySpies() {
1187
    if($this->unitList->unitsCountById(SHIP_SPY) == $this->shipsGetTotal()) {
1188
      throw new Exception('FLIGHT_SHIPS_NOT_ONLY_SPIES', FLIGHT_SHIPS_NOT_ONLY_SPIES);
1189
    }
1190
  }
1191
1192
  protected function restrictToUniverse() {
1193
    if(!$this->targetVector->isInUniverse()) {
1194
      throw new Exception('FLIGHT_VECTOR_BEYOND_UNIVERSE', FLIGHT_VECTOR_BEYOND_UNIVERSE);
1195
    }
1196
  }
1197
1198
  protected function restrictToMovable() {
1199
    if(!$this->unitList->unitsIsAllMovable($this->dbOwnerRow)) {
1200
      throw new Exception('FLIGHT_SHIPS_UNMOVABLE', FLIGHT_SHIPS_UNMOVABLE);
1201
    }
1202
  }
1203
1204
  protected function restrictToFleetUnits() {
1205
    if(!$this->unitList->unitsInGroup(sn_get_groups(array('fleet', 'missile')))) {
1206
      throw new Exception('FLIGHT_SHIPS_UNIT_WRONG', FLIGHT_SHIPS_UNIT_WRONG);
1207
    }
1208
  }
1209
1210
  protected function restrictToColonizer() {
1211
    // Colonization fleet should have at least one colonizer
1212
    if(!$this->unitList->unitsCountById(SHIP_COLONIZER) <= 0) {
1213
      throw new Exception('FLIGHT_SHIPS_NO_COLONIZER', FLIGHT_SHIPS_NO_COLONIZER);
1214
    }
1215
  }
1216
1217
  protected function restrictToTargetExists() {
1218
    if(empty($this->dbTargetRow) || empty($this->dbTargetRow['id'])) {
1219
      throw new Exception('FLIGHT_VECTOR_NO_TARGET', FLIGHT_VECTOR_NO_TARGET);
1220
    }
1221
  }
1222
1223
1224 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...
1225
    // Is it exploration - fleet sent beyond of system?
1226
    if($this->targetVector->isInKnownSpace()) {
1227
      // No exploration beyond this point
1228
      unset($this->allowed_missions[MT_EXPLORE]);
1229
1230
      $this->restrictToKnownSpace();
1231
1232
      return;
1233
    }
1234
    $this->restrictToNotOnlySpies();
1235
    $this->restrictToNoMissiles();
1236
1237
    $this->allowed_missions = array(MT_EXPLORE => MT_EXPLORE,);
1238
1239
    throw new Exception('FLIGHT_ALLOWED', FLIGHT_ALLOWED);
1240
  }
1241
1242 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...
1243
    // Is it colonization - fleet sent to empty place?
1244
    if(!empty($this->dbTargetRow)) {
1245
      // No colonization beyond this point
1246
      unset($this->allowed_missions[MT_COLONIZE]);
1247
1248
      $this->restrictToTargetExists();
1249
1250
      return;
1251
    }
1252
    // Only planet can be destination for colonization
1253
    $this->restrictToTypePlanet(FLIGHT_MISSION_COLONIZE_NOT_PLANET);
1254
    $this->restrictToColonizer();
1255
    $this->restrictToNoMissiles();
1256
1257
    $this->allowed_missions = array(MT_COLONIZE => MT_COLONIZE,);
1258
1259
    throw new Exception('FLIGHT_ALLOWED', FLIGHT_ALLOWED);
1260
  }
1261
1262
  protected function restrictNotDebrisOrMissionRecycle() {
1263
    if($this->targetVector->type != PT_DEBRIS) {
1264
      // No recycling beyond this point
1265
      unset($this->allowed_missions[MT_RECYCLE]);
1266
1267
      return;
1268
    }
1269
1270
    $this->restrictToNoMissiles();
1271
1272
    // restrict to recyclers
1273
    $recyclers = 0;
1274
    foreach(sn_get_groups('flt_recyclers') as $recycler_id) {
1275
      $recyclers += $this->unitList->unitsCountById($recycler_id);
1276
    }
1277
1278
    if($recyclers <= 0) {
1279
      throw new Exception('FLIGHT_SHIPS_NO_RECYCLERS', FLIGHT_SHIPS_NO_RECYCLERS);
1280
    }
1281
1282
    $this->allowed_missions = array(MT_RECYCLE => MT_RECYCLE,);
1283
1284
    throw new Exception('FLIGHT_ALLOWED', FLIGHT_ALLOWED);
1285
  }
1286
1287
  protected function restrictMissionMissile() {
1288
    $missilesAttack = $this->unitList->unitsCountById(UNIT_DEF_MISSILE_INTERPLANET);
1289
    if($missilesAttack <= 0) {
1290
      // No missile attack beyond this point
1291
      unset($this->allowed_missions[MT_MISSILE]);
1292
1293
      return;
1294
    }
1295
1296
    if($missilesAttack != $this->shipsGetTotal()) {
1297
      throw new Exception('FLIGHT_SHIPS_ONLY_MISSILES', FLIGHT_SHIPS_ONLY_MISSILES);
1298
    }
1299
1300
    $this->restrictToTypePlanet(FLIGHT_MISSION_MISSILE_ONLY_PLANET);
1301
    $this->restrictToTargetOther();
1302
1303
    $this->allowed_missions = array(MT_MISSILE => MT_MISSILE,);
1304
    throw new Exception('FLIGHT_ALLOWED', FLIGHT_ALLOWED);
1305
  }
1306
1307 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...
1308
    if($this->unitList->unitsCountById(SHIP_SPY) != $this->shipsGetTotal()) {
1309
//      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...
1310
      unset($this->allowed_missions[MT_SPY]);
1311
1312
      $this->restrictToNotOnlySpies();
1313
1314
      return;
1315
    }
1316
1317
    $this->allowed_missions = array(MT_SPY => MT_SPY,);
1318
    throw new Exception('FLIGHT_ALLOWED', FLIGHT_ALLOWED);
1319
  }
1320
1321
  protected function restrictMissionDestroy() {
1322
    // If target vector is not Moon - then it can't be Destroy mission
1323
    // If no Reapers (i.e. Death Star) in fleet - then mission Moon Destroy is unaccessible
1324
    if($this->targetVector->type != PT_MOON || $this->unitList->unitsCountById(SHIP_HUGE_DEATH_STAR) <= 0) {
1325
      unset($this->allowed_missions[MT_DESTROY]);
1326
    }
1327
  }
1328
1329
  protected function restrictMissionACS() {
1330
    // If no ACS group is shown - then it can't be an ACS attack
1331
    if(empty($this->_group_id)) {
1332
      unset($this->allowed_missions[MT_ACS]);
1333
    }
1334
  }
1335
1336
  /** @throws Exception */
1337
  protected function restrictFriendOrFoe() {
1338
    // Checking target owner
1339 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...
1340
      // Spying can't be done on owner's planet/moon
1341
      unset($this->allowed_missions[MT_SPY]);
1342
      // Attack can't be done on owner's planet/moon
1343
      unset($this->allowed_missions[MT_ATTACK]);
1344
      // ACS can't be done on owner's planet/moon
1345
      unset($this->allowed_missions[MT_ACS]);
1346
      // Destroy can't be done on owner's moon
1347
      unset($this->allowed_missions[MT_DESTROY]);
1348
1349
      $this->restrictToNoMissiles();
1350
1351
      // MT_RELOCATE
1352
      // No checks
1353
      // TODO - check captain
1354
1355
      // MT_HOLD
1356
      // TODO - Check for Allies Deposit for HOLD
1357
1358
      // MT_TRANSPORT
1359
1360
    } else {
1361
      // Relocate can be done only on owner's planet/moon
1362
      unset($this->allowed_missions[MT_RELOCATE]);
1363
1364
      // TODO - check for moratorium
1365
1366
      // MT_HOLD
1367
      // TODO - Check for Allies Deposit for HOLD
1368
      // TODO - Noob protection for HOLD depends on server settings
1369
1370
      // MT_SPY
1371
      $this->restrictToNotOnlySpiesOrMissionSpy();
1372
1373
      // TODO - check noob protection
1374
1375
      // TODO - check bashing
1376
1377
      // No missions except MT_MISSILE should have any missiles in fleet
1378
      $this->restrictMissionMissile();
1379
      $this->restrictToNoMissiles();
1380
      // Beyond this point no mission can have a missile in fleet
1381
1382
      // MT_DESTROY
1383
      $this->restrictMissionDestroy();
1384
1385
      // MT_ACS
1386
      $this->restrictMissionACS();
1387
1388
      // MT_ATTACK - no checks
1389
1390
      // MT_TRANSPORT - no checks
1391
    }
1392
  }
1393
1394
  protected function restrictToNotSource() {
1395
    if($this->targetVector->isEqualToPlanet($this->dbSourcePlanetRow)) {
1396
      throw new Exception('FLIGHT_VECTOR_SAME_SOURCE', FLIGHT_VECTOR_SAME_SOURCE);
1397
    }
1398
  }
1399
1400
  protected function restrictToNonVacationSender() {
1401
    if(!empty($this->dbOwnerRow['vacation']) && $this->dbOwnerRow['vacation'] >= SN_TIME_NOW) {
1402
      throw new Exception('FLIGHT_PLAYER_VACATION_OWN', FLIGHT_PLAYER_VACATION_OWN);
1403
    }
1404
  }
1405
1406
  protected function restrictToValidSpeedPercentOld() {
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) {
1439
    if(floor($fleetCapacity) < ceil(array_sum($this->resource_list) + $fleetConsumption)) {
1440
      throw new Exception('FLIGHT_FLEET_OVERLOAD', FLIGHT_FLEET_OVERLOAD);
1441
    }
1442
  }
1443
1444
  protected function restrict2ByResources($fleetConsumption) {
1445
    $fleetResources = $this->resource_list;
1446
    $fleetResources[RES_DEUTERIUM] = ceil($fleetResources[RES_DEUTERIUM] + $fleetConsumption);
1447
    foreach($fleetResources as $resourceId => $resourceAmount) {
1448
      if($fleetResources[$resourceId] < 0) {
1449
        throw new Exception('FLIGHT_RESOURCES_NEGATIVE', FLIGHT_RESOURCES_NEGATIVE);
1450
      }
1451
1452
      if(mrc_get_level($this->dbOwnerRow, $this->dbSourcePlanetRow, $resourceId) < ceil($fleetResources[$resourceId])) {
1453
        if($resourceId == RES_DEUTERIUM) {
1454
          throw new Exception('FLIGHT_RESOURCES_FUEL_NOT_ENOUGH', FLIGHT_RESOURCES_FUEL_NOT_ENOUGH);
1455
        } else {
1456
          throw new Exception('FLIGHT_RESOURCES_NOT_ENOUGH', FLIGHT_RESOURCES_NOT_ENOUGH);
1457
        }
1458
      }
1459
    }
1460
  }
1461
1462
  /**
1463
   * Restricts mission availability internally w/o DB access
1464
   *
1465
   * @throws Exception
1466
   */
1467
  public function restrictMission() {
1468
    // Only "cheap" checks that didn't require to query DB
1469
1470
1471
    // Check for valid percent speed value
1472
    $this->restrictToValidSpeedPercentOld();
1473
1474
    // Player in Vacation can't send fleets
1475
    $this->restrictToNonVacationSender();
1476
1477
    // Fleet source and destination can't be the same
1478
    $this->restrictToNotSource();
1479
1480
    // No mission could fly beyond Universe - i.e. with wrong Galaxy and/or System coordinates
1481
    $this->restrictToUniverse();
1482
1483
    // Only ships and missiles can be sent to mission
1484
    $this->restrictToFleetUnits();
1485
    // Only units with main engines (speed >=0) can fly - no other units like satellites
1486
    $this->restrictToMovable();
1487
1488
    // No missions except MT_EXPLORE could target coordinates beyond known system
1489
    $this->restrictKnownSpaceOrMissionExplore();
1490
    // Beyond this point all mission address only known space
1491
1492
    // No missions except MT_COLONIZE could target empty coordinates
1493
    $this->restrictTargetExistsOrMissionColonize();
1494
    // Beyond this point all mission address only existing planets/moons
1495
1496
    // No missions except MT_RECYCLE could target debris
1497
    $this->restrictNotDebrisOrMissionRecycle();
1498
    // Beyond this point targets can be only PT_PLANET or PT_MOON
1499
1500
    // TODO - later then
1501
    $this->restrictFriendOrFoe();
1502
  }
1503
1504
1505
  protected function printErrorIfNoShips() {
1506
    if($this->unitList->unitsCount() <= 0) {
1507
      message(classLocale::$lang['fl_err_no_ships'], classLocale::$lang['fl_error'], 'fleet' . DOT_PHP_EX, 5);
1508
    }
1509
  }
1510
1511
  /**
1512
   * @param array $template_result
1513
   *
1514
   * @throws Exception
1515
   */
1516
  protected function renderFleet(&$template_result) {
1517
    $this->printErrorIfNoShips();
1518
1519
    $tplShips = $this->unitList->unitsRender();
1520
    $template_result['.']['fleets'][] = array(
1521
      'START_TYPE_TEXT_SH' => classLocale::$lang['sys_planet_type_sh'][$this->dbSourcePlanetRow['planet_type']],
1522
      'START_COORDS'       => uni_render_coordinates($this->dbSourcePlanetRow),
1523
      'START_NAME'         => $this->dbSourcePlanetRow['name'],
1524
      'END_TYPE_TEXT_SH'   =>
1525
        !empty($this->targetVector->type)
1526
          ? classLocale::$lang['sys_planet_type_sh'][$this->targetVector->type]
1527
          : '',
1528
      'END_COORDS'         => uniRenderVector($this->targetVector),
1529
      'END_NAME'           => !empty($this->dbTargetRow['name']) ? $this->dbTargetRow['name'] : '',
1530
      '.'                  => array(
1531
        'ships' => $tplShips,
1532
      ),
1533
    );
1534
  }
1535
1536
  /**
1537
   * @param array $template_result
1538
   *
1539
   * @return array
1540
   */
1541
  protected function renderAllowedMissions(&$template_result) {
1542
    ksort($this->allowed_missions);
1543
    // If mission is not set - setting first mission from allowed
1544
    if(empty($this->_mission_type) && is_array($this->allowed_missions)) {
1545
      $this->_mission_type = reset($this->allowed_missions);
1546
    }
1547
    foreach($this->allowed_missions as $key => $value) {
1548
      $template_result['.']['missions'][] = array(
1549
        'ID'   => $key,
1550
        'NAME' => classLocale::$lang['type_mission'][$key],
1551
      );
1552
    };
1553
  }
1554
1555
  /**
1556
   * @param $template_result
1557
   */
1558
  protected function renderDuration(&$template_result, $max_duration) {
1559
    if($max_duration) {
1560
      $config_game_speed_expedition = ($this->_mission_type == MT_EXPLORE && classSupernova::$config->game_speed_expedition ? classSupernova::$config->game_speed_expedition : 1);
1561
      for($i = 1; $i <= $max_duration; $i++) {
1562
        $template_result['.']['duration'][] = array(
1563
          'ID'   => $i,
1564
          'TIME' => pretty_time(ceil($i * 3600 / $config_game_speed_expedition)),
1565
        );
1566
      }
1567
    }
1568
  }
1569
1570
  /**
1571
   * @param array $planetResources
1572
   * @param array &$template_result
1573
   */
1574
  protected function renderPlanetResources(&$planetResources, &$template_result) {
1575
    // TODO - REDO to resource_id
1576
    $i = 0;
1577
    foreach($planetResources as $resource_id => $resource_amount) {
1578
      $template_result['.']['resources'][] = array(
1579
        'ID'        => $i++, // $resource_id,
1580
        'ON_PLANET' => $resource_amount,
1581
        'TEXT'      => pretty_number($resource_amount),
1582
        'NAME'      => classLocale::$lang['tech'][$resource_id],
1583
      );
1584
    }
1585
  }
1586
1587
  /**
1588
   * @param $template_result
1589
   */
1590
  protected function renderAllowedPlanetTypes(&$template_result) {
1591
    foreach($this->allowed_planet_types as $possible_planet_type_id) {
1592
      $template_result['.']['possible_planet_type_id'][] = array(
1593
        'ID'         => $possible_planet_type_id,
1594
        'NAME'       => classLocale::$lang['sys_planet_type'][$possible_planet_type_id],
1595
        'NAME_SHORT' => classLocale::$lang['sys_planet_type_sh'][$possible_planet_type_id],
1596
      );
1597
    }
1598
  }
1599
1600
  protected function renderFleet1TargetSelect(&$shortcut) {
1601
    global $note_priority_classes;
1602
1603
    $name = !empty($shortcut['title']) ? $shortcut['title'] : $shortcut['name'];
1604
1605
    $result = array(
1606
      'NAME'       => $name,
1607
      'GALAXY'     => $shortcut['galaxy'],
1608
      'SYSTEM'     => $shortcut['system'],
1609
      'PLANET'     => $shortcut['planet'],
1610
      'TYPE'       => $shortcut['planet_type'],
1611
      'TYPE_PRINT' => classLocale::$lang['fl_shrtcup'][$shortcut['planet_type']],
1612
    );
1613
1614
    if(isset($shortcut['priority'])) {
1615
      $result += array(
1616
        'PRIORITY'       => $shortcut['priority'],
1617
        'PRIORITY_CLASS' => $note_priority_classes[$shortcut['priority']],
1618
      );
1619
    }
1620
1621
    if(isset($shortcut['id'])) {
1622
      $result += array(
1623
        'ID' => $shortcut['id'],
1624
      );
1625
    }
1626
1627
    return $result;
1628
  }
1629
1630
  /**
1631
   * @param $template_result
1632
   */
1633
  protected function renderFleetShortcuts(&$template_result) {
1634
    // Building list of shortcuts
1635
    $query = db_note_list_select_by_owner_and_planet($this->dbOwnerRow);
1636
    while($row = db_fetch($query)) {
1637
      $template_result['.']['shortcut'][] = $this->renderFleet1TargetSelect($row);
1638
    }
1639
  }
1640
1641
  /**
1642
   * Building list of own planets & moons
1643
   *
1644
   * @param $template_result
1645
   */
1646
  protected function renderOwnPlanets(&$template_result) {
1647
    $colonies = db_planet_list_sorted($this->dbOwnerRow);
1648
    if(count($colonies) <= 1) {
1649
      return;
1650
    }
1651
1652
    foreach($colonies as $row) {
1653
      if($row['id'] == $this->dbSourcePlanetRow['id']) {
1654
        continue;
1655
      }
1656
1657
      $template_result['.']['colonies'][] = $this->renderFleet1TargetSelect($row);
1658
    }
1659
  }
1660
1661
  /**
1662
   * @param $template_result
1663
   */
1664
  protected function renderACSList(&$template_result) {
1665
    $query = db_acs_get_list();
1666
    while($row = db_fetch($query)) {
1667
      $members = explode(',', $row['eingeladen']);
1668
      foreach($members as $a => $b) {
1669
        if($b == $this->dbOwnerRow['id']) {
1670
          $template_result['.']['acss'][] = $this->renderFleet1TargetSelect($row);
1671
        }
1672
      }
1673
    }
1674
  }
1675
1676
  /**
1677
   * @param $template_result
1678
   */
1679
  protected function renderShipSortOptions(&$template_result) {
1680
    foreach(classLocale::$lang['player_option_fleet_ship_sort'] as $sort_id => $sort_text) {
1681
      $template_result['.']['ship_sort_list'][] = array(
1682
        'VALUE' => $sort_id,
1683
        'TEXT'  => $sort_text,
1684
      );
1685
    }
1686
    $template_result += array(
1687
      'FLEET_SHIP_SORT'         => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_SORT],
1688
      'FLEET_SHIP_SORT_INVERSE' => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_SORT_INVERSE],
1689
    );
1690
  }
1691
1692
  /**
1693
   */
1694
  public function fleetPage0() {
1695
    global $template_result;
1696
1697
    lng_include('overview');
1698
1699
    if(empty($this->dbSourcePlanetRow)) {
1700
      message(classLocale::$lang['fl_noplanetrow'], classLocale::$lang['fl_error']);
1701
    }
1702
1703
    // TODO - redo to unitlist render/unit render
1704
    $this->renderAvailableShips($template_result, $this->dbOwnerRow, $this->dbSourcePlanetRow);
1705
1706
    $this->renderShipSortOptions($template_result);
1707
1708
    /**
1709
     * @var Player $playerOwner
1710
     */
1711
    $playerOwner = $this->getLocatedAt();
1712
1713
    $template_result += array(
1714
      'FLYING_FLEETS'      => $playerOwner->fleetsFlying(),
1715
      'MAX_FLEETS'         => $playerOwner->fleetsMax(),
1716
      'FREE_FLEETS'        => $playerOwner->fleetsMax() - $playerOwner->fleetsFlying(),
1717
      'FLYING_EXPEDITIONS' => $playerOwner->expeditionsFlying(),
1718
      'MAX_EXPEDITIONS'    => $playerOwner->expeditionsMax(),
1719
      'FREE_EXPEDITIONS'   => $playerOwner->expeditionsMax() - $playerOwner->expeditionsFlying(),
1720
      'COLONIES_CURRENT'   => $playerOwner->coloniesCurrent(),
1721
      'COLONIES_MAX'       => $playerOwner->coloniesMax(),
1722
1723
      'TYPE_NAME' => classLocale::$lang['fl_planettype'][$this->targetVector->type],
1724
1725
      'speed_factor' => flt_server_flight_speed_multiplier(),
1726
1727
      'PLANET_RESOURCES' => pretty_number($this->dbSourcePlanetRow['metal'] + $this->dbSourcePlanetRow['crystal'] + $this->dbSourcePlanetRow['deuterium']),
1728
      'PLANET_DEUTERIUM' => pretty_number($this->dbSourcePlanetRow['deuterium']),
1729
1730
      'PLAYER_OPTION_FLEET_SHIP_SELECT_OLD'       => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_SELECT_OLD],
1731
      'PLAYER_OPTION_FLEET_SHIP_HIDE_SPEED'       => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_HIDE_SPEED],
1732
      'PLAYER_OPTION_FLEET_SHIP_HIDE_CAPACITY'    => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_HIDE_CAPACITY],
1733
      'PLAYER_OPTION_FLEET_SHIP_HIDE_CONSUMPTION' => classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_HIDE_CONSUMPTION],
1734
    );
1735
1736
    $template = gettemplate('fleet0', true);
1737
    $template->assign_recursive($template_result);
1738
    display($template, classLocale::$lang['fl_title']);
1739
  }
1740
1741
  public function fleetPage1() {
1742
    global $template_result;
1743
1744
    $this->renderFleet($template_result);
1745
1746
    $this->renderAllowedPlanetTypes($template_result);
1747
1748
    $this->renderOwnPlanets($template_result);
1749
1750
    $this->renderFleetShortcuts($template_result);
1751
1752
    $this->renderACSList($template_result);
1753
1754
    $template_result += array(
1755
      'speed_factor' => flt_server_flight_speed_multiplier(),
1756
1757
      'fleet_speed'    => flt_fleet_speed($this->dbOwnerRow, $this->shipsGetArray()),
1758
      'fleet_capacity' => $this->shipsGetCapacity(),
1759
1760
      'PLANET_DEUTERIUM' => pretty_number($this->dbSourcePlanetRow['deuterium']),
1761
1762
      'PAGE_HINT' => classLocale::$lang['fl_page1_hint'],
1763
    );
1764
1765
    $template = gettemplate('fleet1', true);
1766
    $template->assign_recursive($template_result);
1767
    display($template, classLocale::$lang['fl_title']);
1768
  }
1769
1770
  public function fleetPage2() {
1771
    global $template_result;
1772
1773
    try {
1774
      $this->restrictMission();
1775
    } catch(Exception $e) {
1776
      // TODO - MESSAGE BOX
1777 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...
1778
        pdie(classLocale::$lang['fl_attack_error'][$e->getCode()]);
1779
      } else {
1780
        pdump('FLIGHT_ALLOWED', FLIGHT_ALLOWED);
1781
      }
1782
    }
1783
1784
    $this->renderAllowedMissions($template_result);
1785
    $this->renderFleet($template_result);
1786
1787
    $max_duration = $this->_mission_type == MT_EXPLORE ? get_player_max_expedition_duration($this->dbOwnerRow) :
1788
      (isset($this->allowed_missions[MT_HOLD]) ? 12 : 0);
1789
    $this->renderDuration($template_result, $max_duration);
1790
1791
    $travel_data = $this->flt_travel_data($this->oldSpeedInTens);
1792
1793
    $sn_group_resources = sn_get_groups('resources_loot');
1794
    $planetResources = array();
1795
    foreach($sn_group_resources as $resource_id) {
1796
      $planetResources[$resource_id] = floor(mrc_get_level($this->dbOwnerRow, $this->dbSourcePlanetRow, $resource_id) - ($resource_id == RES_DEUTERIUM ? $travel_data['consumption'] : 0));
1797
    }
1798
    $this->renderPlanetResources($planetResources, $template_result);
1799
1800
    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) {
1801
      $template_result += array(
1802
        'CAPTAIN_ID'     => $captain['unit_id'],
1803
        'CAPTAIN_LEVEL'  => $captain['captain_level'],
1804
        'CAPTAIN_SHIELD' => $captain['captain_shield'],
1805
        'CAPTAIN_ARMOR'  => $captain['captain_armor'],
1806
        'CAPTAIN_ATTACK' => $captain['captain_attack'],
1807
      );
1808
    }
1809
1810
    $template_result += array(
1811
      'planet_metal'     => $planetResources[RES_METAL],
1812
      'planet_crystal'   => $planetResources[RES_CRYSTAL],
1813
      'planet_deuterium' => $planetResources[RES_DEUTERIUM],
1814
1815
      'fleet_capacity' => $this->shipsGetCapacity() - $travel_data['consumption'],
1816
      'speed'          => $this->oldSpeedInTens,
1817
      'fleet_group'    => $this->_group_id,
1818
1819
      'MAX_DURATION'          => $max_duration,
1820
1821
      // 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...
1822
//      'IS_TRANSPORT_MISSIONS' => !empty($this->allowed_missions[$this->_mission_type]['transport']),
1823
      'IS_TRANSPORT_MISSIONS' => true,
1824
1825
      'PLAYER_COLONIES_CURRENT' => get_player_current_colonies($this->dbOwnerRow),
1826
      'PLAYER_COLONIES_MAX'     => get_player_max_colonies($this->dbOwnerRow),
1827
    );
1828
1829
    $template = gettemplate('fleet2', true);
1830
    $template->assign_recursive($template_result);
1831
    display($template, classLocale::$lang['fl_title']);
1832
  }
1833
1834
1835
  public function restrict2MissionTransportWithResources($fleetResources) {
1836
    if($this->_mission_type != MT_TRANSPORT) {
1837
      return;
1838
    }
1839
1840
    if(array_sum($fleetResources) <= 0) {
1841
      throw new Exception('FLIGHT_RESOURCES_EMPTY', FLIGHT_RESOURCES_EMPTY);
1842
    }
1843
  }
1844
1845
  protected function restrict2MissionExploreAvailable() {
1846
    if($this->_mission_type != MT_EXPLORE) {
1847
      return;
1848
    }
1849
1850
    if(($expeditionsMax = get_player_max_expeditons($this->dbOwnerRow)) <= 0) {
1851
      throw new Exception('FLIGHT_MISSION_EXPLORE_NO_ASTROTECH', FLIGHT_MISSION_EXPLORE_NO_ASTROTECH);
1852
    }
1853
    if(FleetList::fleet_count_flying($this->getPlayerOwnerId(), MT_EXPLORE) >= $expeditionsMax) {
1854
      throw new Exception('FLIGHT_MISSION_EXPLORE_NO_SLOTS', FLIGHT_MISSION_EXPLORE_NO_SLOTS);
1855
    }
1856
1857
    $this->restrictToNotOnlySpies();
1858
    $this->restrictToNoMissiles();
1859
1860
    throw new Exception('FLIGHT_ALLOWED', FLIGHT_ALLOWED);
1861
  }
1862
1863
1864
  public function fleetPage3($time_to_travel) {
1865
    global $target_mission, $fleetarray, $planetrow;
1866
    global $galaxy, $system, $planet, $TargetPlanet, $consumption, $template_result;
1867
    global $errorlist, $planet_type, $MaxExpeditions, $FlyingExpeditions;
1868
    global $speed_percent, $distance, $fleet_speed, $user, $debug;
1869
1870
    $classLocale = classLocale::$lang;
1871
1872
    $this->isRealFlight = true;
1873
1874
    sn_db_transaction_start();
1875
1876
    db_user_lock_with_target_owner($this->dbOwnerRow, $this->dbTargetRow);
1877
1878
    $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...
1879
    $this->dbSourcePlanetRow = db_planet_by_id($this->dbSourcePlanetRow['id'], true);
1880
    if(!empty($this->dbTargetRow['id'])) {
1881
      $this->dbTargetRow = db_planet_by_id($this->dbTargetRow['id'], true);
1882
    }
1883
    if(!empty($this->dbTargetRow['id_owner'])) {
1884
      $this->dbTargetOwnerRow = db_planet_by_id($this->dbTargetRow['id_owner'], true);
1885
    }
1886
1887
    $this->resource_list = array(
1888
      RES_METAL     => max(0, floor(sys_get_param_float('resource0'))),
1889
      RES_CRYSTAL   => max(0, floor(sys_get_param_float('resource1'))),
1890
      RES_DEUTERIUM => max(0, floor(sys_get_param_float('resource2'))),
1891
    );
1892
1893
    $checklist = sn_get_groups('mission_checks');
1894
1895
    $this->travelData = $this->flt_travel_data($this->oldSpeedInTens);
1896
1897
    try {
1898
      $this->checkMissionRestrictions($checklist);
1899
1900
1901
      // Do the restrictMission checks
1902
1903
      // TODO - Кое-какие проверки дают FLIGHT_ALLOWED - ЧТО НЕПРАВДА В ДАННОМ СЛУЧАЕ!!!
1904
      // На странице 1 некоторые проверки ДОЛЖНЫ БЫТЬ опущены - иначе будет некрасиво
1905
      // А вот здесь надо проверять много дополнительной хуйни
1906
      try {
1907
        $this->restrictToNonVacationSender();
1908
1909
        $this->restrictToNotSource();
1910
1911
        // No mission could fly beyond Universe - i.e. with wrong Galaxy and/or System coordinates
1912
        $this->restrictToUniverse();
1913
1914
        // Only ships and missiles can be sent to mission
1915
        $this->restrictToFleetUnits();
1916
        // Only units with main engines (speed >=0) can fly - no other units like satellites
1917
        $this->restrictToMovable();
1918
1919
        // No missions except MT_EXPLORE could target coordinates beyond known system
1920
        $this->restrictKnownSpaceOrMissionExplore();
1921
        // Beyond this point all mission address only known space
1922
1923
        // No missions except MT_COLONIZE could target empty coordinates
1924
        $this->restrictTargetExistsOrMissionColonize();
1925
        // Beyond this point all mission address only existing planets/moons
1926
1927
        // No missions except MT_RECYCLE could target debris
1928
        $this->restrictNotDebrisOrMissionRecycle();
1929
        // Beyond this point targets can be only PT_PLANET or PT_MOON
1930
1931
1932
        // TODO  - ALL OF THE ABOVE!
1933
        $this->restrictMission();
1934
      } catch(Exception $e) {
1935
        // If mission is restricted - rethrow exception
1936
        if($e->getCode() != FLIGHT_ALLOWED) {
1937
          throw new Exception($e->getMessage(), $e->getCode());
1938
        }
1939
      }
1940
1941
      // TODO - later then
1942
1943
      // 2nd level restrictions
1944
      // Still cheap
1945
      $this->restrict2ToAllowedMissions();
1946
      $this->restrict2ToAllowedPlanetTypes();
1947
1948
      // More expensive checks
1949
      $this->restrict2ToMaxFleets();
1950
      $this->restrict2ToEnoughShips();
1951
1952
1953
      $travelData = $this->flt_travel_data($this->oldSpeedInTens);
1954
      $fleetCapacity = $travelData['capacity'];
1955
      $fleetConsumption = $travelData['consumption'];
1956
      /*
1957
        fleet_speed
1958
        distance
1959
        duration
1960
        consumption
1961
        capacity
1962
        hold                   = capacity - consumption,
1963
        transport_effectivness = consumption ? capacity / consumption : 0,
1964
       */
1965
      $this->restrict2ToEnoughCapacity($fleetCapacity, $fleetConsumption);
1966
      $this->restrict2ByResources($fleetConsumption);
1967
1968
1969
      // TODO - REWRITE TO LEVEL 2
1970
      $this->restrict2MissionExploreAvailable();
1971
      $this->restrictTargetExistsOrMissionColonize();
1972
      $this->restrictNotDebrisOrMissionRecycle();
1973
      // 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...
1974 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...
1975
        // Spying can't be done on owner's planet/moon
1976
        unset($this->allowed_missions[MT_SPY]);
1977
        // Attack can't be done on owner's planet/moon
1978
        unset($this->allowed_missions[MT_ATTACK]);
1979
        // ACS can't be done on owner's planet/moon
1980
        unset($this->allowed_missions[MT_ACS]);
1981
        // Destroy can't be done on owner's moon
1982
        unset($this->allowed_missions[MT_DESTROY]);
1983
1984
        $this->restrictToNoMissiles();
1985
1986
        // MT_RELOCATE
1987
        // No checks
1988
        // TODO - check captain
1989
1990
        // MT_HOLD
1991
        // TODO - Check for Allies Deposit for HOLD
1992
1993
        // MT_TRANSPORT
1994
1995
      } else {
1996
        // Relocate can be done only on owner's planet/moon
1997
        unset($this->allowed_missions[MT_RELOCATE]);
1998
1999
        // TODO - check for moratorium
2000
2001
        // MT_HOLD
2002
        // TODO - Check for Allies Deposit for HOLD
2003
        // TODO - Noob protection for HOLD depends on server settings
2004
2005
        // MT_SPY
2006
        $this->restrictToNotOnlySpiesOrMissionSpy();
2007
2008
        // TODO - check noob protection
2009
2010
        // TODO - check bashing
2011
2012
        // No missions except MT_MISSILE should have any missiles in fleet
2013
        $this->restrictMissionMissile();
2014
        $this->restrictToNoMissiles();
2015
        // Beyond this point no mission can have a missile in fleet
2016
2017
        // MT_DESTROY
2018
        $this->restrictMissionDestroy();
2019
2020
        // MT_ACS
2021
        $this->restrictMissionACS();
2022
2023
        // MT_ATTACK - no checks
2024
2025
        // MT_TRANSPORT - no checks
2026
      }
2027
      // 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...
2028
2029
2030
      //
2031
      //
2032
      //
2033
      //
2034
      //
2035
      //
2036
      //
2037
      //
2038
      //
2039
      //
2040
      //
2041
      //
2042
      //
2043
      //
2044
      //
2045
      //
2046
      //
2047
      //
2048
2049
2050
//      $this->restrict2MissionTransportWithResources($fleetResources);
0 ignored issues
show
Unused Code Comprehensibility introduced by
75% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
2051
    } catch(Exception $e) {
2052
      // TODO - MESSAGE BOX
2053 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...
2054
        sn_db_transaction_rollback();
2055
        pdie(classLocale::$lang['fl_attack_error'][$e->getCode()]);
2056
      } else {
2057
        pdump('FLIGHT_ALLOWED', FLIGHT_ALLOWED);
2058
      }
2059
    }
2060
2061
2062
    // TODO check for empty mission AKA mission allowed
2063
2064
    $errorlist = '';
2065
2066
    $errorlist .= !is_array($fleetarray) ? classLocale::$lang['fl_no_fleetarray'] : '';
2067
2068
    $TransMetal = max(0, floor(sys_get_param_float('resource0')));
2069
    $TransCrystal = max(0, floor(sys_get_param_float('resource1')));
2070
    $TransDeuterium = max(0, floor(sys_get_param_float('resource2')));
2071
    $StorageNeeded = $TransMetal + $TransCrystal + $TransDeuterium;
2072
2073
    if(!$StorageNeeded && $target_mission == MT_TRANSPORT) {
2074
      $errorlist .= classLocale::$lang['fl_noenoughtgoods'];
2075
    }
2076
2077
2078
    if($target_mission == MT_EXPLORE) {
2079
      if($MaxExpeditions == 0) {
2080
        $errorlist .= classLocale::$lang['fl_expe_notech'];
2081
      } elseif($FlyingExpeditions >= $MaxExpeditions) {
2082
        $errorlist .= classLocale::$lang['fl_expe_max'];
2083
      }
2084
    } else {
2085
      if($TargetPlanet['id_owner']) {
2086
        if($target_mission == MT_COLONIZE) {
2087
          $errorlist .= classLocale::$lang['fl_colonized'];
2088
        }
2089
2090
        if($TargetPlanet['id_owner'] == $planetrow['id_owner']) {
2091
          if($target_mission == MT_ATTACK) {
2092
            $errorlist .= classLocale::$lang['fl_no_self_attack'];
2093
          }
2094
2095
          if($target_mission == MT_SPY) {
2096
            $errorlist .= classLocale::$lang['fl_no_self_spy'];
2097
          }
2098
        } else {
2099
          if($target_mission == MT_RELOCATE) {
2100
            $errorlist .= classLocale::$lang['fl_only_stay_at_home'];
2101
          }
2102
        }
2103
      } else {
2104
        if($target_mission < MT_COLONIZE) {
2105
          $errorlist .= classLocale::$lang['fl_unknow_target'];
2106
        } else {
2107
//          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...
2108
//            $errorlist .= classLocale::$lang['fl_nomoon'];
2109
//          }
2110
2111
          if($target_mission == MT_RECYCLE) {
2112
            if($TargetPlanet['debris_metal'] + $TargetPlanet['debris_crystal'] == 0) {
2113
              $errorlist .= classLocale::$lang['fl_nodebris'];
2114
            }
2115
          }
2116
        }
2117
      }
2118
    }
2119
2120
2121
    if(sn_module::$sn_module['unit_captain']->manifest['active'] && $captain_id = sys_get_param_id('captain_id')) {
2122
      $captain = sn_module::$sn_module['unit_captain']->unit_captain_get($planetrow['id']);
2123
      if(!$captain) {
2124
        $errorlist .= classLocale::$lang['module_unit_captain_error_no_captain'];
2125
      } elseif($captain['unit_location_type'] == LOC_PLANET) {
2126
        if($target_mission == MT_RELOCATE && ($arriving_captain = mrc_get_level($user, $TargetPlanet, UNIT_CAPTAIN, true))) {
2127
          $errorlist .= classLocale::$lang['module_unit_captain_error_captain_already_bound'];
2128
        }
2129
      } else {
2130
        $errorlist .= classLocale::$lang['module_unit_captain_error_captain_flying'];
2131
      }
2132
    }
2133
2134
    if($errorlist) {
2135
      sn_db_transaction_rollback();
2136
      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...
2137
    }
2138
2139
    //Normally... unless its acs...
2140
    $aks = 0;
2141
    $fleet_group = sys_get_param_int('fleet_group');
2142
    //But is it acs??
2143
    //Well all acs fleets must have a fleet code.
2144
    //The co-ords must be the same as where the acs fleet is going.
2145
    if($fleet_group && sys_get_param_str('acs_target_mr') == "g{$galaxy}s{$system}p{$planet}t{$planet_type}") {
2146
      //ACS attack must exist (if acs fleet has arrived this will also return false (2 checks in 1!!!)
2147
      $aks = db_acs_get_by_group_id($fleet_group);
2148
      if(!$aks) {
2149
        $fleet_group = 0;
2150
      } else {
2151
        //Also it must be mission type 2
2152
        $target_mission = MT_ACS;
2153
2154
        $galaxy = $aks['galaxy'];
2155
        $system = $aks['system'];
2156
        $planet = $aks['planet'];
2157
        $planet_type = $aks['planet_type'];
2158
      }
2159
    } elseif($target_mission == MT_ACS) {
2160
      //Check that a failed acs attack isn't being sent, if it is, make it an attack fleet.
2161
      $target_mission = MT_ATTACK;
2162
    }
2163
2164
    if($target_mission == MT_COLONIZE || $target_mission == MT_EXPLORE) {
2165
      $TargetPlanet = array('galaxy' => $galaxy, 'system' => $system, 'planet' => $planet, 'id_owner' => 0);
2166
    }
2167
    $options = array('fleet_speed_percent' => $speed_percent, 'fleet_group' => $fleet_group, 'resources' => $StorageNeeded);
2168
    $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...
2169
2170
    if($cant_attack !== FLIGHT_ALLOWED) {
2171
      message("<span class='error'><b>{$classLocale['fl_attack_error'][$cant_attack]}</b></span>", classLocale::$lang['fl_error'], 'fleet' . DOT_PHP_EX, 99);
2172
    }
2173
2174
    $mission_time_in_seconds = 0;
2175
    $arrival_time = SN_TIME_NOW + $time_to_travel;
2176
    if($target_mission == MT_ACS && $aks) {
2177
//    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...
2178
      if($arrival_time > $aks['ankunft']) {
2179
        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']);
2180
      }
2181
      $group_sync_delta_time = $aks['ankunft'] - $arrival_time;
2182
      // Set arrival time to ACS arrival time
2183
      $arrival_time = $aks['ankunft'];
2184
      // Set return time to ACS return time + fleet's time to travel
2185
      $return_time = $aks['ankunft'] + $time_to_travel;
2186
    } else {
2187
      if($target_mission == MT_EXPLORE || $target_mission == MT_HOLD) {
2188
        $max_duration = $target_mission == MT_EXPLORE ? get_player_max_expedition_duration($user) : ($target_mission == MT_HOLD ? 12 : 0);
2189
        if($max_duration) {
2190
          $mission_time_in_hours = sys_get_param_id('missiontime');
2191
          if($mission_time_in_hours > $max_duration || $mission_time_in_hours < 1) {
2192
            $debug->warning('Supplying wrong mission time', 'Hack attempt', 302, array('base_dump' => true));
2193
            die();
2194
          }
2195
          $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));
2196
        }
2197
      }
2198
      $return_time = $arrival_time + $mission_time_in_seconds + $time_to_travel;
2199
      $group_sync_delta_time = 0;
2200
    }
2201
2202
//    $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...
2203
2204
    $db_changeset = array();
2205
    foreach($fleetarray as $Ship => $Count) {
2206
//      $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...
2207
      $db_changeset['unit'][] = sn_db_unit_changeset_prepare($Ship, -$Count, $user, $planetrow['id']);
2208
    }
2209
//    $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...
2210
2211
//    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...
2212
//      message("<span class='error'><b>" . classLocale::$lang['fl_nostoragespa'] . pretty_number($StorageNeeded - $FleetStorage) . "</b></span>", classLocale::$lang['fl_error'], 'fleet' . DOT_PHP_EX, 2);
2213
//    }
2214
//    if($planetrow['deuterium'] < $TransDeuterium + $consumption) {
2215
//      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);
2216
//    }
2217
//    if(($planetrow['metal'] < $TransMetal) || ($planetrow['crystal'] < $TransCrystal)) {
2218
//      message("<font color=\"red\"><b>" . classLocale::$lang['fl_no_resources'] . "</b></font>", classLocale::$lang['fl_error'], 'fleet' . DOT_PHP_EX, 2);
2219
//    }
2220
2221
2222
    //
2223
    //
2224
    //
2225
    //
2226
    //
2227
    //
2228
    //
2229
    //
2230
    // ---------------- END OF CHECKS ------------------------------------------------------
2231
2232
    $fleetarray[RES_METAL] = $TransMetal;
2233
    $fleetarray[RES_CRYSTAL] = $TransCrystal;
2234
    $fleetarray[RES_DEUTERIUM] = $TransDeuterium;
2235
2236
    $objFleet = new Fleet();
2237
    $objFleet->set_times($time_to_travel, $mission_time_in_seconds, $group_sync_delta_time);
2238
    $objFleet->unitsSetFromArray($fleetarray);
2239
    $objFleet->mission_type = $target_mission;
2240
    $objFleet->set_start_planet($planetrow);
2241
    $objFleet->set_end_planet(array(
2242
      'id'          => !empty($TargetPlanet['id']) ? $TargetPlanet['id'] : null,
2243
      'galaxy'      => !empty($galaxy) ? $galaxy : 0,
2244
      'system'      => !empty($system) ? $system : 0,
2245
      'planet'      => !empty($planet) ? $planet : 0,
2246
      'planet_type' => !empty($planet_type) ? $planet_type : 0,
2247
      'id_owner'    => $TargetPlanet['id_owner'],
2248
    ));
2249
    $objFleet->playerOwnerId = $user['id'];
2250
    $objFleet->group_id = $fleet_group;
2251
    $objFleet->dbInsert();
2252
2253
    db_planet_set_by_id($planetrow['id'], "`metal` = `metal` - {$TransMetal}, `crystal` = `crystal` - {$TransCrystal}, `deuterium` = `deuterium` - {$TransDeuterium} - {$consumption}");
2254
    db_changeset_apply($db_changeset);
2255
2256
    $template = gettemplate('fleet3', true);
2257
2258
    if(is_array($captain)) {
2259
      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...
2260
    }
2261
2262
    $template_route = array(
2263
      'ID'                 => 1,
2264
      'START_TYPE_TEXT_SH' => classLocale::$lang['sys_planet_type_sh'][$planetrow['planet_type']],
2265
      'START_COORDS'       => uni_render_coordinates($planetrow),
2266
      'START_NAME'         => $planetrow['name'],
2267
      'START_TIME_TEXT'    => date(FMT_DATE_TIME, $return_time + SN_CLIENT_TIME_DIFF),
2268
      'START_LEFT'         => floor($return_time + 1 - SN_TIME_NOW),
2269
    );
2270
    if(!empty($TargetPlanet)) {
2271
      $template_route += array(
2272
        'END_TYPE_TEXT_SH' => classLocale::$lang['sys_planet_type_sh'][$TargetPlanet['planet_type']],
2273
        'END_COORDS'       => uni_render_coordinates($TargetPlanet),
2274
        'END_NAME'         => $TargetPlanet['name'],
2275
        'END_TIME_TEXT'    => date(FMT_DATE_TIME, $arrival_time + SN_CLIENT_TIME_DIFF),
2276
        'END_LEFT'         => floor($arrival_time + 1 - SN_TIME_NOW),
2277
      );
2278
    }
2279
2280
    $template->assign_block_vars('fleets', $template_route);
2281
2282
    $sn_groups_fleet = sn_get_groups('fleet');
2283
    foreach($fleetarray as $ship_id => $ship_count) {
2284
      if(in_array($ship_id, $sn_groups_fleet) && $ship_count) {
2285
//      $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...
2286
        $template->assign_block_vars('fleets.ships', array(
2287
          'ID'          => $ship_id,
2288
          'AMOUNT'      => $ship_count,
2289
          'AMOUNT_TEXT' => pretty_number($ship_count),
2290
//        '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...
2291
//        'SPEED'       => $ship_base_data['speed'],
2292
          'NAME'        => classLocale::$lang['tech'][$ship_id],
2293
        ));
2294
      }
2295
    }
2296
2297
    $template->assign_vars(array(
2298
      'mission'         => classLocale::$lang['type_mission'][$target_mission] . ($target_mission == MT_EXPLORE || $target_mission == MT_HOLD ? ' ' . pretty_time($mission_time_in_seconds) : ''),
2299
      'dist'            => pretty_number($distance),
2300
      'speed'           => pretty_number($fleet_speed),
2301
      'deute_need'      => pretty_number($consumption),
2302
      'from'            => "{$planetrow['galaxy']}:{$planetrow['system']}:{$planetrow['planet']}",
2303
      'time_go'         => date(FMT_DATE_TIME, $arrival_time),
2304
      'time_go_local'   => date(FMT_DATE_TIME, $arrival_time + SN_CLIENT_TIME_DIFF),
2305
      'time_back'       => date(FMT_DATE_TIME, $return_time),
2306
      'time_back_local' => date(FMT_DATE_TIME, $return_time + SN_CLIENT_TIME_DIFF),
2307
    ));
2308
2309
    pdie('Stop for debug');
2310
2311
    sn_db_transaction_commit();
2312
    $planetrow = db_planet_by_id($planetrow['id']);
2313
    $template->assign_recursive($template_result);
2314
    display($template, classLocale::$lang['fl_title']);
2315
  }
2316
2317
2318
  /**
2319
   * @param array $checklist
2320
   *
2321
   * @throws Exception
2322
   */
2323
  public function checkMissionRestrictions($checklist) {
2324
    foreach($checklist as $condition => $action) {
2325
      $checkResult = call_user_func(array($this, $condition));
2326
2327
      if(is_array($action) && !empty($action[$checkResult])) {
2328
        $action = $action[$checkResult];
2329
      }
2330
2331
      if(is_array($action)) {
2332
        $this->checkMissionRestrictions($action);
2333
      } elseif(!$checkResult) {
2334
        throw new Exception($action, $action);
2335
      }
2336
    }
2337
  }
2338
2339
  protected function checkSpeedPercentOld() {
2340
    return in_array($this->oldSpeedInTens, array(10, 9, 8, 7, 6, 5, 4, 3, 2, 1));
2341
  }
2342
2343
  protected function checkSenderNoVacation() {
2344
    return empty($this->dbOwnerRow['vacation']) || $this->dbOwnerRow['vacation'] >= SN_TIME_NOW;
2345
  }
2346
2347
  protected function checkTargetNoVacation() {
2348
    return empty($this->dbTargetOwnerRow['vacation']) || $this->dbTargetOwnerRow['vacation'] >= SN_TIME_NOW;
2349
  }
2350
2351
  protected function checkMultiAccount() {
2352
    return sys_is_multiaccount($this->dbOwnerRow, $this->dbTargetOwnerRow);
2353
  }
2354
2355
  protected function checkFleetNotEmpty() {
2356
    return $this->unitList->unitsCount() >= 1;
2357
  }
2358
2359
  protected function checkTargetNotSource() {
2360
    return !$this->targetVector->isEqualToPlanet($this->dbSourcePlanetRow);
2361
  }
2362
2363
  protected function checkTargetInUniverse() {
2364
    return $this->targetVector->isInUniverse();
2365
  }
2366
2367
  protected function checkUnitsPositive() {
2368
    return $this->unitList->unitsPositive();
2369
  }
2370
2371
  protected function checkOnlyFleetUnits() {
2372
    return $this->unitList->unitsInGroup(sn_get_groups(array('fleet', 'missile')));
2373
  }
2374
2375
  protected function checkOnlyFlyingUnits() {
2376
    return $this->unitList->unitsIsAllMovable($this->dbOwnerRow);
2377
  }
2378
2379
  protected function checkEnoughFleetSlots() {
2380
    return FleetList::fleet_count_flying($this->getPlayerOwnerId()) < GetMaxFleets($this->dbOwnerRow);
2381
  }
2382
2383
  protected function checkSourceEnoughShips() {
2384
    return $this->unitList->shipsIsEnoughOnPlanet($this->dbSourcePlanetRow);
2385
  }
2386
2387
  protected function checkEnoughCapacity($includeResources = true) {
2388
    $checkVia = $this->travelData['consumption'];
2389
    $checkVia = ceil(($includeResources ? array_sum($this->resource_list) : 0) + $checkVia);
2390
2391
    return
2392
      !empty($this->travelData) &&
2393
      is_array($this->travelData) &&
2394
      floor($this->travelData['capacity']) >= $checkVia;
2395
  }
2396
2397
  protected function checkNotTooFar() {
2398
    return $this->checkEnoughCapacity(false);
2399
  }
2400
2401
  protected function checkDebrisExists() {
2402
    return is_array($this->dbTargetRow) && ($this->dbTargetRow['debris_metal'] + $this->dbTargetRow['debris_crystal'] > 0);
2403
  }
2404
2405
  protected function checkResourcesPositive() {
2406
    foreach($this->resource_list as $resourceId => $resourceAmount) {
2407
      if($resourceAmount < 0) {
2408
        return false;
2409
      }
2410
    }
2411
2412
    return true;
2413
  }
2414
2415
  protected function checkCargo() {
2416
    return array_sum($this->resource_list) >= 1;
2417
  }
2418
2419
  protected function checkSourceEnoughFuel() {
2420
    $deuteriumOnPlanet = mrc_get_level($this->dbOwnerRow, $this->dbSourcePlanetRow, RES_DEUTERIUM);
2421
2422
    return $deuteriumOnPlanet < ceil($this->travelData['consumption']);
2423
  }
2424
2425
2426
  protected function checkSourceEnoughResources() {
2427
    $fleetResources = $this->resource_list;
2428
    $fleetResources[RES_DEUTERIUM] = ceil($fleetResources[RES_DEUTERIUM] + $this->travelData['consumption']);
2429
    foreach($fleetResources as $resourceId => $resourceAmount) {
2430
      if(mrc_get_level($this->dbOwnerRow, $this->dbSourcePlanetRow, $resourceId) < ceil($fleetResources[$resourceId])) {
2431
        return false;
2432
      }
2433
    }
2434
2435
    return true;
2436
  }
2437
2438
  protected function checkKnownSpace() {
2439
    return $this->targetVector->isInKnownSpace();
2440
  }
2441
2442
  protected function checkNotOnlySpies() {
2443
    return $this->unitList->unitsCountById(SHIP_SPY) < $this->shipsGetTotal();
2444
  }
2445
2446
  public function checkNoMissiles() {
2447
    return
2448
      $this->unitList->unitsCountById(UNIT_DEF_MISSILE_INTERPLANET) == 0
2449
      &&
2450
      $this->unitList->unitsCountById(UNIT_DEF_MISSILE_INTERCEPTOR) == 0;
2451
  }
2452
2453
2454
  protected function checkTargetExists() {
2455
    return !empty($this->dbTargetRow['id']);
2456
  }
2457
2458
  protected function checkHaveColonizer() {
2459
    // Colonization fleet should have at least one colonizer
2460
    return $this->unitList->unitsCountById(SHIP_COLONIZER) >= 1;
2461
  }
2462
2463
  protected function checkTargetIsPlanet() {
2464
    return $this->targetVector->type == PT_PLANET;
2465
  }
2466
2467
  protected function checkTargetIsDebris() {
2468
    return $this->targetVector->type == PT_DEBRIS;
2469
  }
2470
2471
  protected function checkHaveRecyclers() {
2472
    $recyclers = 0;
2473
    foreach(sn_get_groups('flt_recyclers') as $recycler_id) {
2474
      $recyclers += $this->unitList->unitsCountById($recycler_id);
2475
    }
2476
2477
    return $recyclers >= 1;
2478
  }
2479
2480
2481
  // TODO
2482
  protected function checkTargetOwn() {
2483
    $result = $this->dbTargetRow['id_owner'] == $this->dbSourcePlanetRow['id_owner'];
2484
2485
    if($result) {
2486
      // Spying can't be done on owner's planet/moon
2487
      unset($this->allowed_missions[MT_SPY]);
2488
      // Attack can't be done on owner's planet/moon
2489
      unset($this->allowed_missions[MT_ATTACK]);
2490
      // ACS can't be done on owner's planet/moon
2491
      unset($this->allowed_missions[MT_ACS]);
2492
      // Destroy can't be done on owner's moon
2493
      unset($this->allowed_missions[MT_DESTROY]);
2494
      unset($this->allowed_missions[MT_MISSILE]);
2495
2496
      // MT_RELOCATE
2497
      // No checks
2498
      // TODO - check captain
2499
2500
      // MT_HOLD
2501
      // TODO - Check for Allies Deposit for HOLD
2502
2503
      // MT_TRANSPORT
2504
2505
    } else {
2506
      // Relocate can be done only on owner's planet/moon
2507
      unset($this->allowed_missions[MT_RELOCATE]);
2508
2509
    }
2510
2511
    return $result; // this->getPlayerOwnerId();
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
2512
  }
2513
2514
2515
  protected function alwaysFalse() {
2516
    return false;
2517
  }
2518
2519
2520
  protected function checkSpiesOnly() {
2521
    $result = $this->unitList->unitsCountById(SHIP_SPY) == $this->shipsGetTotal();
2522
    if($result) {
2523
      $this->allowed_missions = array(
2524
        MT_SPY => MT_SPY,
2525
      );
2526
    } else {
2527
      unset($this->allowed_missions[MT_SPY]);
2528
    }
2529
2530
    return $result;
2531
  }
2532
2533
  protected function checkTargetAllyDeposit() {
2534
    $result = mrc_get_level($this->dbTargetOwnerRow, $this->dbTargetRow, STRUC_ALLY_DEPOSIT) >= 1;
2535
    if(!$result) {
2536
      unset($this->allowed_missions[MT_HOLD]);
2537
    }
2538
2539
    return $result;
2540
  }
2541
2542
2543
  protected function checkMissionsOwn() {
2544
    $result = !$this->_mission_type || in_array($this->_mission_type, array(
2545
        MT_HOLD      => MT_HOLD,
2546
        MT_RECYCLE   => MT_RECYCLE,
2547
        MT_RELOCATE  => MT_RELOCATE,
2548
        MT_TRANSPORT => MT_TRANSPORT,
2549
      ));
2550
2551
    unset($this->allowed_missions[MT_ATTACK]);
2552
    unset($this->allowed_missions[MT_COLONIZE]);
2553
    unset($this->allowed_missions[MT_EXPLORE]);
2554
    unset($this->allowed_missions[MT_ACS]);
2555
    unset($this->allowed_missions[MT_SPY]);
2556
    unset($this->allowed_missions[MT_DESTROY]);
2557
    unset($this->allowed_missions[MT_MISSILE]);
2558
2559
    return $result;
2560
  }
2561
2562
  protected function checkMission($missionType) {
2563
    $result = !$this->_mission_type || $this->_mission_type == $missionType;
2564
    if($result) {
2565
      $this->allowed_missions = array(
2566
        $missionType => $missionType,
2567
      );
2568
    } else {
2569
      unset($this->allowed_missions[$missionType]);
2570
    }
2571
2572
    return $result;
2573
  }
2574
2575
  protected function checkMissionNonRestrict($missionType) {
2576
    return $this->_mission_type == $missionType;
2577
  }
2578
2579
  protected function checkMissionExplore() {
2580
    return $this->checkMission(MT_EXPLORE);
2581
  }
2582
2583
  protected function checkMissionColonize() {
2584
    return $this->checkMission(MT_COLONIZE);
2585
  }
2586
2587
  protected function checkMissionRecycle() {
2588
    return $this->checkMission(MT_RECYCLE);
2589
  }
2590
2591
  protected function checkMissionMissile() {
2592
    return $this->checkMission(MT_MISSILE);
2593
  }
2594
2595
  protected function checkNotEmptyMission() {
2596
    return !empty($this->_mission_type);
2597
  }
2598
2599
2600
  protected function checkMissionRelocate() {
2601
    return $this->checkMissionNonRestrict(MT_RELOCATE);
2602
  }
2603
2604
  protected function checkMissionHoldNonUnique() {
2605
    $result = $this->checkMissionNonRestrict(MT_HOLD);
2606
2607
    return $result;
2608
  }
2609
2610
  protected function checkMissionTransport() {
2611
    return $this->checkMissionNonRestrict(MT_TRANSPORT);
2612
  }
2613
  protected function checkMissionTransportReal() {
2614
    return
2615
      $this->checkRealFlight()
2616
      &&
2617
      $this->checkMissionTransport();
2618
  }
2619
2620
2621
  protected function checkMissionSpy() {
2622
    return $this->checkMission(MT_SPY);
2623
  }
2624
2625
2626
  protected function checkRealFlight() {
2627
    return $this->isRealFlight;
2628
  }
2629
2630
  protected function checkMissionExists() {
2631
    return !empty($this->exists_missions[$this->_mission_type]);
2632
  }
2633
2634
  protected function checkTargetActive() {
2635
    return
2636
      empty($this->dbTargetOwnerRow['onlinetime'])
2637
      ||
2638
      SN_TIME_NOW - $this->dbTargetOwnerRow['onlinetime'] >= PLAYER_TIME_ACTIVE_SECONDS;
2639
  }
2640
2641
  // TODO - REDO MAIN FUNCTION
2642
  protected function checkTargetNotActive() {
2643
    return !$this->checkTargetActive();
2644
  }
2645
2646
2647
  protected function checkSameAlly() {
2648
    return !empty($this->dbTargetOwnerRow['ally_id']) && $this->dbTargetOwnerRow['ally_id'] == $this->dbOwnerRow['ally_id'];
2649
  }
2650
2651
  protected function checkTargetNoob() {
2652
    $user_points = $this->dbTargetOwnerRow['total_points'];
2653
    $enemy_points = $this->dbTargetOwnerRow['total_points'];
2654
2655
    return
2656
      // Target is under Noob Protection but Fleet owner is not
2657
      ($enemy_points <= classSupernova::$config->game_noob_points && $user_points > classSupernova::$config->game_noob_points)
2658
      ||
2659
      (classSupernova::$config->game_noob_factor && $user_points > $enemy_points * classSupernova::$config->game_noob_factor);
2660
  }
2661
2662
  // TODO - REDO MAIN FUNCTION
2663
  protected function checkTargetNotNoob() {
2664
    return !$this->checkTargetNoob();
2665
  }
2666
2667
2668
  protected function checkMissionHoldReal() {
2669
    return
2670
      $this->checkRealFlight()
2671
      &&
2672
      $this->checkMissionHoldNonUnique();
2673
  }
2674
2675
2676
2677
  protected function checkMissionHoldOnNotNoob() {
2678
    return
2679
      $this->checkTargetNotActive()
2680
      ||
2681
      ($this->checkSameAlly() && classSupernova::$config->ally_help_weak)
2682
      ||
2683
      $this->checkTargetNotNoob();
2684
  }
2685
2686
2687
  protected function checkOnlyAttackMissiles() {
2688
    $missilesAttack = $this->unitList->unitsCountById(UNIT_DEF_MISSILE_INTERPLANET);
2689
2690
    return $missilesAttack != 0 && $missilesAttack == $this->shipsGetTotal();
2691
  }
2692
2693
}
2694