Passed
Branch dev (39e428)
by Janko
20:42
created

Spacecraft::setDatabaseId()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 5
ccs 0
cts 3
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stu\Orm\Entity;
6
7
use Doctrine\Common\Collections\ArrayCollection;
8
use Doctrine\Common\Collections\Collection;
9
use Doctrine\ORM\Mapping\Column;
10
use Doctrine\ORM\Mapping\DiscriminatorColumn;
11
use Doctrine\ORM\Mapping\DiscriminatorMap;
12
use Doctrine\ORM\Mapping\Entity;
13
use Doctrine\ORM\Mapping\GeneratedValue;
14
use Doctrine\ORM\Mapping\Id;
15
use Doctrine\ORM\Mapping\InheritanceType;
16
use Doctrine\ORM\Mapping\JoinColumn;
17
use Doctrine\ORM\Mapping\ManyToOne;
18
use Doctrine\ORM\Mapping\OneToMany;
19
use Doctrine\ORM\Mapping\OneToOne;
20
use Doctrine\ORM\Mapping\OrderBy;
21
use Doctrine\ORM\Mapping\Table;
22
use Override;
0 ignored issues
show
Bug introduced by
The type Override was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
23
use RuntimeException;
24
use Stu\Component\Game\TimeConstants;
0 ignored issues
show
Bug introduced by
The type Stu\Component\Game\TimeConstants was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
25
use Stu\Component\Map\DirectionEnum;
26
use Stu\Component\Spacecraft\SpacecraftAlertStateEnum;
27
use Stu\Component\Spacecraft\SpacecraftModuleTypeEnum;
28
use Stu\Component\Spacecraft\SpacecraftRumpEnum;
0 ignored issues
show
Bug introduced by
The type Stu\Component\Spacecraft\SpacecraftRumpEnum was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
29
use Stu\Component\Spacecraft\SpacecraftStateEnum;
30
use Stu\Component\Spacecraft\SpacecraftLssModeEnum;
31
use Stu\Component\Spacecraft\SpacecraftTypeEnum;
32
use Stu\Component\Spacecraft\System\SpacecraftSystemTypeEnum;
33
use Stu\Component\Spacecraft\System\Type\TorpedoStorageShipSystem;
0 ignored issues
show
Bug introduced by
The type Stu\Component\Spacecraft...orpedoStorageShipSystem was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
34
use Stu\Component\Spacecraft\System\Type\TractorBeamShipSystem;
35
use Stu\Lib\Transfer\CommodityTransfer;
36
use Stu\Module\Control\GameControllerInterface;
37
use Stu\Module\Logging\LoggerUtilInterface;
38
use Stu\Module\Spacecraft\Lib\Battle\FightLib;
39
use Stu\Orm\Repository\SpacecraftRepository;
40
41
#[Table(name: 'stu_spacecraft')]
42
#[Entity(repositoryClass: SpacecraftRepository::class)]
43
#[InheritanceType('JOINED')]
44
#[DiscriminatorColumn(name: 'type', type: 'string')]
45
#[DiscriminatorMap([
46
    SpacecraftTypeEnum::SHIP->value => Ship::class,
47
    SpacecraftTypeEnum::STATION->value => Station::class
