Completed
Push — work-fleets ( d1f99e...fc0000 )
by SuperNova.WS
06:40
created

classes/FleetValidator.php (1 issue)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
use DBStatic\DBStaticFleetBashing;
3
use Exception\ExceptionFleetInvalid;
4
5
/**
6
 * Class FleetValidator
7
 */
8
class FleetValidator {
9
  /**
10
   * @var Fleet $fleet
11
   */
12
  protected $fleet;
13
14
  protected static $conditionsGlobal = array(
15
    // Cheap checks - class Fleet already have all this info internally
16
    'checkSpeedPercentOld'       => FLIGHT_FLEET_SPEED_WRONG,
17
    'checkTargetInUniverse'      => FLIGHT_VECTOR_BEYOND_UNIVERSE,
18
    'checkTargetNotSource'       => FLIGHT_VECTOR_SAME_SOURCE,
19
    'checkSenderNoVacation'      => FLIGHT_PLAYER_VACATION_OWN,  // tODO
20
    'checkTargetNoVacation'      => FLIGHT_PLAYER_VACATION,
21
    'checkFleetNotEmpty'         => FLIGHT_SHIPS_NO_SHIPS,
22
    // 'checkUnitsPositive'         => FLIGHT_SHIPS_NEGATIVE, // Unused - 'cause it's not allowed to put negative units into Unit class
23
    // 'checkOnlyFleetUnits'        => FLIGHT_SHIPS_UNIT_WRONG, // Unused - 'cause it's only possible to pass to fleet SHIP or RESOURCE
24
    'checkOnlyFlyingUnits'       => FLIGHT_SHIPS_UNMOVABLE,
25
    'checkResourcesPositive'     => FLIGHT_RESOURCES_NEGATIVE,
26
    'checkNotTooFar'             => FLIGHT_FLEET_TOO_FAR,
27
    'checkEnoughCapacity'        => FLIGHT_FLEET_OVERLOAD,
28
29
    // checkMissionAllowed
30
    // consumptionIsNegative ??????
31
32
    // Medium checks - currently requires access to DB but potentially doesn't
33
    'checkSourceEnoughShips'     => FLIGHT_SHIPS_NOT_ENOUGH,
34
    'checkSourceEnoughFuel'      => FLIGHT_RESOURCES_FUEL_NOT_ENOUGH,
35
    'checkSourceEnoughResources' => FLIGHT_RESOURCES_NOT_ENOUGH,
36
37
    'checkMultiAccountNot'            => FLIGHT_PLAYER_SAME_IP,
38
39
    // Heavy checks - will absolutely require DB access
40
    'checkEnoughFleetSlots'           => FLIGHT_FLEET_NO_SLOTS,
41
42
    // TODO - THIS CHECKS SHOULD BE ADDED IN UNIT_CAPTAIN MODULE!
43
    'checkCaptainSent'                => array(
44
      true => array(
45
        'checkCaptainExists'         => FLIGHT_CAPTAIN_NOT_HIRED,
46
        'checkCaptainOnPlanetType'   => FLIGHT_CAPTAIN_ALREADY_FLYING,
47
        'checkCaptainOnPlanetSource' => FLIGHT_CAPTAIN_ON_OTHER_PLANET,
48
        'checkCaptainNotRelocating'  => FLIGHT_CAPTAIN_RELOCATE_LOCK,
49
      ),
50
    ),
51
  );
52
53
54
  /**
55
   * FleetValidator constructor.
56
   *
57
   * @param Fleet $fleet
58
   */
59
  public function __construct($fleet) {
60
    $this->fleet = $fleet;
61
  }
62
63
  /**
64
   *
65
   */
66
  public function validateGlobals() {
67
//    print('Validate globals<br/>');
68
    $this->checkMissionRestrictions(self::$conditionsGlobal);
69
//    print('Globals validated<br/>');
70
71
//    try {
72
//      // TODO - Do the restrictMission checks
73
//
74
//      // TODO - Кое-какие проверки дают FLIGHT_ALLOWED - ЧТО НЕПРАВДА В ДАННОМ СЛУЧАЕ!!!
75
//      // На странице 1 некоторые проверки ДОЛЖНЫ БЫТЬ опущены - иначе будет некрасиво
76
//      // А вот здесь надо проверять много дополнительной хуйни
77
//      $this->checkMissionRestrictions($checklist);
78
////pdump('passed');
79
//
80
//      // 2nd level restrictions
81
//      // Still cheap
82
////      $this->restrict2ToAllowedMissions();
83
////      $this->restrict2ToAllowedPlanetTypes();
84
//    } catch (Exception\ExceptionFleetInvalid $e) {
85
////pdump($e->getCode(), '$e->getCode()');
86
////pdump($e->getMessage(), '$e->getMessage()');
87
//      if ($e->getCode() != FLIGHT_ALLOWED) {
88
//        pdie(classLocale::$lang['fl_attack_error'][$e->getCode()]);
89
//      } else {
90
//        pdump('FLIGHT_ALLOWED', FLIGHT_ALLOWED);
91
//      }
92
//    }
93
  }
94
95
  /**
96
   *
97
   */
98
  public function validate() {
99
    $checklist = sn_get_groups('mission_checks');
100
101
    $this->checkMissionRestrictions($checklist);
102
103
//    try {
104
//      // TODO - Do the restrictMission checks
105
//
106
//      // TODO - Кое-какие проверки дают FLIGHT_ALLOWED - ЧТО НЕПРАВДА В ДАННОМ СЛУЧАЕ!!!
107
//      // На странице 1 некоторые проверки ДОЛЖНЫ БЫТЬ опущены - иначе будет некрасиво
108
//      // А вот здесь надо проверять много дополнительной хуйни
109
//      $this->checkMissionRestrictions($checklist);
110
////pdump('passed');
111
//
112
//      // 2nd level restrictions
113
//      // Still cheap
114
////      $this->restrict2ToAllowedMissions();
115
////      $this->restrict2ToAllowedPlanetTypes();
116
//    } catch (Exception\ExceptionFleetInvalid $e) {
117
////pdump($e->getCode(), '$e->getCode()');
118
////pdump($e->getMessage(), '$e->getMessage()');
119
//      if ($e->getCode() != FLIGHT_ALLOWED) {
120
//        pdie(classLocale::$lang['fl_attack_error'][$e->getCode()]);
121
//      } else {
122
//        pdump('FLIGHT_ALLOWED', FLIGHT_ALLOWED);
123
//      }
124
//    }
125
    pdump('// TODO - Сделать flletvalidator DI - внутре контейнер для методов, а методы - анонимные функции, вызывающие другие методы же', FLIGHT_ALLOWED);
126
  }
127
128
  /**
129
   * @param array $checklist
130
   *
131
   * @throws Exception
132
   */
133
  public function checkMissionRestrictions($checklist, $exception = true) {
134
    foreach ($checklist as $condition => $action) {
135
136
      $checkResult = call_user_func(array($this, $condition));
137
      defined('DEBUG_FLEET_MISSION_VALIDATE_DUMP_STEPS')
138
        ? pdump($action, $condition . ' ' . ($checkResult ? 'TRUE' : 'FALSE')) : false;
139
140
      // If check failed and there no alternative actions - throw exception
141
      // Shortcut ACTION => FAIL_STATUS instead of ACTION => array(false => FAIL_STATUS)
142
      if (!$checkResult && !is_array($action)) {
143
        throw new ExceptionFleetInvalid($action, $action);
144
      }
145
146
      // If no actions on current result - just skipping to next condition
147
      if (!isset($action[$checkResult])) {
148
        // If not - just continuing
149
        continue;
150
      }
151
152
      // Otherwise - we got some action for current result
153
      $action = $action[$checkResult];
154
155
      // Is it a list of conditions?
156
      if (is_array($action)) {
157
        // Yes - performing condition check
158
        $this->checkMissionRestrictions($action);
159
      } else {
160
        // No - then just performing action
161
        if($exception) {
162
          throw new ExceptionFleetInvalid($action, $action);
163
        } else {
164
          return $action;
165
        }
166
      }
167
    }
168
169
    return FLIGHT_ALLOWED;
170
  }
171
172
173
  /**
174
   * @throws Exception
175
   */
176
  protected function restrict2ToAllowedMissions() {
177
    if (empty($this->fleet->allowed_missions[$this->fleet->mission_type])) {
178
      throw new Exception('FLIGHT_MISSION_IMPOSSIBLE', FLIGHT_MISSION_IMPOSSIBLE);
179
    }
180
  }
181
182
  /**
183
   * @throws Exception
184
   */
185
  protected function restrict2ToAllowedPlanetTypes() {
186
    if (empty($this->fleet->allowed_planet_types[$this->fleet->targetVector->type])) {
187
      throw new Exception('FLIGHT_MISSION_IMPOSSIBLE', FLIGHT_MISSION_IMPOSSIBLE);
188
    }
189
  }
190
191
192
  /**
193
   * @return bool
194
   */
195
  protected function checkSpeedPercentOld() {
196
    return in_array($this->fleet->oldSpeedInTens, array(10, 9, 8, 7, 6, 5, 4, 3, 2, 1));
197
  }
198
199
  /**
200
   * @return bool
201
   */
202
  protected function checkSenderNoVacation() {
203
    return empty($this->fleet->dbOwnerRow['vacation']) || $this->fleet->dbOwnerRow['vacation'] <= SN_TIME_NOW;
204
  }
205
206
  /**
207
   * @return bool
208
   */
209
  protected function checkTargetNoVacation() {
210
    return empty($this->fleet->dbTargetOwnerRow['vacation']) || $this->fleet->dbTargetOwnerRow['vacation'] >= SN_TIME_NOW;
211
  }
212
213
  /**
214
   * @return bool
215
   */
216
  protected function checkMultiAccountNot() {
217
    return !sys_is_multiaccount($this->fleet->dbOwnerRow, $this->fleet->dbTargetOwnerRow);
218
  }
219
220
  /**
221
   * @return bool
222
   */
223
  protected function checkTargetNotSource() {
224
    return !$this->fleet->targetVector->isSameLocation($this->fleet->dbSourcePlanetRow);
225
  }
226
227
  /**
228
   * @return bool
229
   */
230
  protected function checkTargetInUniverse() {
231
    return $this->fleet->targetVector->isInUniverse();
232
  }
233
234
  /**
235
   * @return bool
236
   */
237
  protected function checkUnitsPositive() {
238
    return $this->fleet->shipsAllPositive();
239
  }
240
241
  /**
242
   * @return bool
243
   */
244
  protected function checkOnlyFleetUnits() {
245
    return $this->fleet->shipsAllFlying();
246
  }
247
248
  /**
249
   * @return bool
250
   */
251
  protected function checkOnlyFlyingUnits() {
252
    return $this->fleet->shipsAllMovable();
253
  }
254
255
  /**
256
   * @return bool
257
   */
258
  protected function checkEnoughFleetSlots() {
259
    return FleetList::fleet_count_flying($this->fleet->getPlayerOwnerId()) < GetMaxFleets($this->fleet->dbOwnerRow);
260
  }
261
262
263
  /**
264
   * @return bool
265
   */
266
  protected function checkEnoughCapacity($includeResources = true) {
267
    $checkVia = $this->fleet->travelData['consumption'];
268
    $checkVia = ceil(($includeResources ? array_sum($this->fleet->resource_list) : 0) + $checkVia);
269
270
    return
271
      !empty($this->fleet->travelData) &&
272
      is_array($this->fleet->travelData) &&
273
      floor($this->fleet->travelData['capacity']) >= $checkVia;
274
  }
275
276
  /**
277
   * @return bool
278
   */
279
  protected function checkNotTooFar() {
280
    return $this->checkEnoughCapacity(false);
281
  }
282
283
  /**
284
   * @return bool
285
   */
286
  protected function checkDebrisExists() {
287
    return is_array($this->fleet->dbTargetRow) && ($this->fleet->dbTargetRow['debris_metal'] + $this->fleet->dbTargetRow['debris_crystal'] > 0);
288
  }
289
290
291
292
293
294
295
296
297
298
299
300
301
  // Resources checks
302
303
  /**
304
   * @return bool
305
   */
306
  protected function checkResourcesPositive() {
307
    foreach ($this->fleet->resource_list as $resourceId => $resourceAmount) {
308
      if ($resourceAmount < 0) {
309
        return false;
310
      }
311
    }
312
313
    return true;
314
  }
315
316
  /**
317
   * @return bool
318
   */
319
  protected function checkCargo() {
320
    return array_sum($this->fleet->resource_list) >= 1;
321
  }
322
323
  /**
324
   * @return bool
325
   */
326
  protected function checkSourceEnoughFuel() {
327
    $deuteriumOnPlanet = mrc_get_level($this->fleet->dbOwnerRow, $this->fleet->dbSourcePlanetRow, RES_DEUTERIUM);
328
329
    return $deuteriumOnPlanet > ceil($this->fleet->travelData['consumption']);
330
  }
331
332
  /**
333
   * @return bool
334
   */
335
  protected function checkSourceEnoughResources() {
336
    $fleetResources = $this->fleet->resource_list;
337
    $fleetResources[RES_DEUTERIUM] = ceil($fleetResources[RES_DEUTERIUM] + $this->fleet->travelData['consumption']);
338
    foreach ($fleetResources as $resourceId => $resourceAmount) {
339
      if (mrc_get_level($this->fleet->dbOwnerRow, $this->fleet->dbSourcePlanetRow, $resourceId) < ceil($fleetResources[$resourceId])) {
340
        return false;
341
      }
342
    }
343
344
    return true;
345
  }
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
  // Target vector checks (????????)
372
373
  /**
374
   * @return bool
375
   */
376
  protected function checkKnownSpace() {
377
    return $this->fleet->targetVector->isInKnownSpace();
378
  }
379
380
  /**
381
   * @return bool
382
   */
383
  protected function checkUnKnownSpace() {
384
    return !$this->checkKnownSpace();
385
  }
386
387
  /**
388
   * @return bool
389
   */
390
  protected function checkTargetExists() {
391
    return !empty($this->fleet->dbTargetRow['id']);
392
  }
393
394
  /**
395
   * @return bool
396
   */
397
  protected function checkTargetNotExists() {
398
    return !$this->checkTargetExists();
399
  }
400
401
  /**
402
   * @return bool
403
   */
404
  protected function checkTargetIsPlanet() {
405
    return $this->fleet->targetVector->type == PT_PLANET;
406
  }
407
408
  /**
409
   * @return bool
410
   */
411
  protected function checkTargetIsDebris() {
412
    return $this->fleet->targetVector->type == PT_DEBRIS;
413
  }
414
415
  /**
416
   * @return bool
417
   */
418
  protected function checkTargetIsMoon() {
419
    return $this->fleet->targetVector->type == PT_MOON;
420
  }
421
422
423
424
425
426
427
  // Ships checks
428
429
  /**
430
   * @return bool
431
   */
432
  protected function checkFleetNotEmpty() {
433
    return $this->fleet->shipsGetTotal() >= 1;
434
  }
435
436
437
  /**
438
   * @return bool
439
   */
440
  protected function checkSourceEnoughShips() {
441
    return $this->fleet->shipsIsEnoughOnPlanet();
442
  }
443
444
445
  /**
446
   * @return bool
447
   */
448
  protected function checkHaveColonizer() {
449
    // Colonization fleet should have at least one colonizer
450
    return $this->fleet->shipsGetTotalById(SHIP_COLONIZER) >= 1;
451
  }
452
453
  /**
454
   * @return bool
455
   */
456
  protected function checkHaveRecyclers() {
457
    $recyclers = 0;
458
    foreach (classSupernova::$gc->groupRecyclers as $recycler_id) {
0 ignored issues
show
The expression \classSupernova::$gc->groupRecyclers of type array|object<Closure> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
459
      $recyclers += $this->fleet->shipsGetTotalById($recycler_id);
460
    }
461
462
    return $recyclers >= 1;
463
  }
464
465
  /**
466
   * @return bool
467
   */
468
  // TODO - used only as callable. Redo inversion
469
  protected function checkSpiesOnly() {
470
    return $this->fleet->shipsGetTotalById(SHIP_SPY) == $this->fleet->shipsGetTotal();
471
  }
472
473
  /**
474
   * @return bool
475
   */
476
  protected function checkNotOnlySpies() {
477
    return !$this->checkSpiesOnly();
478
  }
479
480
  /**
481
   * @return bool
482
   */
483
  protected function checkNoMissiles() {
484
    return
485
      $this->fleet->shipsGetTotalById(UNIT_DEF_MISSILE_INTERPLANET) == 0
486
      &&
487
      $this->fleet->shipsGetTotalById(UNIT_DEF_MISSILE_INTERCEPTOR) == 0;
488
  }
489
490
491
  /**
492
   * @return bool
493
   */
494
  protected function checkTargetOwn() {
495
    return $this->fleet->dbTargetRow['id_owner'] == $this->fleet->dbSourcePlanetRow['id_owner'];
496
  }
497
498
  /**
499
   * @return bool
500
   */
501
  protected function forceTargetOwn() {
502
    if ($result = $this->checkTargetOwn()) {
503
      unset($this->fleet->allowed_missions[MT_EXPLORE]);
504
      unset($this->fleet->allowed_missions[MT_COLONIZE]);
505
      unset($this->fleet->allowed_missions[MT_RECYCLE]);
506
      unset($this->fleet->allowed_missions[MT_MISSILE]);
507
508
      unset($this->fleet->allowed_missions[MT_SPY]);
509
510
      unset($this->fleet->allowed_missions[MT_ATTACK]);
511
      unset($this->fleet->allowed_missions[MT_ACS]);
512
      unset($this->fleet->allowed_missions[MT_DESTROY]);
513
    } else {
514
      unset($this->fleet->allowed_missions[MT_RELOCATE]);
515
    }
516
517
    return $result;
518
  }
519
520
  protected function checkMissionPeaceful() {
521
    return
522
      !$this->fleet->mission_type
523
      ||
524
      in_array($this->fleet->mission_type, array(
525
        MT_HOLD,
526
        MT_RELOCATE,
527
        MT_TRANSPORT,
528
      ));
529
  }
530
531
  /**
532
   * @return bool
533
   */
534
  protected function checkTargetOther() {
535
    return !$this->checkTargetOwn();
536
  }
537
538
539
  /**
540
   * @return bool
541
   */
542
  protected function alwaysFalse() {
543
    return false;
544
  }
545
546
547
  /**
548
   * @return bool
549
   */
550
  protected function checkTargetAllyDeposit() {
551
    $result = mrc_get_level($this->fleet->dbTargetOwnerRow, $this->fleet->dbTargetRow, STRUC_ALLY_DEPOSIT) >= 1;
552
    if (!$result) {
553
      unset($this->fleet->allowed_missions[MT_HOLD]);
554
    }
555
556
    return $result;
557
  }
558
559
  /**
560
   * @param int  $missionType
561
   * @param bool $exact
562
   *
563
   * @return bool
564
   */
565
  protected function checkMission($missionType, $exact = false) {
566
    return $this->fleet->mission_type == $missionType || (!$exact && $this->fleet->mission_type == MT_NONE);
567
  }
568
569
570
  /**
571
   * Check mission type OR no mission - and limits available missions to this type if positive
572
   *
573
   * @param int $missionType
574
   *
575
   * @return bool
576
   */
577
  protected function forceMission($missionType, $exact = false) {
578
    return $this->unsetMission($missionType, $this->checkMission($missionType, $exact), true);
579
  }
580
581
  protected function unsetMission($missionType, $result, $forceMission = false) {
582
    if (!$result) {
583
      unset($this->fleet->allowed_missions[$missionType]);
584
    } elseif ($forceMission) {
585
      $this->fleet->allowed_missions = array(
586
        $missionType => $this->fleet->exists_missions[$missionType],
587
      );
588
    }
589
590
    return $result;
591
  }
592
593
  /**
594
   * @param string $name
595
   * @param string $prefix
596
   *
597
   * @return int|false
598
   * @throws Exception
599
   */
600
  protected function checkMissionPrefix($name, $prefix) {
601
    $result = false;
602
    if (strpos($name, $prefix) === 0) {
603
      $mission = 'MT_' . strtoupper(substr($name, strlen($prefix)));
604
      if (!defined($mission)) {
605
        // TODO - Ну, как-то получше это обделать
606
        throw new Exception('Mission type "' . $mission . '" is not defined', FLIGHT_MISSION_UNKNOWN);
607
      }
608
609
      $result = constant($mission);
610
    }
611
612
    return $result;
613
  }
614
615
  public function __call($name, $arguments) {
616
    $result = null;
617
    if (($missionType = $this->checkMissionPrefix($name, 'unsetMission')) !== false) {
618
      $result = $this->unsetMission($missionType, false);
619
    } elseif (($missionType = $this->checkMissionPrefix($name, 'forceMissionExact')) !== false) {
620
      $result = $this->forceMission($missionType, true);
621
    } elseif (($missionType = $this->checkMissionPrefix($name, 'forceMission')) !== false) {
622
      $result = $this->forceMission($missionType, false);
623
    } elseif (($missionType = $this->checkMissionPrefix($name, 'checkMissionExact')) !== false) {
624
      $result = $this->checkMission($missionType, true);
625
    } elseif (($missionType = $this->checkMissionPrefix($name, 'checkMission')) !== false) {
626
      $result = $this->checkMission($missionType, false);
627
    }
628
629
    return $result;
630
  }
631
632
  /**
633
   * Just checks mission type
634
   *
635
   * @param int $missionType
636
   *
637
   * @return bool
638
   */
639
  // TODO - obsolete ??
640
  protected function checkMissionExact($missionType) {
641
    return $this->checkMission($missionType, true);
642
  }
643
644
645
  /**
646
   * @return bool
647
   */
648
  protected function checkNotEmptyMission() {
649
    return !empty($this->fleet->mission_type);
650
  }
651
652
  /**
653
   * @return bool
654
   */
655
  protected function checkRealFlight() {
656
    return $this->fleet->isRealFlight;
657
  }
658
659
660
  /**
661
   * @return bool
662
   */
663
  protected function unsetMissionSpyComplex() {
664
    unset($this->fleet->allowed_missions[MT_SPY]);
665
    if ($this->fleet->mission_type == MT_SPY) {
666
      if ($this->checkRealFlight()) {
667
        return false;
668
      }
669
      $this->fleet->mission_type = MT_NONE;
670
    }
671
672
    return true;
673
  }
674
675
676
  /**
677
   * @return bool
678
   */
679
  protected function checkMissionExists() {
680
    return !empty($this->fleet->exists_missions[$this->fleet->mission_type]);
681
  }
682
683
  /**
684
   * @return bool
685
   */
686
  protected function checkMissionAllowed() {
687
    return !empty($this->fleet->allowed_missions[$this->fleet->mission_type]);
688
  }
689
690
  /**
691
   * @return bool
692
   */
693
  protected function checkPlayerInactiveOrNotNoob() {
694
    return
695
      $this->checkTargetNotActive()
696
      ||
697
      $this->checkTargetNotNoob();
698
  }
699
700
  /**
701
   * @return bool
702
   */
703
  protected function checkTargetActive() {
704
    return
705
      empty($this->fleet->dbTargetOwnerRow['onlinetime'])
706
      ||
707
      SN_TIME_NOW - $this->fleet->dbTargetOwnerRow['onlinetime'] >= PLAYER_TIME_ACTIVE_SECONDS;
708
  }
709
710
  /**
711
   * @return bool
712
   */
713
  // TODO - REDO MAIN FUNCTION
714
  protected function checkTargetNotActive() {
715
    return !$this->checkTargetActive();
716
  }
717
718
719
  /**
720
   * @return bool
721
   */
722
  protected function checkSameAlly() {
723
    return !empty($this->fleet->dbTargetOwnerRow['ally_id']) && $this->fleet->dbTargetOwnerRow['ally_id'] == $this->fleet->dbOwnerRow['ally_id'];
724
  }
725
726
  /**
727
   * @return bool
728
   */
729
  protected function checkTargetNoob() {
730
    $user_points = $this->fleet->dbTargetOwnerRow['total_points'];
731
    $enemy_points = $this->fleet->dbTargetOwnerRow['total_points'];
732
733
    return
734
      // Target is under Noob Protection but Fleet owner is not
735
      (
736
        classSupernova::$config->game_noob_points
737
        &&
738
        $enemy_points <= classSupernova::$config->game_noob_points
739
        &&
740
        $user_points > classSupernova::$config->game_noob_points
741
      ) || (
742
        classSupernova::$config->game_noob_factor
743
        &&
744
        $user_points > $enemy_points * classSupernova::$config->game_noob_factor
745
      );
746
  }
747
748
  /**
749
   * @return bool
750
   */
751
  // TODO - REDO MAIN FUNCTION
752
  protected function checkTargetNotNoob() {
753
    return !$this->checkTargetNoob();
754
  }
755
756
757
  /**
758
   * @return bool
759
   */
760
  protected function checkMissionHoldReal() {
761
    return
762
      $this->checkRealFlight()
763
      &&
764
      $this->checkMissionExact(MT_HOLD);
765
  }
766
767
  /**
768
   * @return bool
769
   */
770
  protected function checkMissionHoldOnNotNoob() {
771
    return
772
      $this->checkTargetNotActive()
773
      ||
774
      ($this->checkSameAlly() && classSupernova::$config->ally_help_weak)
775
      ||
776
      $this->checkTargetNotNoob();
777
  }
778
779
780
  // Missiles
781
782
  /**
783
   * @return bool
784
   */
785
  protected function checkOnlyAttackMissiles() {
786
    $missilesAttack = $this->fleet->shipsGetTotalById(UNIT_DEF_MISSILE_INTERPLANET);
787
788
    return $missilesAttack != 0 && $missilesAttack == $this->fleet->shipsGetTotal();
789
  }
790
791
  /**
792
   * @return bool
793
   */
794
  protected function checkSiloLevel() {
795
    $sn_data_mip = get_unit_param(UNIT_DEF_MISSILE_INTERPLANET);
796
797
    return mrc_get_level($this->fleet->dbOwnerRow, $this->fleet->dbSourcePlanetRow, STRUC_SILO) >= $sn_data_mip[P_REQUIRE][STRUC_SILO];
798
  }
799
800
  /**
801
   * @return bool
802
   */
803
  protected function checkSameGalaxy() {
804
    return $this->fleet->targetVector->galaxy == $this->fleet->dbSourcePlanetRow['galaxy'];
805
  }
806
807
  /**
808
   * @return bool
809
   */
810
  protected function checkMissileDistance() {
811
    return abs($this->fleet->dbSourcePlanetRow['system'] - $this->fleet->targetVector->system) <= flt_get_missile_range($this->fleet->dbOwnerRow);
812
  }
813
814
  /**
815
   * @return bool
816
   */
817
  protected function checkMissileTarget() {
818
    return empty($this->fleet->targetedUnitId) || in_array($this->fleet->targetedUnitId, sn_get_groups('defense_active'));
819
  }
820
821
822
  /**
823
   * @return int
824
   */
825
  protected function checkExpeditionsMax() {
826
    return get_player_max_expeditons($this->fleet->dbOwnerRow) > 0;
827
  }
828
829
  /**
830
   * @return bool
831
   */
832
  protected function checkExpeditionsFree() {
833
    return get_player_max_expeditons($this->fleet->dbOwnerRow) > FleetList::fleet_count_flying($this->fleet->dbOwnerRow['id'], MT_EXPLORE);
834
  }
835
836
  /**
837
   * @return bool
838
   */
839
  protected function checkCaptainSent() {
840
    return $this->fleet->captainId >= 1;
841
  }
842
843
  /**
844
   * @return bool
845
   */
846
  protected function checkCaptainExists() {
847
    return !empty($this->fleet->captain) && is_array($this->fleet->captain);
848
  }
849
850
  /**
851
   * @return bool
852
   */
853
  protected function checkCaptainOnPlanetType() {
854
    return $this->fleet->captain['unit_location_type'] == $this->fleet->dbSourcePlanetRow['planet_type'];
855
  }
856
857
  /**
858
   * @return bool
859
   */
860
  protected function checkCaptainOnPlanetSource() {
861
    return $this->checkCaptainOnPlanetType() && $this->fleet->captain['unit_location_id'] == $this->fleet->dbSourcePlanetRow['id'];
862
  }
863
864
  /**
865
   * @return bool
866
   */
867
  protected function checkCaptainNotRelocating() {
868
    if ($this->fleet->mission_type == MT_RELOCATE) {
869
      $arriving_captain = mrc_get_level($this->fleet->dbOwnerRow, $this->fleet->dbTargetRow, UNIT_CAPTAIN, true);
870
    } else {
871
      $arriving_captain = false;
872
    }
873
874
    return empty($arriving_captain) || !is_array($arriving_captain);
875
  }
876
877
878
  /**
879
   * @return bool
880
   */
881
  protected function checkMissionDestroyReal() {
882
    return
883
      $this->checkRealFlight()
884
      &&
885
      $this->checkMissionExact(MT_DESTROY);
886
  }
887
888
  /**
889
   * @return bool
890
   */
891
  protected function checkHaveReapers() {
892
    $unitsTyped = 0;
893
    foreach (sn_get_groups('flt_reapers') as $unit_id) {
894
      $unitsTyped += $this->fleet->shipsGetTotalById($unit_id);
895
    }
896
897
    return $unitsTyped >= 1;
898
  }
899
900
901
  /**
902
   * @return bool
903
   */
904
  protected function checkMissionACSReal() {
905
    return
906
      $this->checkRealFlight()
907
      &&
908
      $this->checkMissionExact(MT_ACS);
909
  }
910
911
  protected function checkACSInTime() {
912
    return $this->fleet->acs['ankunft'] - $this->fleet->time_launch >= $this->fleet->travelData['duration'];
913
  }
914
915
916
  protected function checkMissionRealAndSelected($missionType) {
917
    return
918
      $this->checkRealFlight()
919
      &&
920
      $this->checkMissionExact($missionType);
921
  }
922
923
  protected function checkMissionResultAndUnset($missionType, $result, $forceMission = false) {
924
    $this->unsetMission($missionType, $result, $forceMission);
925
926
    return $result && $this->checkMissionRealAndSelected($missionType);
927
  }
928
929
930
  /**
931
   * @return bool
932
   */
933
  protected function checkMissionSpyPossibleAndReal() {
934
    return $this->checkMissionResultAndUnset(
935
      MT_SPY,
936
      $this->checkSpiesOnly() && $this->checkTargetOther(),
937
      true
938
    );
939
  }
940
941
  /**
942
   * @return bool
943
   */
944
  protected function checkMissionDestroyAndReal() {
945
    return $this->checkMissionResultAndUnset(
946
      MT_DESTROY,
947
      $this->checkTargetIsMoon() && $this->checkHaveReapers()
948
    );
949
  }
950
951
  /**
952
   * @return bool
953
   */
954
  protected function checkMissionHoldPossibleAndReal() {
955
    return $this->checkMissionResultAndUnset(
956
      MT_HOLD,
957
      $this->checkTargetAllyDeposit() && $this->checkMissionHoldOnNotNoob() && $this->checkNotOnlySpies()
958
    );
959
  }
960
961
  /**
962
   * @return bool
963
   */
964
  protected function checkSpiesOnlyFriendlyRestrictsToRelocate() {
965
    if ($result = $this->checkSpiesOnly()) {
966
      $this->fleet->allowed_missions = array(
967
        MT_RELOCATE => $this->fleet->exists_missions[MT_RELOCATE],
968
      );
969
    }
970
971
    return $result;
972
  }
973
974
975
  protected function checkFleetGroupACS() {
976
    $result = !empty($this->fleet->group_id) && !empty($this->fleet->acs);
977
    $this->unsetMission(MT_ACS, $result, true);
978
    if ($result) {
979
      $this->fleet->mission_type = MT_ACS;
980
    } else {
981
      $this->fleet->group_id = 0;
982
    }
983
984
    return $result;
985
  }
986
987
  protected function checkACSNotEmpty() {
988
    return !empty($this->fleet->acs);
989
  }
990
991
  /**
992
   * @return bool
993
   */
994
  protected function checkACSInvited() {
995
    $playersInvited = !empty($this->fleet->acs['eingeladen']) ? explode(',', $this->fleet->acs['eingeladen']) : array();
996
    foreach ($playersInvited as $playerId) {
997
      if (intval($playerId) == $this->fleet->dbOwnerRow['id']) {
998
        return true;
999
      }
1000
    }
1001
1002
    return false;
1003
  }
1004
1005
  /**
1006
   * @return bool
1007
   */
1008
  protected function checkMissionACSPossibleAndReal() {
1009
    return $this->checkMissionResultAndUnset(
1010
      MT_ACS,
1011
      $this->checkACSNotEmpty() && $this->checkACSInvited() && $this->checkACSInTime(),
1012
      true
1013
    );
1014
  }
1015
1016
  /**
1017
   * @return bool
1018
   */
1019
  protected function checkMissionTransportPossibleAndReal() {
1020
    return $this->checkMissionResultAndUnset(
1021
      MT_TRANSPORT,
1022
      $this->checkCargo() && $this->checkPlayerInactiveOrNotNoob() && $this->checkNotOnlySpies()
1023
    );
1024
  }
1025
1026
  /**
1027
   * @return bool
1028
   */
1029
  protected function checkMissionTransportReal() {
1030
    return
1031
      $this->checkMissionExact(MT_TRANSPORT)
1032
      &&
1033
      $this->checkRealFlight();
1034
  }
1035
1036
1037
  protected function checkBashingNotRestricted() {
1038
    return classSupernova::$config->fleet_bashing_attacks <= 0;
1039
  }
1040
1041
  protected function checkBashingBothAllies() {
1042
    return $this->fleet->dbOwnerRow['ally_id'] && $this->fleet->dbTargetOwnerRow['ally_id'];
1043
  }
1044
1045
  protected function checkBashingAlliesHaveRelationWar() {
1046
    return ali_relation($this->fleet->dbOwnerRow['ally_id'], $this->fleet->dbTargetOwnerRow['ally_id']) == ALLY_DIPLOMACY_WAR;
1047
  }
1048
1049
  protected function checkBashingBothAlliesAndRelationWar() {
1050
    return $this->checkBashingBothAllies() && $this->checkBashingAlliesHaveRelationWar();
1051
  }
1052
1053
  protected function checkBashingAlliesWarNoDelay() {
1054
    $user = $this->fleet->dbOwnerRow;
1055
    $enemy = $this->fleet->dbTargetOwnerRow;
1056
1057
    $relations = ali_relations($user['ally_id'], $enemy['ally_id']);
1058
1059
    return SN_TIME_NOW - $relations[$enemy['ally_id']]['alliance_diplomacy_time'] > classSupernova::$config->fleet_bashing_war_delay;
1060
  }
1061
1062
1063
  protected function checkBashingNone() {
1064
    $user = $this->fleet->dbOwnerRow;
1065
1066
    $time_limit = SN_TIME_NOW + $this->fleet->travelData['duration'] - classSupernova::$config->fleet_bashing_scope;
1067
    $bashing_list = array(SN_TIME_NOW);
1068
1069
    // Retrieving flying fleets
1070
    $objFleetsBashing = FleetList::dbGetFleetListBashing($user['id'], $this->fleet->dbTargetRow);
1071 View Code Duplication
    foreach ($objFleetsBashing->_container as $fleetBashing) {
1072
      // Checking for ACS - each ACS count only once
1073
      if ($fleetBashing->group_id) {
1074
        $bashing_list["{$user['id']}_{$fleetBashing->group_id}"] = $fleetBashing->time_arrive_to_target;
1075
      } else {
1076
        $bashing_list[] = $fleetBashing->time_arrive_to_target;
1077
      }
1078
    }
1079
1080
    // Check for joining to ACS - if there are already fleets in ACS no checks should be done
1081
    if ($this->fleet->mission_type == MT_ACS && $bashing_list["{$user['id']}_{$this->fleet->group_id}"]) {
1082
      return true;
1083
    }
1084
1085
    $query = DBStaticFleetBashing::db_bashing_list_get($user, $this->fleet->dbTargetRow, $time_limit);
1086
    while ($bashing_row = db_fetch($query)) {
1087
      $bashing_list[] = $bashing_row['bashing_time'];
1088
    }
1089
1090
    sort($bashing_list);
1091
1092
    $last_attack = 0;
1093
    $wave = 0;
1094
    $attack = 1;
1095
    foreach ($bashing_list as &$bash_time) {
1096
      $attack++;
1097
      if (
1098
        $bash_time - $last_attack > classSupernova::$config->fleet_bashing_interval
1099
        ||
1100
        $attack > classSupernova::$config->fleet_bashing_attacks
1101
      ) {
1102
        $wave++;
1103
        $attack = 1;
1104
      }
1105
1106
      $last_attack = $bash_time;
1107
    }
1108
1109
    return $wave <= classSupernova::$config->fleet_bashing_waves;
1110
  }
1111
1112
}
1113