sn_flt_can_attack()   F
last analyzed

Complexity

Conditions 95
Paths 7128

Size

Total Lines 272
Code Lines 134

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 95
eloc 134
nc 7128
nop 6
dl 0
loc 272
rs 0
c 1
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
use DBAL\db_mysql;
4
use DBAL\OldDbChangeSet;
5
use Fleet\DbFleetStatic;
6
use Fleet\Fleet;
7
use Fleet\FleetStatic;
8
use Planet\DBStaticPlanet;
9
10
/**
11
 * @param int   $ship_id
12
 * @param int   $speed_percent
13
 * @param array $shipsData
14
 *
15
 * @return float|int
16
 */
17
function flt_get_max_distance($ship_id, $speed_percent = 100, $shipsData = []) {
18
  $single_ship_data = $shipsData[$ship_id];
19
20
  if (!$single_ship_data['capacity'] || !$single_ship_data['consumption']) {
21
    return 0;
22
  }
23
24
  return calcDistance($speed_percent, $single_ship_data);
25
}
26
27
/**
28
 * @param $speed_percent
29
 * @param $single_ship_data
30
 *
31
 * @return float
32
 */
33
function calcDistance($speed_percent, $single_ship_data) {
34
  return floor(($single_ship_data['capacity'] - 1) / $single_ship_data['consumption'] / pow($speed_percent / 100 + 1, 2) * 35000);
35
}
36
37
38
/**
39
 * @param         $user_row
40
 * @param         $from
41
 * @param         $to
42
 * @param         $fleet_array
43
 * @param int     $speed_percent
44
 * @param array[] $shipsData - prepared ships data to use in calculations
45
 *
46
 * @return array
47
 */