48
])]
49
abstract class Spacecraft implements SpacecraftInterface
50
{
51
    #[Id]
52
    #[Column(type: 'integer')]
53
    #[GeneratedValue(strategy: 'IDENTITY')]
54
    private ?int $id = null;
55
56
    #[Column(type: 'integer')]
57
    private int $user_id = 0;
58
59
    #[Column(type: 'integer')]
60
    private int $rump_id = 0;
0 ignored issues
show
introduced by
The private property $rump_id is not used, and could be removed.
Loading history...
61
62
    #[Column(type: 'integer', nullable: true)]
63
    private ?int $plan_id = null;
0 ignored issues
show
introduced by
The private property $plan_id is not used, and could be removed.
Loading history...
64
65
    #[Column(type: 'smallint', length: 1, enumType: DirectionEnum::class, nullable: true)]
66
    private ?DirectionEnum $direction = null;
67
68
    #[Column(type: 'string')]
69
    private string $name = '';
70
71
    #[Column(type: 'smallint', length: 1, enumType: SpacecraftAlertStateEnum::class)]
72
    private SpacecraftAlertStateEnum $alvl = SpacecraftAlertStateEnum::ALERT_GREEN;
73
74
    #[Column(type: 'smallint', length: 1, enumType: SpacecraftLssModeEnum::class)]
75
    private SpacecraftLssModeEnum $lss_mode = SpacecraftLssModeEnum::LSS_NORMAL;
76
77
    #[Column(type: 'integer', length: 6)]
78
    private int $huelle = 0;
79
80
    #[Column(type: 'integer', length: 6)]
81
    private int $max_huelle = 0;
82
83
    #[Column(type: 'integer', length: 6)]
84
    private int $schilde = 0;
85
86
    #[Column(type: 'integer', length: 6)]
87
    private int $max_schilde = 0;
88
89
    #[Column(type: 'integer', nullable: true)]
90
    private ?int $tractored_ship_id = null;
91
92
    #[Column(type: 'integer', nullable: true)]
93
    private ?int $holding_web_id = null;
94
95
    #[Column(type: 'integer', nullable: true)]
96
    private ?int $database_id = null;
97
98
    private bool $is_destroyed = false;
99
100
    #[Column(type: 'boolean')]
101
    private bool $disabled = false;
102
103
    #[Column(type: 'smallint', length: 3)]
104
    private int $hit_chance = 0;
105
106
    #[Column(type: 'smallint', length: 3)]
107
    private int $evade_chance = 0;
108
109
    #[Column(type: 'smallint', length: 4)]
110
    private int $base_damage = 0;
111
112
    #[Column(type: 'smallint', length: 3)]
113
    private int $sensor_range = 0;
114
115
    #[Column(type: 'integer')]
116
    private int $shield_regeneration_timer = 0;
117
118
    #[Column(type: 'smallint', enumType: SpacecraftStateEnum::class)]
119
    private SpacecraftStateEnum $state = SpacecraftStateEnum::SHIP_STATE_NONE;
120
121
    #[Column(type: 'integer')]
122
    private int $location_id = 0;
0 ignored issues
show
introduced by
The private property $location_id is not used, and could be removed.
Loading history...
123
124
    #[Column(type: 'boolean')]
125
    private bool $in_emergency = false;
126
127
    #[OneToOne(targetEntity: 'Ship')]
128
    #[JoinColumn(name: 'tractored_ship_id', referencedColumnName: 'id')]
129
    private ?ShipInterface $tractoredShip = null;
130
131
    #[ManyToOne(targetEntity: 'TholianWeb')]
132
    #[JoinColumn(name: 'holding_web_id', referencedColumnName: 'id', onDelete: 'CASCADE')]
133
    private ?TholianWebInterface $holdingWeb = null;
134
135
    #[ManyToOne(targetEntity: 'User')]
136
    #[JoinColumn(name: 'user_id', referencedColumnName: 'id', onDelete: 'CASCADE')]
137
    private UserInterface $user;
138
139
    /**
140
     * @var ArrayCollection<int, CrewAssignmentInterface>
141
     */
142
    #[OneToMany(targetEntity: 'CrewAssignment', mappedBy: 'spacecraft', indexBy: 'id')]
143
    #[OrderBy(['id' => 'ASC'])]
144
    private Collection $crew;
145
146
    #[OneToOne(targetEntity: 'TorpedoStorage', mappedBy: 'spacecraft')]
147
    private ?TorpedoStorageInterface $torpedoStorage = null;
148
149
    /**
150
     * @var ArrayCollection<int, SpacecraftSystemInterface>
151
     */
152
    #[OneToMany(targetEntity: 'SpacecraftSystem', mappedBy: 'spacecraft', indexBy: 'system_type')]
153
    #[OrderBy(['system_type' => 'ASC'])]
154
    private Collection $systems;
155
156
    #[ManyToOne(targetEntity: 'SpacecraftRump')]
157
    #[JoinColumn(name: 'rump_id', referencedColumnName: 'id')]
158
    private SpacecraftRumpInterface $rump;
159
160
    #[ManyToOne(targetEntity: 'SpacecraftBuildplan')]
161
    #[JoinColumn(name: 'plan_id', referencedColumnName: 'id', onDelete: 'CASCADE')]
162
    private ?SpacecraftBuildplanInterface $buildplan = null;
163
164
    /**
165
     * @var ArrayCollection<int, StorageInterface>
166
     */
167
    #[OneToMany(targetEntity: 'Storage', mappedBy: 'spacecraft', indexBy: 'commodity_id')]
168
    #[OrderBy(['commodity_id' => 'ASC'])]
169
    private Collection $storage;
170
171
    #[ManyToOne(targetEntity: 'Location')]
172
    #[JoinColumn(name: 'location_id', referencedColumnName: 'id')]
173
    private LocationInterface $location;
174
175
    /**
176
     * @var ArrayCollection<int, ShipLogInterface>
177
     */
178
    #[OneToMany(targetEntity: 'ShipLog', mappedBy: 'spacecraft', fetch: 'EXTRA_LAZY')]
179
    #[OrderBy(['id' => 'DESC'])]
180
    private Collection $logbook;
181
182
    #[OneToOne(targetEntity: 'ShipTakeover', mappedBy: 'source')]
183
    private ?ShipTakeoverInterface $takeoverActive = null;
184
185
    #[OneToOne(targetEntity: 'ShipTakeover', mappedBy: 'target')]
186
    private ?ShipTakeoverInterface $takeoverPassive = null;
187
188 3
    public function __construct()
189
    {
190 3
        $this->crew = new ArrayCollection();
191 3
        $this->systems = new ArrayCollection();
192 3
        $this->storage = new ArrayCollection();
193 3
        $this->logbook = new ArrayCollection();
194
    }
195
196 41
    #[Override]
197
    public function getId(): int
198
    {
199 41
        if ($this->id === null) {
200
            throw new RuntimeException('entity not yet persisted');
201
        }
202
203 41
        return $this->id;
204
    }
205
206 1
    #[Override]
207
    public function getUserId(): int
208
    {
209 1
        return $this->user_id;
210
    }
211
212 6
    #[Override]
213
    public function getUserName(): string
214
    {
215 6
        return $this->getUser()->getName();
216
    }
217
218
    #[Override]
219
    public function getSystemsId(): ?int
220
    {
221
        return $this->getSystem() !== null ? $this->getSystem()->getId() : null;
222
    }
223
224 3
    #[Override]
225
    public function getLayer(): ?LayerInterface
226
    {
227 3
        return $this->getLocation()->getLayer();
228
    }
229
230
    #[Override]
231
    public function getFlightDirection(): ?DirectionEnum
232
    {
233
        return $this->direction;
234
    }
235
236
    #[Override]
237
    public function setFlightDirection(DirectionEnum $direction): SpacecraftInterface
238
    {
239
        $this->direction = $direction;
240
        return $this;
241
    }
242
243 33
    #[Override]
244
    public function getName(): string
245
    {
246 33
        return $this->name;
247
    }
248
249
    #[Override]
250
    public function setName(string $name): SpacecraftInterface
251
    {
252
        $this->name = $name;
253
        return $this;
254
    }
255
256 2
    #[Override]
257
    public function getLssMode(): SpacecraftLssModeEnum
258
    {
259 2
        return $this->lss_mode;
260
    }
261
262
    #[Override]
263
    public function setLssMode(SpacecraftLssModeEnum $lssMode): SpacecraftInterface
264
    {
265
        $this->lss_mode = $lssMode;
266
        return $this;
267
    }
268
269 6
    #[Override]
270
    public function getAlertState(): SpacecraftAlertStateEnum
271
    {
272 6
        return $this->alvl;
273
    }
274
275
    #[Override]
276
    public function setAlertState(SpacecraftAlertStateEnum $state): SpacecraftInterface
277
    {
278
        $this->alvl = $state;
279
        return $this;
280
    }
281
282
    #[Override]
283
    public function setAlertStateGreen(): SpacecraftInterface
284
    {
285
        return $this->setAlertState(SpacecraftAlertStateEnum::ALERT_GREEN);
286
    }
287
288 20
    #[Override]
289
    public function isSystemHealthy(SpacecraftSystemTypeEnum $type): bool
290
    {
291 20
        if (!$this->hasSpacecraftSystem($type)) {
292 17
            return false;
293
        }
294
295 7
        return $this->getSpacecraftSystem($type)->isHealthy();
296
    }
297
298 32
    #[Override]
299
    public function getSystemState(SpacecraftSystemTypeEnum $type): bool
300
    {
301 32
        if (!$this->hasSpacecraftSystem($type)) {
302 30
            return false;
303
        }
304
305 12
        return $this->getSpacecraftSystem($type)->getMode()->isActivated();
306
    }
307
308 4
    #[Override]
309
    public function getImpulseState(): bool
310
    {
311 4
        return $this->getSystemState(SpacecraftSystemTypeEnum::IMPULSEDRIVE);
312
    }
313
314 6
    #[Override]
315
    public function getWarpDriveState(): bool
316
    {
317 6
        return $this->getSystemState(SpacecraftSystemTypeEnum::WARPDRIVE);
318
    }
319
320 2
    #[Override]
321
    public function isWarped(): bool
322
    {
323 2
        return $this->getWarpDriveState();
324
    }
325
326 4
    #[Override]
327
    public function getWebState(): bool
328
    {
329 4
        return $this->getHoldingWeb() !== null;
330
    }
331
332 30
    #[Override]
333
    public function getCloakState(): bool
334
    {
335 30
        return $this->getSystemState(SpacecraftSystemTypeEnum::CLOAK);
336
    }
337
338 2
    #[Override]
339
    public function getTachyonState(): bool
340
    {
341 2
        return $this->getSystemState(SpacecraftSystemTypeEnum::TACHYON_SCANNER);
342
    }
343
344 1
    #[Override]
345
    public function getSubspaceState(): bool
346
    {
347 1
        return $this->getSystemState(SpacecraftSystemTypeEnum::SUBSPACE_SCANNER);
348
    }
349
350
    #[Override]
351
    public function getRPGModuleState(): bool
352
    {
353
        return $this->getSystemState(SpacecraftSystemTypeEnum::RPG_MODULE);
354
    }
355
356 14
    #[Override]
357
    public function getHull(): int
358
    {
359 14
        return $this->huelle;
360
    }
361
362
    #[Override]
363
    public function setHuell(int $hull): SpacecraftInterface
364
    {
365
        $this->huelle = $hull;
366
        return $this;
367
    }
368
369 14
    #[Override]
370
    public function getMaxHull(): int
371
    {
372 14
        return $this->max_huelle;
373
    }
374
375
    #[Override]
376
    public function setMaxHuell(int $maxHull): SpacecraftInterface
377
    {
378
        $this->max_huelle = $maxHull;
379
        return $this;
380
    }
381
382 9
    #[Override]
383
    public function getShield(): int
384
    {
385 9
        return $this->schilde;
386
    }
387
388
    #[Override]
389
    public function setShield(int $schilde): SpacecraftInterface
390
    {
391
        $this->schilde = $schilde;
392
        return $this;
393
    }
394
395
    /**
396
     * proportional to shield system status
397
     */
398 9
    #[Override]
399
    public function getMaxShield(bool $isTheoretical = false): int
400
    {
401 9
        if ($isTheoretical || !$this->hasSpacecraftSystem(SpacecraftSystemTypeEnum::SHIELDS)) {
402 5
            return $this->max_schilde;
403
        }
404
405 7
        return (int) (ceil($this->max_schilde
406 7
            * $this->getSpacecraftSystem(SpacecraftSystemTypeEnum::SHIELDS)->getStatus() / 100));
407
    }
408
409
    #[Override]
410
    public function setMaxShield(int $maxShields): SpacecraftInterface
411
    {
412
        $this->max_schilde = $maxShields;
413
        return $this;
414
    }
415
416
    #[Override]
417
    public function getHealthPercentage(): float
418
    {
419
        return ($this->getHull() + $this->getShield())
420
            / ($this->getMaxHull() + $this->getMaxShield(true)) * 100;
421
    }
422
423 20
    #[Override]
424
    public function getShieldState(): bool
425
    {
426 20
        return $this->getSystemState(SpacecraftSystemTypeEnum::SHIELDS);
427
    }
428
429 6
    #[Override]
430
    public function getNbs(): bool
431
    {
432 6
        return $this->getSystemState(SpacecraftSystemTypeEnum::NBS);
433
    }
434
435 6
    #[Override]
436
    public function getLss(): bool
437
    {
438 6
        return $this->getSystemState(SpacecraftSystemTypeEnum::LSS);
439
    }
440
441 3
    #[Override]
442
    public function getPhaserState(): bool
443
    {
444 3
        return $this->getSystemState(SpacecraftSystemTypeEnum::PHASER);
445
    }
446
447 1
    #[Override]
448
    public function isAlertGreen(): bool
449
    {
450 1
        return $this->getAlertState() === SpacecraftAlertStateEnum::ALERT_GREEN;
451
    }
452
453 1
    #[Override]
454
    public function getTorpedoState(): bool
455
    {
456 1
        return $this->getSystemState(SpacecraftSystemTypeEnum::TORPEDO);
457
    }
458
459
    #[Override]
460
    public function getTorpedoCount(): int
461
    {
462
        if ($this->getTorpedoStorage() === null) {
463
            return 0;
464
        }
465
466
        return $this->getTorpedoStorage()->getStorage()->getAmount();
467
    }
468
469 7
    #[Override]
470
    public function isStation(): bool
471
    {
472 7
        return $this instanceof StationInterface;
473
    }
474
475 1
    #[Override]
476
    public function isShuttle(): bool
477
    {
478 1
        return $this->getRump()->getCategoryId() === SpacecraftRumpEnum::SHIP_CATEGORY_SHUTTLE;
479
    }
480
481 2
    #[Override]
482
    public function isConstruction(): bool
483
    {
484 2
        return $this->getRump()->getCategoryId() === SpacecraftRumpEnum::SHIP_CATEGORY_CONSTRUCTION;
485
    }
486
487 1
    #[Override]
488
    public function getDatabaseId(): ?int
489
    {
490 1
        return $this->database_id;
491
    }
492
493
    #[Override]
494
    public function setDatabaseId(?int $databaseEntryId): SpacecraftInterface
495
    {
496
        $this->database_id = $databaseEntryId;
497
        return $this;
498
    }
499
500 10
    #[Override]
501
    public function isDestroyed(): bool
502
    {
503 10
        return $this->is_destroyed;
504
    }
505
506
    #[Override]
507
    public function setIsDestroyed(bool $isDestroyed): SpacecraftInterface
508
    {
509
        $this->is_destroyed = $isDestroyed;
510
        return $this;
511
    }
512
513
    #[Override]
514
    public function isDisabled(): bool
515
    {
516
        return $this->disabled;
517
    }
518
519
    #[Override]
520
    public function setDisabled(bool $isDisabled): SpacecraftInterface
521
    {
522
        $this->disabled = $isDisabled;
523
        return $this;
524
    }
525
526
527
528
    /**
529
     * proportional to computer system status
530
     */
531 1
    #[Override]
532
    public function getHitChance(): int
533
    {
534 1
        if (!$this->hasSpacecraftSystem(SpacecraftSystemTypeEnum::COMPUTER)) {
535
            return $this->hit_chance;
536
        }
537
538 1
        return (int) (ceil($this->hit_chance
539 1
            * $this->getSpacecraftSystem(SpacecraftSystemTypeEnum::COMPUTER)->getStatus() / 100));
540
    }
541
542
    #[Override]
543
    public function setHitChance(int $hitChance): SpacecraftInterface
544
    {
545
        $this->hit_chance = $hitChance;
546
        return $this;
547
    }
548
549
    /**
550
     * proportional to impulsedrive system status
551
     */
552 1
    #[Override]
553
    public function getEvadeChance(): int
554
    {
555 1
        if (!$this->hasSpacecraftSystem(SpacecraftSystemTypeEnum::IMPULSEDRIVE)) {
556
            return $this->evade_chance;
557
        }
558
559 1
        return (int) (ceil($this->evade_chance
560 1
            * $this->getSpacecraftSystem(SpacecraftSystemTypeEnum::IMPULSEDRIVE)->getStatus() / 100));
561
    }
562
563
    #[Override]
564
    public function setEvadeChance(int $evadeChance): SpacecraftInterface
565
    {
566
        $this->evade_chance = $evadeChance;
567
        return $this;
568
    }
569
570
    /**
571
     * proportional to energy weapon system status
572
     */
573 1
    #[Override]
574
    public function getBaseDamage(): int
575
    {
576 1
        if (!$this->hasSpacecraftSystem(SpacecraftSystemTypeEnum::PHASER)) {
577
            return $this->base_damage;
578
        }
579
580 1
        return (int) (ceil($this->base_damage
581 1
            * $this->getSpacecraftSystem(SpacecraftSystemTypeEnum::PHASER)->getStatus() / 100));
582
    }
583
584
    #[Override]
585
    public function setBaseDamage(int $baseDamage): SpacecraftInterface
586
    {
587
        $this->base_damage = $baseDamage;
588
        return $this;
589
    }
590
591
    /**
592
     * proportional to sensor system status
593
     */
594 2
    #[Override]
595
    public function getSensorRange(): int
596
    {
597 2
        if (!$this->hasSpacecraftSystem(SpacecraftSystemTypeEnum::LSS)) {
598
            return $this->sensor_range;
599
        }
600
601 2
        return (int) (ceil($this->sensor_range
602 2
            * $this->getSpacecraftSystem(SpacecraftSystemTypeEnum::LSS)->getStatus() / 100));
603
    }
604
605
    #[Override]
606
    public function setSensorRange(int $sensorRange): SpacecraftInterface
607
    {
608
        $this->sensor_range = $sensorRange;
609
        return $this;
610
    }
611
612
    /**
613
     * proportional to tractor beam system status
614
     */
615 1
    #[Override]
616
    public function getTractorPayload(): int
617
    {
618 1
        if (!$this->hasSpacecraftSystem(SpacecraftSystemTypeEnum::TRACTOR_BEAM)) {
619
            return 0;
620
        }
621
622 1
        return (int) (ceil($this->getRump()->getTractorPayload()
623 1
            * $this->getSpacecraftSystem(SpacecraftSystemTypeEnum::TRACTOR_BEAM)->getStatus() / 100));
624
    }
625
626
    #[Override]
627
    public function getShieldRegenerationTimer(): int
628
    {
629
        return $this->shield_regeneration_timer;
630
    }
631
632
    #[Override]
633
    public function setShieldRegenerationTimer(int $shieldRegenerationTimer): SpacecraftInterface
634
    {
635
        $this->shield_regeneration_timer = $shieldRegenerationTimer;
636
        return $this;
637
    }
638
639 5
    #[Override]
640
    public function getState(): SpacecraftStateEnum
641
    {
642 5
        return $this->state;
643
    }
644
645
    #[Override]
646
    public function setState(SpacecraftStateEnum $state): SpacecraftInterface
647
    {
648
        $this->state = $state;
649
        return $this;
650
    }
651
652 1
    #[Override]
653
    public function getIsInEmergency(): bool
654
    {
655 1
        return $this->in_emergency;
656
    }
657
658
    #[Override]
659
    public function setIsInEmergency(bool $inEmergency): SpacecraftInterface
660
    {
661
        $this->in_emergency = $inEmergency;
662
        return $this;
663
    }
664
665
    #[Override]
666
    public function isUnderRepair(): bool
667
    {
668
        return $this->getState() === SpacecraftStateEnum::SHIP_STATE_REPAIR_ACTIVE
669
            || $this->getState() === SpacecraftStateEnum::SHIP_STATE_REPAIR_PASSIVE;
670
    }
671
672 13
    #[Override]
673
    public function getCrewAssignments(): Collection
674
    {
675 13
        return $this->crew;
676
    }
677
678 5
    #[Override]
679
    public function getPosX(): int
680
    {
681 5
        return $this->location->getX();
682
    }
683
684 5
    #[Override]
685
    public function getPosY(): int
686
    {
687 5
        return $this->location->getY();
688
    }
689
690 12
    #[Override]
691
    public function getCrewCount(): int
692
    {
693 12
        return $this->getCrewAssignments()->count();
694
    }
695
696 7
    #[Override]
697
    public function getNeededCrewCount(): int
698
    {
699 7
        $buildplan = $this->getBuildplan();
700 7
        if ($buildplan === null) {
701
            return 0;
702
        }
703
704 7
        return $buildplan->getCrew();
705
    }
706
707 6
    #[Override]
708
    public function getExcessCrewCount(): int
709
    {
710 6
        return $this->getCrewCount() - $this->getNeededCrewCount();
711
    }
712
713 3
    #[Override]
714
    public function hasEnoughCrew(?GameControllerInterface $game = null): bool
715
    {
716 3
        $buildplan = $this->getBuildplan();
717
718 3
        if ($buildplan === null) {
719
            if ($game !== null) {
720
                $game->addInformation(_("Keine Crew vorhanden"));
721
            }
722
            return false;
723
        }
724
725 3
        $result = $buildplan->getCrew() <= 0
726 3
            || $this->getCrewCount() >= $buildplan->getCrew();
727
728 3
        if (!$result && $game !== null) {
729
            $game->addInformationf(
730
                _("Es werden %d Crewmitglieder benötigt"),
731
                $buildplan->getCrew()
732
            );
733
        }
734
735 3
        return $result;
736
    }
737
738 43
    #[Override]
739
    public function getUser(): UserInterface
740
    {
741 43
        return $this->user;
742
    }
743
744
    #[Override]
745
    public function setUser(UserInterface $user): SpacecraftInterface
746
    {
747
        $this->user = $user;
748
        return $this;
749
    }
750
751 6
    #[Override]
752
    public function getSystem(): ?StarSystemInterface
753
    {
754 6
        return $this->getStarsystemMap() !== null ? $this->getStarsystemMap()->getSystem() : null;
755
    }
756
757 2
    #[Override]
758
    public function getModules(): array
759
    {
760 2
        $modules = [];
761
762 2
        $buildplan = $this->getBuildplan();
763 2
        if ($buildplan === null) {
764
            return $modules;
765
        }
766
767 2
        foreach ($buildplan->getModules() as $obj) {
768 2
            $module = $obj->getModule();
769 2
            $index = $module->getType() === SpacecraftModuleTypeEnum::SPECIAL ? $module->getId() : $module->getType()->value;
770 2
            $modules[$index] = $module;
771
        }
772
773 2
        return $modules;
774
    }
775
776
    #[Override]
777
    public function isDeflectorHealthy(): bool
778
    {
779
        return $this->isSystemHealthy(SpacecraftSystemTypeEnum::DEFLECTOR);
780
    }
781
782 7
    #[Override]
783
    public function isTroopQuartersHealthy(): bool
784
    {
785 7
        return $this->isSystemHealthy(SpacecraftSystemTypeEnum::TROOP_QUARTERS);
786
    }
787
788
    #[Override]
789
    public function isMatrixScannerHealthy(): bool
790
    {
791
        return $this->isSystemHealthy(SpacecraftSystemTypeEnum::MATRIX_SCANNER);
792
    }
793
794 10
    #[Override]
795
    public function isTorpedoStorageHealthy(): bool
796
    {
797 10
        return $this->isSystemHealthy(SpacecraftSystemTypeEnum::TORPEDO_STORAGE);
798
    }
799
800 1
    #[Override]
801
    public function isShuttleRampHealthy(): bool
802
    {
803 1
        return $this->isSystemHealthy(SpacecraftSystemTypeEnum::SHUTTLE_RAMP);
804
    }
805
806 1
    #[Override]
807
    public function isWebEmitterHealthy(): bool
808
    {
809 1
        return $this->isSystemHealthy(SpacecraftSystemTypeEnum::THOLIAN_WEB);
810
    }
811
812
    #[Override]
813
    public function isWarpAble(): bool
814
    {
815
        return $this->isSystemHealthy(SpacecraftSystemTypeEnum::WARPDRIVE);
816
    }
817
818 2
    #[Override]
819
    public function isTractoring(): bool
820
    {
821 2
        return $this->getTractoredShip() !== null;
822
    }
823
824
    #[Override]
825
    public function isOverColony(): ?ColonyInterface
826
    {
827
        return $this->getStarsystemMap() !== null ? $this->getStarsystemMap()->getColony() : null;
828
    }
829
830 2
    #[Override]
831
    public function isOverSystem(): ?StarSystemInterface
832
    {
833 2
        $location = $this->getLocation();
834 2
        if ($location instanceof StarSystemMapInterface) {
835
            return null;
836
        }
837
838 2
        return $location->getSystem();
839
    }
840
841 1
    #[Override]
842
    public function isWarpPossible(): bool
843
    {
844 1
        return $this->hasSpacecraftSystem(SpacecraftSystemTypeEnum::WARPDRIVE) && $this->getSystem() === null;
845
    }
846
847 1
    #[Override]
848
    public function getTorpedo(): ?TorpedoTypeInterface
849
    {
850 1
        if ($this->getTorpedoStorage() === null) {
851 1
            return null;
852
        }
853
854
        return $this->getTorpedoStorage()->getTorpedo();
855
    }
856
857 1
    #[Override]
858
    public function getTorpedoStorage(): ?TorpedoStorageInterface
859
    {
860 1
        return $this->torpedoStorage;
861
    }
862
863
    #[Override]
864
    public function setTorpedoStorage(?TorpedoStorageInterface $torpedoStorage): SpacecraftInterface
865
    {
866
        $this->torpedoStorage = $torpedoStorage;
867
        return $this;
868
    }
869
870 15
    #[Override]
871
    public function getStorage(): Collection
872
    {
873 15
        return $this->storage;
874
    }
875
876 1
    #[Override]
877
    public function getLogbook(): Collection
878
    {
879 1
        return $this->logbook;
880
    }
881
882 4
    #[Override]
883
    public function getTakeoverActive(): ?ShipTakeoverInterface
884
    {
885 4
        return $this->takeoverActive;
886
    }
887
888
    #[Override]
889
    public function setTakeoverActive(?ShipTakeoverInterface $takeover): SpacecraftInterface
890
    {
891
        $this->takeoverActive = $takeover;
892
893
        return $this;
894
    }
895
896 4
    #[Override]
897
    public function getTakeoverPassive(): ?ShipTakeoverInterface
898
    {
899 4
        return $this->takeoverPassive;
900
    }
901
902
    #[Override]
903
    public function setTakeoverPassive(?ShipTakeoverInterface $takeover): SpacecraftInterface
904
    {
905
        $this->takeoverPassive = $takeover;
906
907
        return $this;
908
    }
909
910 14
    #[Override]
911
    public function getStorageSum(): int
912
    {
913 14
        return array_reduce(
914 14
            $this->getStorage()->getValues(),
915 14
            fn(int $sum, StorageInterface $storage): int => $sum + $storage->getAmount(),
916 14
            0
917 14
        );
918
    }
919
920 13
    #[Override]
921
    public function getMaxStorage(): int
922
    {
923 13
        return $this->getRump()->getStorage();
924
    }
925
926 8
    #[Override]
927
    public function getBeamableStorage(): Collection
928
    {
929 8
        return CommodityTransfer::excludeNonBeamable($this->storage);
930
    }
931
932 7
    #[Override]
933
    public function getMap(): ?MapInterface
934
    {
935 7
        if ($this->location instanceof MapInterface) {
936 5
            return $this->location;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->location returns the type Stu\Orm\Entity\LocationInterface which includes types incompatible with the type-hinted return Stu\Orm\Entity\MapInterface|null.
Loading history...
937
        }
938 2
        if ($this->location instanceof StarSystemMapInterface) {
939 2
            return $this->location->getSystem()->getMap();
0 ignored issues
show
Bug introduced by
The method getSystem() does not exist on Stu\Orm\Entity\LocationInterface. It seems like you code against a sub-type of said class. However, the method does not exist in Stu\Orm\Entity\Location. Are you sure you never get one of those? ( Ignorable by Annotation )

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

939
            return $this->location->/** @scrutinizer ignore-call */ getSystem()->getMap();
Loading history...
940
        }
941
942
        return null;
943
    }
944
945 1
    #[Override]
946
    public function getMapRegion(): ?MapRegionInterface
947
    {
948 1
        $systemMap = $this->getStarsystemMap();
949 1
        if ($systemMap !== null) {
950
            return null;
951
        }
952
953 1
        $map = $this->getMap();
954 1
        if ($map === null) {
955
            return null;
956
        }
957
958 1
        return $map->getMapRegion();
959
    }
960
961 3
    #[Override]
962
    public function setLocation(LocationInterface $location): SpacecraftInterface
963
    {
964 3
        $this->location = $location;
965
966 3
        return $this;
967
    }
968
969 9
    #[Override]
970
    public function getStarsystemMap(): ?StarSystemMapInterface
971
    {
972 9
        if ($this->location instanceof StarSystemMapInterface) {
973 5
            return $this->location;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->location returns the type Stu\Orm\Entity\LocationInterface which includes types incompatible with the type-hinted return Stu\Orm\Entity\StarSystemMapInterface|null.
Loading history...
974
        }
975
976 6
        return null;
977
    }
978
979 30
    #[Override]
980
    public function getLocation(): MapInterface|StarSystemMapInterface
981
    {
982
        if (
983 30
            $this->location instanceof MapInterface
984 30
            || $this->location instanceof StarSystemMapInterface
985
        ) {
986 30
            return $this->location;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->location returns the type Stu\Orm\Entity\LocationInterface which includes types incompatible with the type-hinted return Stu\Orm\Entity\MapInterf...\StarSystemMapInterface.
Loading history...
987
        }
988
989
        throw new RuntimeException('unknown type');
990
    }
991
992 11
    #[Override]
993
    public function getBeamFactor(): int
994
    {
995 11
        return $this->getRump()->getBeamFactor();
996
    }
997
998 4
    #[Override]
999
    public function getSectorString(): string
1000
    {
1001 4
        return $this->getLocation()->getSectorString();
1002
    }
1003
1004 13
    #[Override]
1005
    public function getBuildplan(): ?SpacecraftBuildplanInterface
1006
    {
1007 13
        return $this->buildplan;
1008
    }
1009
1010
    #[Override]
1011
    public function setBuildplan(?SpacecraftBuildplanInterface $spacecraftBuildplan): SpacecraftInterface
1012
    {
1013
        $this->buildplan = $spacecraftBuildplan;
1014
        return $this;
1015
    }
1016
1017 37
    #[Override]
1018
    public function getSystems(): Collection
1019
    {
1020 37
        return $this->systems;
1021
    }
1022
1023 36
    #[Override]
1024
    public function hasSpacecraftSystem(SpacecraftSystemTypeEnum $type): bool
1025
    {
1026 36
        return $this->getSystems()->containsKey($type->value);
1027
    }
1028
1029 17
    #[Override]
1030
    public function getSpacecraftSystem(SpacecraftSystemTypeEnum $type): SpacecraftSystemInterface
1031
    {
1032 17
        $system = $this->getSystems()->get($type->value);
1033 17
        if ($system === null) {
1034
            throw new RuntimeException(sprintf('system type %d does not exist on ship', $type->value));
1035
        }
1036
1037 17
        return $system;
1038
    }
1039
1040 1
    #[Override]
1041
    public function displayNbsActions(): bool
1042
    {
1043 1
        return !$this->getCloakState()
1044 1
            && !$this->isWarped();
1045
    }
1046
1047
    #[Override]
1048
    public function isTractorbeamPossible(): bool
1049
    {
1050
        return TractorBeamShipSystem::isTractorBeamPossible($this);
1051
    }
1052
1053
    #[Override]
1054
    public function isBoardingPossible(): bool
1055
    {
1056
        return FightLib::isBoardingPossible($this);
1057
    }
1058
1059
    #[Override]
1060
    public function isInterceptable(): bool
1061
    {
1062
        //TODO can tractored ships be intercepted?!
1063
        return $this->getWarpDriveState();
1064
    }
1065
1066 2
    #[Override]
1067
    public function getTractoredShip(): ?ShipInterface
1068
    {
1069 2
        return $this->tractoredShip;
1070
    }
1071
1072
    #[Override]
1073
    public function setTractoredShip(?ShipInterface $ship): SpacecraftInterface
1074
    {
1075
        $this->tractoredShip = $ship;
1076
        return $this;
1077
    }
1078
1079
    #[Override]
1080
    public function setTractoredShipId(?int $shipId): SpacecraftInterface
1081
    {
1082
        $this->tractored_ship_id = $shipId;
1083
        return $this;
1084
    }
1085
1086 8
    #[Override]
1087
    public function getHoldingWeb(): ?TholianWebInterface
1088
    {
1089 8
        return $this->holdingWeb;
1090
    }
1091
1092
    #[Override]
1093
    public function setHoldingWeb(?TholianWebInterface $web): SpacecraftInterface
1094
    {
1095
        $this->holdingWeb = $web;
1096
1097
        if ($web === null) {
1098
            $this->holding_web_id = null;
1099
        }
1100
1101
        return $this;
1102
    }
1103
1104 4
    #[Override]
1105
    public function getHoldingWebBackgroundStyle(): string
1106
    {
1107 4
        if ($this->getHoldingWeb() === null) {
1108 4
            return '';
1109
        }
1110
1111
        if ($this->getHoldingWeb()->isFinished()) {
1112
            $icon =  'web.png';
1113
        } else {
1114
            $closeTofinish = $this->getHoldingWeb()->getFinishedTime() - time() < TimeConstants::ONE_HOUR_IN_SECONDS;
1115
1116
            $icon = $closeTofinish ? 'web_u.png' : 'web_u2.png';
1117
        }
1118
1119
        return sprintf('src="assets/buttons/%s"; class="indexedGraphics" style="z-index: 5;"', $icon);
1120
    }
1121
1122
    public function getHoldingWebImageStyle(): string
1123
    {
1124
        if ($this->getHoldingWeb() === null) {
1125
            return '';
1126
        }
1127
1128
        if ($this->getHoldingWeb()->isFinished()) {
1129
            $icon =  'webfill.png';
1130
        } else {
1131
            $closeTofinish = $this->getHoldingWeb()->getFinishedTime() - time() < TimeConstants::ONE_HOUR_IN_SECONDS;
1132
1133
            $icon = $closeTofinish ? 'web_ufill.png' : 'web_ufill2.png';
1134
        }
1135
1136
        return $icon;
1137
    }
1138
1139 7
    private function getShieldRegenerationPercentage(): int
1140
    {
1141 7
        return $this->isSystemHealthy(SpacecraftSystemTypeEnum::SHIELDS) ? 10 : 0;
1142
    }
1143
1144 7
    #[Override]
1145
    public function getShieldRegenerationRate(): int
1146
    {
1147 7
        return (int) ceil(($this->getMaxShield() / 100) * $this->getShieldRegenerationPercentage());
1148
    }
1149
1150 1
    #[Override]
1151
    public function canIntercept(): bool
1152
    {
1153 1
        return $this->isSystemHealthy(SpacecraftSystemTypeEnum::WARPDRIVE)
1154 1
            && !$this->isTractoring()
1155 1
            && (!$this instanceof ShipInterface || !$this->isTractored());
1156
    }
1157
1158 3
    #[Override]
1159
    public function canMove(): bool
1160
    {
1161 3
        return $this->hasSpacecraftSystem(SpacecraftSystemTypeEnum::WARPDRIVE)
1162 3
            || $this->hasSpacecraftSystem(SpacecraftSystemTypeEnum::IMPULSEDRIVE);
1163
    }
1164
1165 1
    #[Override]
1166
    public function hasActiveWeapon(): bool
1167
    {
1168 1
        return $this->getPhaserState() || $this->getTorpedoState();
1169
    }
1170
1171
    #[Override]
1172
    public function hasEscapePods(): bool
1173
    {
1174
        return $this->getRump()->isEscapePods() && $this->getCrewCount() > 0;
1175
    }
1176
1177 1
    #[Override]
1178
    public function getRepairRate(): int
1179
    {
1180
        // @todo
1181 1
        return 100;
1182
    }
1183
1184 35
    #[Override]
1185
    public function getRump(): SpacecraftRumpInterface
1186
    {
1187 35
        return $this->rump;
1188
    }
1189
1190 18
    #[Override]
1191
    public function getRumpId(): int
1192
    {
1193 18
        return $this->getRump()->getId();
1194
    }
1195
1196 18
    #[Override]
1197
    public function getRumpName(): string
1198
    {
1199 18
        return $this->getRump()->getName();
1200
    }
1201
1202
    #[Override]
1203
    public function setRump(SpacecraftRumpInterface $shipRump): SpacecraftInterface
1204
    {
1205
        $this->rump = $shipRump;
1206
        return $this;
1207
    }
1208
1209 4
    #[Override]
1210
    public function hasPhaser(): bool
1211
    {
1212 4
        return $this->hasSpacecraftSystem(SpacecraftSystemTypeEnum::PHASER);
1213
    }
1214
1215 6
    #[Override]
1216
    public function hasTorpedo(): bool
1217
    {
1218 6
        return $this->hasSpacecraftSystem(SpacecraftSystemTypeEnum::TORPEDO);
1219
    }
1220
1221 4
    #[Override]
1222
    public function hasCloak(): bool
1223
    {
1224 4
        return $this->hasSpacecraftSystem(SpacecraftSystemTypeEnum::CLOAK);
1225
    }
1226
1227 4
    #[Override]
1228
    public function hasShuttleRamp(): bool
1229
    {
1230 4
        return $this->hasSpacecraftSystem(SpacecraftSystemTypeEnum::SHUTTLE_RAMP);
1231
    }
1232
1233 6
    #[Override]
1234
    public function hasWarpdrive(): bool
1235
    {
1236 6
        return $this->hasSpacecraftSystem(SpacecraftSystemTypeEnum::WARPDRIVE);
1237
    }
1238
1239 1
    #[Override]
1240
    public function hasReactor(): bool
1241
    {
1242 1
        return $this->hasSpacecraftSystem(SpacecraftSystemTypeEnum::WARPCORE) ||
1243 1
            $this->hasSpacecraftSystem(SpacecraftSystemTypeEnum::FUSION_REACTOR) ||
1244 1
            $this->hasSpacecraftSystem(SpacecraftSystemTypeEnum::SINGULARITY_REACTOR);
1245
    }
1246
1247 2
    #[Override]
1248
    public function hasNbsLss(): bool
1249
    {
1250 2
        return $this->hasSpacecraftSystem(SpacecraftSystemTypeEnum::LSS);
1251
    }
1252
1253 6
    #[Override]
1254
    public function hasUplink(): bool
1255
    {
1256 6
        return $this->hasSpacecraftSystem(SpacecraftSystemTypeEnum::UPLINK);
1257
    }
1258
1259 2
    #[Override]
1260
    public function hasTranswarp(): bool
1261
    {
1262 2
        return $this->hasSpacecraftSystem(SpacecraftSystemTypeEnum::TRANSWARP_COIL);
1263
    }
1264
1265
    #[Override]
1266
    public function getTranswarpCooldown(): ?int
1267
    {
1268
        $cooldown = $this->getSpacecraftSystem(SpacecraftSystemTypeEnum::TRANSWARP_COIL)->getCooldown();
1269
1270
        return $cooldown > time() ? $cooldown : null;
1271
    }
1272
1273 3
    #[Override]
1274
    public function getMaxTorpedos(): int
1275
    {
1276 3
        return $this->getRump()->getBaseTorpedoStorage()
1277 3
            + ($this->isSystemHealthy(SpacecraftSystemTypeEnum::TORPEDO_STORAGE)
1278 3
                ? TorpedoStorageShipSystem::TORPEDO_CAPACITY : 0);
1279
    }
1280
1281
    #[Override]
1282
    public function hasFreeShuttleSpace(?LoggerUtilInterface $loggerUtil = null): bool
1283
    {
1284
        if ($loggerUtil !== null) {
1285
            $loggerUtil->log(sprintf('rumpShuttleSlots: %d', $this->getRump()->getShuttleSlots()));
1286
            $loggerUtil->log(sprintf('storedShuttleCount: %d', $this->getStoredShuttleCount()));
1287
        }
1288
        return $this->hasSpacecraftSystem(SpacecraftSystemTypeEnum::SHUTTLE_RAMP)
1289
            && $this->getRump()->getShuttleSlots() - $this->getStoredShuttleCount() > 0;
1290
    }
1291
1292
    #[Override]
1293
    public function getStoredShuttles(): array
1294
    {
1295
        $shuttles = [];
1296
1297
        foreach ($this->getStorage() as $stor) {
1298
            if ($stor->getCommodity()->isShuttle()) {
1299
                $shuttles[] = $stor->getCommodity();
1300
            }
1301
        }
1302
1303
        return $shuttles;
1304
    }
1305
1306
    #[Override]
1307
    public function getStoredShuttleCount(): int
1308
    {
1309
        $count = 0;
1310
1311
        foreach ($this->getStorage() as $stor) {
1312
            if ($stor->getCommodity()->isShuttle()) {
1313
                $count += $stor->getAmount();
1314
            }
1315
        }
1316
1317
        return $count;
1318
    }
1319
1320
    /**
1321
     * @return CommodityInterface[]
1322
     */
1323 2
    #[Override]
1324
    public function getStoredBuoy(): array
1325
    {
1326 2
        $buoy = [];
1327
1328 2
        foreach ($this->getStorage() as $stor) {
1329 1
            if ($stor->getCommodity()->isBouy()) {
1330
                $buoy[] = $stor->getCommodity();
1331
            }
1332
        }
1333
1334 2
        return $buoy;
1335
    }
1336
1337
1338 2
    #[Override]
1339
    public function hasStoredBuoy(): bool
1340
    {
1341 2
        return $this->getStoredBuoy() !== [];
1342
    }
1343
1344 2
    #[Override]
1345
    public function canMan(): bool
1346
    {
1347 2
        $buildplan = $this->getBuildplan();
1348
1349 2
        return $buildplan !== null
1350 2
            && $buildplan->getCrew() > 0
1351 2
            && $this->hasSpacecraftSystem(SpacecraftSystemTypeEnum::LIFE_SUPPORT);
1352
    }
1353
1354
    #[Override]
1355
    public function hasCrewmanOfUser(int $userId): bool
1356
    {
1357
        foreach ($this->getCrewAssignments() as $shipCrew) {
1358
            if ($shipCrew->getCrew()->getUser()->getId() === $userId) {
1359
                return true;
1360
            }
1361
        }
1362
1363
        return false;
1364
    }
1365
1366 4
    #[Override]
1367
    public function getHref(): string
1368
    {
1369 4
        return sprintf(
1370 4
            '%s?%s=1&id=%d',
1371 4
            $this->getType()->getModuleView()->getPhpPage(),
1372 4
            $this->getType()->getViewIdentifier(),
1373 4
            $this->getId()
1374 4
        );
1375
    }
1376
1377
    #[Override]
1378
    public function __toString(): string
1379
    {
1380
        if ($this->id !== null) {
1381
            return sprintf('id: %d, name: %s', $this->getId(), $this->getName());
1382
        }
1383
1384
        return $this->getName();
1385
    }
1386
1387 4
    #[Override]
1388
    public function getHullColorStyle(): string
1389
    {
1390 4
        return $this->getColorStyle($this->getHull(), $this->getMaxHull());
1391
    }
1392
1393 4
    private function getColorStyle(int $actual, int $max): string
1394
    {
1395
        // full
1396 4
        if ($actual === $max) {
1397 3
            return '';
1398
        }
1399
1400
        // less than 100% - green
1401 1
        if ($actual / $max > 0.75) {
1402 1
            return 'color: #19c100;';
1403
        }
1404
1405
        // less than 75% - yellow
1406
        if ($actual / $max > 0.50) {
1407
            return 'color: #f4e932;';
1408
        }
1409
1410
        // less than 50% - orange
1411
        if ($actual / $max > 0.25) {
1412
            return 'color: #f48b28;';
1413
        }
1414
1415
        // less than 25% - red
1416
        return 'color: #ff3c3c;';
1417
    }
1418
}
1419