48
function flt_travel_data($user_row, $from, $to, $fleet_array, $speed_percent = 10, $shipsData = [], $distance = null) {
49
  $distance = $distance === null ? Universe::distance($from, $to) : $distance;
50
51
  $consumption = 0;
52
  $capacity    = 0;
53
  $duration    = 0;
54
55
  $game_fleet_speed = Universe::flt_server_flight_speed_multiplier();
56
  $fleet_speed      = FleetStatic::flt_fleet_speed($user_row, $fleet_array, $shipsData);
57
  if (!empty($fleet_array) && $fleet_speed && $game_fleet_speed) {
58
    $speed_percent = $speed_percent ? max(min($speed_percent, 10), 1) : 10;
59
    $real_speed    = $speed_percent * sqrt($fleet_speed);
60
61
    $duration = max(1, round(
62
      (35000 / $speed_percent * sqrt($distance * 10 / $fleet_speed) + 10) / $game_fleet_speed
63
    ));
64
65
    foreach ($fleet_array as $ship_id => $ship_count) {
66
      if (!$ship_id || !$ship_count) {
67
        continue;
68
      }
69
70
      $single_ship_data          = !empty($shipsData[$ship_id]) ? $shipsData[$ship_id] : get_ship_data($ship_id, $user_row);
71
      $single_ship_data['speed'] = $single_ship_data['speed'] < 1 ? 1 : $single_ship_data['speed'];
72
73
      $consumption += $single_ship_data['consumption'] * $ship_count * pow($real_speed / sqrt($single_ship_data['speed']) / 10 + 1, 2);
74
      $capacity    += $single_ship_data['capacity'] * $ship_count;
75
    }
76
77
    $consumption = ceil($distance * $consumption / 35000) + 1;
78
  }
79
80
  return array(
81
    'fleet_speed'            => $fleet_speed,
82
    'distance'               => $distance,
83
    'duration'               => $duration,
84
    'consumption'            => $consumption,
85
    'capacity'               => $capacity,
86
    'hold'                   => $capacity - $consumption,
87
    'transport_effectivness' => $consumption ? $capacity / $consumption : 0,
88
  );
89
}
90
91
function flt_bashing_check($user, $enemy, $planet_dst, $mission, $flight_duration, $fleet_group = 0) {
92
  global $config;
93
94
  $config_bashing_attacks  = $config->fleet_bashing_attacks;
95
  $config_bashing_interval = $config->fleet_bashing_interval;
96
  if (!$config_bashing_attacks) {
97
    // Bashing allowed - protection disabled
98
    return ATTACK_ALLOWED;
99
  }
100
101
  $bashing_result = ATTACK_BASHING;
102
  if ($user['ally_id'] && $enemy['ally_id']) {
103
    $relations = ali_relations($user['ally_id'], $enemy['ally_id']);
104
    if (!empty($relations)) {
105
      $relations = $relations[$enemy['ally_id']];
106
      switch ($relations['alliance_diplomacy_relation']) {
107
        case ALLY_DIPLOMACY_WAR:
108
          if (SN_TIME_NOW - $relations['alliance_diplomacy_time'] <= $config->fleet_bashing_war_delay) {
109
            $bashing_result = ATTACK_BASHING_WAR_DELAY;
110
          } else {
111
            return ATTACK_ALLOWED;
112
          }
113
        break;
114
        // Here goes other relations
115
116
        /*
117
                default:
118
                  return ATTACK_ALLOWED;
119
                break;
120
        */
121
      }
122
    }
123
  }
124
125
  $time_limit   = SN_TIME_NOW + $flight_duration - $config->fleet_bashing_scope;
126
  $bashing_list = array(SN_TIME_NOW);
127
128
  // Retrieving flying fleets
129
  $bashing_fleet_list = DbFleetStatic::fleet_list_bashing($user['id'], $planet_dst);
130
  foreach ($bashing_fleet_list as $fleet_row) {
131
    // Checking for ACS - each ACS count only once
132
    if ($fleet_row['fleet_group']) {
133
      $bashing_list["{$user['id']}_{$fleet_row['fleet_group']}"] = $fleet_row['fleet_start_time'];
134
    } else {
135
      $bashing_list[] = $fleet_row['fleet_start_time'];
136
    }
137
  }
138
139
  // Check for joining to ACS - if there are already fleets in ACS no checks should be done
140
  if ($mission == MT_AKS && $bashing_list["{$user['id']}_{$fleet_group}"]) {
141
    return ATTACK_ALLOWED;
142
  }
143
144
  $query = doquery("SELECT bashing_time FROM `{{bashing}}` WHERE bashing_user_id = {$user['id']} AND bashing_planet_id = {$planet_dst['id']} AND bashing_time >= {$time_limit};");
0 ignored issues
show
Deprecated Code introduced by
The function doquery() has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

144
  $query = /** @scrutinizer ignore-deprecated */ doquery("SELECT bashing_time FROM `{{bashing}}` WHERE bashing_user_id = {$user['id']} AND bashing_planet_id = {$planet_dst['id']} AND bashing_time >= {$time_limit};");
Loading history...
145
  while ($bashing_row = db_fetch($query)) {
0 ignored issues
show
Deprecated Code introduced by
The function db_fetch() has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

145
  while ($bashing_row = /** @scrutinizer ignore-deprecated */ db_fetch($query)) {
Loading history...
146
    $bashing_list[] = $bashing_row['bashing_time'];
147
  }
148
149
  sort($bashing_list);
150
151
  $last_attack = 0;
152
  $wave        = 0;
153
  $attack      = 1;
154
  foreach ($bashing_list as &$bash_time) {
155
    $attack++;
156
    if ($bash_time - $last_attack > $config_bashing_interval || $attack > $config_bashing_attacks) {
157
      $attack = 1;
158
      $wave++;
159
    }
160
161
    $last_attack = $bash_time;
162
  }
163
164
  return ($wave > $config->fleet_bashing_waves ? $bashing_result : ATTACK_ALLOWED);
165
}
166
167
/**
168
 * @param array $planet_src - source planet record/vector
169
 * @param array $planet_dst - destination planet record/vector
170
 * @param array $fleet      - array of ship amount [(int)shipId => (float)shipAmount]
171
 * @param int   $mission    - Mission ID
172
 * @param array $options    - [
173
 *                          P_FLEET_ATTACK_RESOURCES_SUM       => (float),
174
 *                          P_FLEET_ATTACK_RES_LIST            => [(int)resId => (float)amount]
175
 *                          P_FLEET_ATTACK_SPEED_PERCENT_TENTH => (int)1..10
176
 *                          P_FLEET_ATTACK_FLEET_GROUP         => (int|string)
177
 *                          P_FLEET_ATTACK_FLYING_COUNT        => (int)
178
 *                          P_FLEET_ATTACK_TARGET_STRUCTURE    => (int) - targeted defense structure snID for MISSILE missions
179
 *                          P_FLEET_ATTACK_STAY_TIME           => (int) - stay HOURS
180
 *                          ]
181
 *
182
 * @return int
183
 */
184
function flt_can_attack($planet_src, $planet_dst, $fleet = [], $mission, $options = []) {
185
  $result = null;
186
187
  return sn_function_call('flt_can_attack', [$planet_src, $planet_dst, $fleet, $mission, $options, &$result]);
188
}
189
190
/**
191
 * @param array $planet_src
192
 * @param array $planet_dst
193
 * @param array $fleet
194
 * @param int   $mission
195
 * @param array $options
196
 * @param int   $result
197
 *
198
 * @return int
199
 * @see flt_can_attack()
200
 */
201
function sn_flt_can_attack($planet_src, $planet_dst, $fleet = [], $mission, $options = [], &$result) {
202
  //TODO: try..catch
203
  global $config, $user;
204
205
  !is_array($options) ? $options = [] : false;
0 ignored issues
show
introduced by
The condition is_array($options) is always true.
Loading history...
206
207
  if ($user['vacation']) {
208
    return $result = ATTACK_OWN_VACATION;
209
  }
210
211
  $sn_groups_mission = sn_get_groups('missions');
212
  if (!isset($sn_groups_mission[$mission])) {
213
    return $result = ATTACK_MISSION_ABSENT;
214
  }
215
  $sn_data_mission = $sn_groups_mission[$mission];
216
217
//TODO: Проверка на отстуствие ресурсов в нетранспортных миссиях (Транспорт, Передислокация, Колонизация)
218
219
  //TODO: Проверка на наличие ресурсов при Транспорте
220
  // TODO: Проверка на отрицательные ресурсы при транспорте
221
  // TODO: Проверка на перегрузку при транспорте
222
223
  // TODO: В ракетных миссиях могут лететь только ракеты
224
  // TODO: В неракетных миссиях ракеты должны отсутствовать
225
226
  if (empty($fleet) || !is_array($fleet)) {
227
    return $result = ATTACK_NO_FLEET;
228
  }
229
230
  $ships        = 0;
231
  $recyclers    = 0;
232
  $spies        = 0;
233
  $resources    = 0;
234
  $ship_ids     = sn_get_groups('fleet');
235
  $resource_ids = sn_get_groups('resources_loot');
236
  foreach ($fleet as $ship_id => $ship_count) {
237
    $is_ship     = in_array($ship_id, $ship_ids);
238
    $is_resource = in_array($ship_id, $resource_ids);
239
//    if (!$is_ship && !$is_resource) {
240
//      // TODO Спецобработчик для Капитана и модулей
241
//      return ATTACK_WRONG_UNIT;
242
//    }
243
244
    if ($ship_count < 0) {
245
      return $result = $is_ship ? ATTACK_SHIP_COUNT_WRONG : ATTACK_RESOURCE_COUNT_WRONG;
246
    }
247
248
    if ($ship_count > mrc_get_level($user, $planet_src, $ship_id)) {
249
      // TODO ATTACK_NO_MISSILE
250
      return $result = $is_ship ? ATTACK_NO_SHIPS : ATTACK_NO_RESOURCES;
251
    }
252
253
    if ($is_ship) {
254
      $single_ship_data = get_ship_data($ship_id, $user);
255
      if ($single_ship_data[P_SPEED] <= 0) {
256
        return $result = ATTACK_ZERO_SPEED;
257
      }
258
      $ships     += $ship_count;
259
      $recyclers += in_array($ship_id, sn_get_groups('flt_recyclers')) ? $ship_count : 0;
260
      $spies     += $ship_id == SHIP_SPY ? $ship_count : 0;
261
    } elseif ($is_resource) {
262
      $resources += $ship_count;
263
    }
264
  }
265
266
  if (empty($resources) && !empty($options[P_FLEET_ATTACK_RES_LIST]) && is_array($options[P_FLEET_ATTACK_RES_LIST])) {
267
    $resources = array_sum($options[P_FLEET_ATTACK_RES_LIST]);
268
  }
269
270
  if (
271
    isset($options[P_FLEET_ATTACK_RESOURCES_SUM])
272
    && $options[P_FLEET_ATTACK_RESOURCES_SUM] > 0
273
    && empty($sn_data_mission['transport'])
274
  ) {
275
    return $result = ATTACK_RESOURCE_FORBIDDEN;
276
  }
277
278
  /*
279
    elseif($mission == MT_TRANSPORT)
280
    {
281
      return ATTACK_TRANSPORT_EMPTY;
282
    }
283
  */
284
285
  $speed = $options[P_FLEET_ATTACK_SPEED_PERCENT_TENTH];
286
  if ($speed && ($speed != intval($speed) || $speed < 1 || $speed > 10)) {
287
    return $result = ATTACK_WRONG_SPEED;
288
  }
289
290
  $travel_data = flt_travel_data($user, $planet_src, $planet_dst, $fleet, $options[P_FLEET_ATTACK_SPEED_PERCENT_TENTH]);
291
292
293
  if (mrc_get_level($user, $planet_src, RES_DEUTERIUM) < $fleet[RES_DEUTERIUM] + $travel_data['consumption']) {
294
    return $result = ATTACK_NO_FUEL;
295
  }
296
297
  if ($travel_data['consumption'] > $travel_data['capacity']) {
298
    return $result = ATTACK_TOO_FAR;
299
  }
300
301
  if ($travel_data['hold'] < $resources) {
302
    return $result = ATTACK_OVERLOADED;
303
  }
304
305
  $fleet_start_time = SN_TIME_NOW + $travel_data['duration'];
306
307
  $fleet_group = $options[P_FLEET_ATTACK_FLEET_GROUP];
308
  if ($fleet_group) {
309
    if ($mission != MT_AKS) {
310
      return $result = ATTACK_WRONG_MISSION;
311
    };
312
313
    $acs = DbFleetStatic::dbAcsGetById($fleet_group);
314
    if (!$acs['id']) {
315
      return $result = ATTACK_NO_ACS;
316
    }
317
318
    if ($planet_dst['galaxy'] != $acs['galaxy'] || $planet_dst['system'] != $acs['system'] || $planet_dst['planet'] != $acs['planet'] || $planet_dst['planet_type'] != $acs['planet_type']) {
319
      return $result = ATTACK_ACS_WRONG_TARGET;
320
    }
321
322
    if ($fleet_start_time > $acs['ankunft']) {
323
      return $result = ATTACK_ACS_TOO_LATE;
324
    }
325
326
    if (DbFleetStatic::acsIsAcsFull($acs['id'])) {
327
      return $result = ATTACK_ACS_MAX_FLEETS;
328
    }
329
  }
330
331
  $flying_fleets = $options[P_FLEET_ATTACK_FLYING_COUNT];
332
  if (!$flying_fleets) {
333
    $flying_fleets = DbFleetStatic::fleet_count_flying($user['id']);
334
  }
335
  if (GetMaxFleets($user) <= $flying_fleets && $mission != MT_MISSILE) {
336
    return $result = ATTACK_NO_SLOTS;
337
  }
338
339
  // В одиночку шпионские зонды могут летать только в миссии Шпионаж, Передислокация и Транспорт
340
  if ($ships && $spies && $spies == $ships && !($mission == MT_SPY || $mission == MT_RELOCATE || $mission == MT_TRANSPORT)) {
341
    return $result = ATTACK_SPIES_LONLY;
342
  }
343
344
  // Checking for no planet
345
  if (!$planet_dst['id_owner']) {
346
    if ($mission == MT_COLONIZE && !$fleet[SHIP_COLONIZER]) {
347
      return $result = ATTACK_NO_COLONIZER;
348
    }
349
350
    if ($mission == MT_EXPLORE || $mission == MT_COLONIZE) {
351
      return $result = ATTACK_ALLOWED;
352
    }
353
354
    return $result = ATTACK_NO_TARGET;
355
  }
356
357
  if ($mission == MT_RECYCLE) {
358
    if ($planet_dst['debris_metal'] + $planet_dst['debris_crystal'] <= 0) {
359
      return $result = ATTACK_NO_DEBRIS;
360
    }
361
    if ($recyclers <= 0) {
362
      return $result = ATTACK_NO_RECYCLERS;
363
    }
364
365
    return $result = ATTACK_ALLOWED;
366
  }
367
368
  // Got planet. Checking if it is ours
369
  if ($planet_dst['id_owner'] == $user['id']) {
370
    if ($mission == MT_TRANSPORT || $mission == MT_RELOCATE) {
371
      return $result = ATTACK_ALLOWED;
372
    }
373
374
    return $planet_src['id'] == $planet_dst['id'] ? ATTACK_SAME : ATTACK_OWN;
375
  }
376
377
  // No, planet not ours. Cutting mission that can't be send to not-ours planet
378
  if ($mission == MT_RELOCATE || $mission == MT_COLONIZE || $mission == MT_EXPLORE) {
379
    return $result = ATTACK_WRONG_MISSION;
380
  }
381
382
  $enemy = db_user_by_id($planet_dst['id_owner']);
0 ignored issues
show
Deprecated Code introduced by
The function db_user_by_id() has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

382
  $enemy = /** @scrutinizer ignore-deprecated */ db_user_by_id($planet_dst['id_owner']);
Loading history...
383
  // We cannot attack or send resource to users in VACATION mode
384
  if ($enemy['vacation'] && $mission != MT_RECYCLE) {
385
    return $result = ATTACK_VACATION;
386
  }
387
388
  // Multi IP protection
389
  // TODO: Here we need a procedure to check proxies
390
  if (sys_is_multiaccount($user, $enemy)) {
391
    return $result = ATTACK_SAME_IP;
392
  }
393
394
  $user_points  = $user['total_points'];
395
  $enemy_points = $enemy['total_points'];
396
397
  // Is it transport? If yes - checking for buffing to prevent mega-alliance destroyer
398
  if ($mission == MT_TRANSPORT) {
399
    if ($user_points >= $enemy_points || $config->allow_buffing) {
400
      return $result = ATTACK_ALLOWED;
401
    } else {
402
      return $result = ATTACK_BUFFING;
403
    }
404
  }
405
406
  // Only aggresive missions passed to this point. HOLD counts as passive but aggresive
407
408
  // Is it admin with planet protection?
409
  if ($planet_dst['id_level'] > $user['authlevel']) {
410
    return $result = ATTACK_ADMIN;
411
  }
412
413
  // Okay. Now skipping protection checks for inactive longer then 1 week
414
  if (!$enemy['onlinetime'] || $enemy['onlinetime'] >= (SN_TIME_NOW - 60 * 60 * 24 * 7)) {
415
    if (
416
      (SN::$gc->general->playerIsNoobByPoints($enemy_points) && !SN::$gc->general->playerIsNoobByPoints($user_points))
417
      ||
418
      (SN::$gc->general->playerIs1stStrongerThen2nd($user_points, $enemy_points))
419
    ) {
420
      if ($mission != MT_HOLD) {
421
        return $result = ATTACK_NOOB;
422
      }
423
      if ($mission == MT_HOLD && !($user['ally_id'] && $user['ally_id'] == $enemy['ally_id'] && $config->ally_help_weak)) {
424
        return $result = ATTACK_NOOB;
425
      }
426
    }
427
  }
428
429
  // Is it HOLD mission? If yes - there should be ally deposit
430
  if ($mission == MT_HOLD) {
431
    if (mrc_get_level($user, $planet_dst, STRUC_ALLY_DEPOSIT)) {
432
      return $result = ATTACK_ALLOWED;
433
    }
434
435
    return $result = ATTACK_NO_ALLY_DEPOSIT;
436
  }
437
438
  if ($mission == MT_SPY) {
439
    return $result = $spies >= 1 ? ATTACK_ALLOWED : ATTACK_NO_SPIES;
440
  }
441
442
  // Is it MISSILE mission?
443
  if ($mission == MT_MISSILE) {
444
    $sn_data_mip = get_unit_param(UNIT_DEF_MISSILE_INTERPLANET);
445
    if (mrc_get_level($user, $planet_src, STRUC_SILO) < $sn_data_mip[P_REQUIRE][STRUC_SILO]) {
446
      return $result = ATTACK_NO_SILO;
447
    }
448
449
    if (!$fleet[UNIT_DEF_MISSILE_INTERPLANET]) {
450
      return $result = ATTACK_NO_MISSILE;
451
    }
452
453
    $distance  = abs($planet_dst['system'] - $planet_src['system']);
454
    $mip_range = flt_get_missile_range($user);
455
    if ($distance > $mip_range || $planet_dst['galaxy'] != $planet_src['galaxy']) {
456
      return $result = ATTACK_MISSILE_TOO_FAR;
457
    }
458
459
    if (!empty($options[P_FLEET_ATTACK_TARGET_STRUCTURE]) && !in_array($options[P_FLEET_ATTACK_TARGET_STRUCTURE], sn_get_groups('defense_active'))) {
460
      return $result = ATTACK_WRONG_STRUCTURE;
461
    }
462
  }
463
464
  if ($mission == MT_DESTROY && $planet_dst['planet_type'] != PT_MOON) {
465
    return $result = ATTACK_WRONG_MISSION;
466
  }
467
468
  if ($mission == MT_ATTACK || $mission == MT_AKS || $mission == MT_DESTROY) {
469
    return $result = flt_bashing_check($user, $enemy, $planet_dst, $mission, $travel_data['duration'], $fleet_group);
470
  }
471
472
  return $result = ATTACK_ALLOWED;
473
}
474
475
/**
476
 * @param array $user    - actual user record
477
 * @param array $from    - actual planet record
478
 * @param array $to      - actual planet record
479
 * @param array $fleet   - array of records $unit_id -> $amount
480
 * @param int   $mission - fleet mission
481
 * @param array $options
482
 *
483
 * @return int
484
 * @throws Exception
485
 * @see flt_can_attack()
486
 */
487
function flt_t_send_fleet($user, &$from, $to, $fleet, $resources, $mission, $options = array()) {
488
  $internal_transaction = !db_mysql::db_transaction_check(false) ? db_mysql::db_transaction_start() : false;
489
490
  // TODO Потенциальный дедлок - если успела залочится запись пользователя - хозяина планеты
491
  $user = db_user_by_id($user['id'], true);
0 ignored issues
show
Deprecated Code introduced by
The function db_user_by_id() has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

491
  $user = /** @scrutinizer ignore-deprecated */ db_user_by_id($user['id'], true);
Loading history...
492
  $from = sys_o_get_updated($user['id'], $from['id'], SN_TIME_NOW);
493
  $from = $from['planet'];
494
495
//  $fleet = [
496
//    202 => 1,
497
//  ];
498
//  $resources = [
499
//    901 => 1,
500
//  ];
501
//  var_dump($fleet);
502
//  var_dump($resources);
503
//  var_dump(mrc_get_level($user, $from, 202));
504
//  var_dump($from['metal']);
505
//  var_dump($from['deuterium']);
506
//  die();
507
508
509
  !is_array($resources) ? $resources = [] : false;
510
  if (empty($options[P_FLEET_ATTACK_RES_LIST])) {
511
    $options[P_FLEET_ATTACK_RES_LIST] = $resources;
512
  }
513
  $can_attack = flt_can_attack($from, $to, $fleet, $mission, $options);
514
  if ($can_attack != ATTACK_ALLOWED) {
515
    $internal_transaction ? db_mysql::db_transaction_rollback() : false;
516
517
    return $can_attack;
518
  }
519
520
  empty($options[P_FLEET_ATTACK_SPEED_PERCENT_TENTH]) ? $options[P_FLEET_ATTACK_SPEED_PERCENT_TENTH] = 10 : false;
521
  $options[P_FLEET_ATTACK_STAY_TIME] = !empty($options[P_FLEET_ATTACK_STAY_TIME]) ? $options[P_FLEET_ATTACK_STAY_TIME] * PERIOD_HOUR : 0;
522
523
  $fleetObj    = new Fleet();
524
  $travel_data = $fleetObj
525
    ->setMission($mission)
526
    ->setSourceFromPlanetRecord($from)
527
    ->setDestinationFromPlanetRecord($to)
528
    ->setUnits($fleet)
529
    ->setUnits($resources)
530
    ->setSpeedPercentInTenth($options[P_FLEET_ATTACK_SPEED_PERCENT_TENTH])
531
    ->calcTravelTimes(SN_TIME_NOW, $options[P_FLEET_ATTACK_STAY_TIME]);
532
  $fleetObj->save();
533
534
  $result = fltSendFleetAdjustPlanetResources($from['id'], $resources, $travel_data['consumption']);
0 ignored issues
show
Unused Code introduced by
The assignment to $result is dead and can be removed.
Loading history...
535
536
  $result = fltSendFleetAdjustPlanetUnits($user, $from['id'], $fleet);
537
538
  $internal_transaction ? db_mysql::db_transaction_commit() : false;
539
540
  $from = DBStaticPlanet::db_planet_by_id($from['id']);
541
542
//  var_dump(mrc_get_level($user, $from, 202));
543
//  var_dump($from['metal']);
544
//  var_dump($from['deuterium']);
545
//  die();
546
547
  return ATTACK_ALLOWED;
548
}
549
550
/**
551
 * @param array      $user
552
 * @param int|string $fromId
553
 * @param float[]    $fleet - [(int)shipId => (float)count]
554
 *
555
 * @return bool
556
 */
557
function fltSendFleetAdjustPlanetUnits($user, $fromId, $fleet) {
558
  $result = [];
559
560
  foreach ($fleet as $unit_id => $amount) {
561
    if (floatval($amount) >= 1 && intval($unit_id) && in_array($unit_id, sn_get_groups('fleet'))) {
562
      $result[] = OldDbChangeSet::db_changeset_prepare_unit($unit_id, -$amount, $user, $fromId);
0 ignored issues
show
Deprecated Code introduced by
The function DBAL\OldDbChangeSet::db_changeset_prepare_unit() has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

562
      $result[] = /** @scrutinizer ignore-deprecated */ OldDbChangeSet::db_changeset_prepare_unit($unit_id, -$amount, $user, $fromId);
Loading history...
563
    }
564
  }
565
566
  return OldDbChangeSet::db_changeset_apply(['unit' => $result]);
0 ignored issues
show
Deprecated Code introduced by
The function DBAL\OldDbChangeSet::db_changeset_apply() has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

566
  return /** @scrutinizer ignore-deprecated */ OldDbChangeSet::db_changeset_apply(['unit' => $result]);
Loading history...
567
}
568
569
/**
570
 * @param int|string $fromId      - Source planet ID
571
 * @param array      $resources   - Array of resources to transfer [(int)resourceId => (float)amount]
572
 * @param int|float  $consumption - Fleet consumption
573
 *
574
 * @return bool
575
 *
576
 * @throws Exception
577
 */
578
function fltSendFleetAdjustPlanetResources($fromId, $resources, $consumption) {
579
  $planetObj = SN::$gc->repoV2->getPlanet($fromId);
580
581
  $planetObj->changeResource(RES_DEUTERIUM, -$consumption);
582
583
  foreach ($resources as $resource_id => $amount) {
584
    if (floatval($amount) >= 1 && intval($resource_id) && in_array($resource_id, sn_get_groups('resources_loot'))) {
585
      $planetObj->changeResource($resource_id, -$amount);
586
    }
587
  }
588
589
  return $planetObj->save();
590
}
591
592
function flt_calculate_ship_to_transport_sort($a, $b) {
593
  return $a['transport_effectivness'] == $b['transport_effectivness'] ? 0 : ($a['transport_effectivness'] > $b['transport_effectivness'] ? -1 : 1);
594
}
595
596
// flt_calculate_ship_to_transport - calculates how many ships need to transport pointed amount of resources
597
// $ship_list - list of available ships
598
// $resource_amount - how much amount of resources need to be transported
599
// $from - transport from
600
// $to - transport to
601
function flt_calculate_fleet_to_transport($ship_list, $resource_amount, $from, $to) {
602
  global $user;
603
604
  $ship_data   = array();
605
  $fleet_array = array();
606
  foreach ($ship_list as $transport_id => $cork) {
607
    $ship_data[$transport_id] = flt_travel_data($user, $from, $to, array($transport_id => 1), 10);
608
  }
609
  uasort($ship_data, 'flt_calculate_ship_to_transport_sort');
610
611
  $fleet_hold     = 0;
0 ignored issues
show
Unused Code introduced by
The assignment to $fleet_hold is dead and can be removed.
Loading history...
612
  $fleet_capacity = 0;
613
  $fuel_total     = $fuel_left = mrc_get_level($user, $from, RES_DEUTERIUM);
614
  foreach ($ship_data as $transport_id => &$ship_info) {
615
    $ship_loaded = min($ship_list[$transport_id], ceil($resource_amount / $ship_info['hold']), floor($fuel_left / $ship_info['consumption']));
616
    if ($ship_loaded) {
617
      $fleet_array[$transport_id] = $ship_loaded;
618
      $resource_amount            -= min($resource_amount, $ship_info['hold'] * $ship_loaded);
619
      $fuel_left                  -= $ship_info['consumption'] * $ship_loaded;
620
621
      $fleet_capacity += $ship_info['capacity'] * $ship_loaded;
622
    }
623
  }
624
625
  return array('fleet' => $fleet_array, 'ship_data' => $ship_data, 'capacity' => $fleet_capacity, 'consumption' => $fuel_total - $fuel_left);
626
}
627