Skip to content

Commit 1a68ce2

Browse files
committed
fix working condition for orbital/underground buildings
1 parent 44c8c6e commit 1a68ce2

File tree

8 files changed

+672
-52
lines changed

8 files changed

+672
-52
lines changed

src/Component/Building/BuildingManager.php

Lines changed: 224 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Stu\Component\Building;
66

77
use Stu\Module\Building\Action\BuildingFunctionActionMapperInterface;
8+
use Stu\Module\Commodity\CommodityTypeConstants;
89
use Stu\Orm\Entity\Building;
910
use Stu\Orm\Entity\ColonyChangeable;
1011
use Stu\Orm\Entity\Colony;
@@ -138,12 +139,28 @@ public function remove(PlanetField $field, bool $isDueToUpgrade = false): void
138139

139140
$host = $field->getHost();
140141
$changeable = $this->getChangeable($field);
142+
$wasActive = $field->isActive();
141143

142144
if (!$field->isUnderConstruction()) {
145+
if ($wasActive && $host instanceof Colony) {
146+
$this->handleUndergroundLogisticsRemoval($field, $host);
147+
if (!$isDueToUpgrade) {
148+
$this->handleOrbitalMaintenanceRemoval($field, $host);
149+
}
150+
}
151+
143152
$this->deactivate($field);
144-
$changeable
145-
->setMaxStorage($changeable->getMaxStorage() - $building->getStorage())
146-
->setMaxEps($changeable->getMaxEps() - $building->getEpsStorage());
153+
154+
$shouldUpdateStorageAndEps = true;
155+
if ($this->buildingRequiresUndergroundLogistics($building)) {
156+
$shouldUpdateStorageAndEps = $this->hasUndergroundLogisticsProduction($host);
157+
}
158+
159+
if ($shouldUpdateStorageAndEps) {
160+
$changeable
161+
->setMaxStorage($changeable->getMaxStorage() - $building->getStorage())
162+
->setMaxEps($changeable->getMaxEps() - $building->getEpsStorage());
163+
}
147164
}
148165

149166
foreach ($building->getFunctions() as $function) {
@@ -175,6 +192,8 @@ public function finish(PlanetField $field, bool $activate = true): ?string
175192
->setActive(0)
176193
->setIntegrity($building->getIntegrity());
177194

195+
$shouldReactivateOthers = $field->getReactivateAfterUpgrade() === $field->getId();
196+
178197
$activationDetails = null;
179198
if ($building->isActivateAble()) {
180199
if ($activate) {
@@ -186,13 +205,37 @@ public function finish(PlanetField $field, bool $activate = true): ?string
186205
}
187206
}
188207

189-
$changeable
190-
->setMaxStorage($changeable->getMaxStorage() + $building->getStorage())
191-
->setMaxEps($changeable->getMaxEps() + $building->getEpsStorage());
208+
$shouldUpdateStorageAndEps = true;
209+
if ($this->buildingRequiresUndergroundLogistics($building)) {
210+
$host = $field->getHost();
211+
if (!$this->hasEnoughUndergroundLogistics($host, $building)) {
212+
$shouldUpdateStorageAndEps = false;
213+
}
214+
}
215+
216+
if ($shouldUpdateStorageAndEps) {
217+
$changeable
218+
->setMaxStorage($changeable->getMaxStorage() + $building->getStorage())
219+
->setMaxEps($changeable->getMaxEps() + $building->getEpsStorage());
220+
}
192221

193222
$this->saveHost($field->getHost());
194223
$this->planetFieldRepository->save($field);
195224

225+
$reactivatedCount = 0;
226+
if ($shouldReactivateOthers) {
227+
$host = $field->getHost();
228+
if ($host instanceof Colony) {
229+
$field->setReactivateAfterUpgrade(null);
230+
$this->planetFieldRepository->save($field);
231+
$reactivatedCount = $this->reactivateOrbitalBuildingsAfterUpgrade($host, $field->getId());
232+
}
233+
}
234+
235+
if ($reactivatedCount > 0) {
236+
$activationDetails .= sprintf(' - Es wurden %d Orbitalgebäude reaktiviert', $reactivatedCount);
237+
}
238+
196239
return $activationDetails;
197240
}
198241

@@ -204,4 +247,179 @@ private function getChangeable(PlanetField $field): ColonyChangeable|ColonySandb
204247
? $host
205248
: $host->getChangeable();
206249
}
250+
251+
private function buildingRequiresUndergroundLogistics(Building $building): bool
252+
{
253+
$logisticsCommodityId = CommodityTypeConstants::COMMODITY_EFFECT_UNDERGROUND_LOGISTICS;
254+
255+
foreach ($building->getCommodities() as $buildingCommodity) {
256+
if ($buildingCommodity->getCommodityId() === $logisticsCommodityId && $buildingCommodity->getAmount() < 0) {
257+
return true;
258+
}
259+
}
260+
261+
return false;
262+
}
263+
264+
private function buildingProducesUndergroundLogistics(Building $building): bool
265+
{
266+
$logisticsCommodityId = CommodityTypeConstants::COMMODITY_EFFECT_UNDERGROUND_LOGISTICS;
267+
268+
foreach ($building->getCommodities() as $buildingCommodity) {
269+
if ($buildingCommodity->getCommodityId() === $logisticsCommodityId && $buildingCommodity->getAmount() > 0) {
270+
return true;
271+
}
272+
}
273+
274+
return false;
275+
}
276+
277+
private function hasUndergroundLogisticsProduction(Colony|ColonySandbox $host): bool
278+
{
279+
$logisticsCommodityId = CommodityTypeConstants::COMMODITY_EFFECT_UNDERGROUND_LOGISTICS;
280+
281+
$producingFields = $this->planetFieldRepository->getCommodityProducingByHostAndCommodity($host, $logisticsCommodityId);
282+
283+
foreach ($producingFields as $field) {
284+
if ($field->isActive()) {
285+
return true;
286+
}
287+
}
288+
289+
return false;
290+
}
291+
292+
private function hasEnoughUndergroundLogistics(Colony|ColonySandbox $host, Building $building): bool
293+
{
294+
$logisticsCommodityId = CommodityTypeConstants::COMMODITY_EFFECT_UNDERGROUND_LOGISTICS;
295+
296+
$production = 0;
297+
$consumption = 0;
298+
299+
$producingFields = $this->planetFieldRepository->getCommodityProducingByHostAndCommodity($host, $logisticsCommodityId);
300+
foreach ($producingFields as $field) {
301+
if ($field->isActive() && $field->getBuilding() !== null) {
302+
foreach ($field->getBuilding()->getCommodities() as $commodity) {
303+
if ($commodity->getCommodityId() === $logisticsCommodityId) {
304+
$production += $commodity->getAmount();
305+
}
306+
}
307+
}
308+
}
309+
310+
$consumingFields = $this->planetFieldRepository->getCommodityConsumingByHostAndCommodity($host, $logisticsCommodityId, [1]);
311+
foreach ($consumingFields as $field) {
312+
if ($field->getBuilding() !== null) {
313+
foreach ($field->getBuilding()->getCommodities() as $commodity) {
314+
if ($commodity->getCommodityId() === $logisticsCommodityId) {
315+
$consumption += $commodity->getAmount();
316+
}
317+
}
318+
}
319+
}
320+
321+
$buildingConsumption = 0;
322+
foreach ($building->getCommodities() as $commodity) {
323+
if ($commodity->getCommodityId() === $logisticsCommodityId) {
324+
$buildingConsumption = $commodity->getAmount();
325+
break;
326+
}
327+
}
328+
329+
return ($production + $consumption + $buildingConsumption) >= 0;
330+
}
331+
332+
private function handleUndergroundLogisticsRemoval(PlanetField $field, Colony $host): void
333+
{
334+
$building = $field->getBuilding();
335+
if ($building === null) {
336+
return;
337+
}
338+
339+
if (!$this->buildingProducesUndergroundLogistics($building)) {
340+
return;
341+
}
342+
343+
$logisticsCommodityId = CommodityTypeConstants::COMMODITY_EFFECT_UNDERGROUND_LOGISTICS;
344+
345+
$consumingFields = $this->planetFieldRepository->getCommodityConsumingByHostAndCommodity(
346+
$host,
347+
$logisticsCommodityId,
348+
[0, 1]
349+
);
350+
351+
$totalStorage = 0;
352+
$totalEps = 0;
353+
354+
foreach ($consumingFields as $consumingField) {
355+
$consumingBuilding = $consumingField->getBuilding();
356+
if ($consumingBuilding === null) {
357+
continue;
358+
}
359+
360+
$totalStorage += $consumingBuilding->getStorage();
361+
$totalEps += $consumingBuilding->getEpsStorage();
362+
}
363+
364+
if ($totalStorage > 0 || $totalEps > 0) {
365+
$changeable = $host->getChangeable();
366+
$changeable
367+
->setMaxStorage($changeable->getMaxStorage() - $totalStorage)
368+
->setMaxEps($changeable->getMaxEps() - $totalEps);
369+
}
370+
}
371+
372+
private function reactivateOrbitalBuildingsAfterUpgrade(Colony $host, int $upgradedFieldId): int
373+
{
374+
$fieldsToReactivate = array_filter(
375+
$host->getPlanetFields()->toArray(),
376+
fn(PlanetField $f) => $f->getReactivateAfterUpgrade() === $upgradedFieldId
377+
);
378+
379+
$reactivatedCount = 0;
380+
381+
foreach ($fieldsToReactivate as $fieldToReactivate) {
382+
if ($this->activate($fieldToReactivate)) {
383+
$reactivatedCount++;
384+
}
385+
$fieldToReactivate->setReactivateAfterUpgrade(null);
386+
$this->planetFieldRepository->save($fieldToReactivate);
387+
}
388+
389+
return $reactivatedCount;
390+
}
391+
392+
private function handleOrbitalMaintenanceRemoval(PlanetField $field, Colony $host): void
393+
{
394+
$building = $field->getBuilding();
395+
if ($building === null) {
396+
return;
397+
}
398+
399+
$maintenanceCommodityId = CommodityTypeConstants::COMMODITY_EFFECT_ORBITAL_MAINTENANCE;
400+
$producesMaintenance = false;
401+
402+
foreach ($building->getCommodities() as $buildingCommodity) {
403+
if ($buildingCommodity->getCommodityId() === $maintenanceCommodityId && $buildingCommodity->getAmount() > 0) {
404+
$producesMaintenance = true;
405+
break;
406+
}
407+
}
408+
409+
if (!$producesMaintenance) {
410+
return;
411+
}
412+
413+
$consumingFields = $this->planetFieldRepository->getCommodityConsumingByHostAndCommodity(
414+
$host,
415+
$maintenanceCommodityId,
416+
[1]
417+
);
418+
419+
foreach ($consumingFields as $consumingField) {
420+
if ($consumingField->isActive()) {
421+
$this->deactivate($consumingField);
422+
}
423+
}
424+
}
207425
}

src/Migrations/Sqlite/Version20260123171558.php renamed to src/Migrations/Sqlite/Version20260129200432.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
/**
1111
* Auto-generated Migration: Please modify to your needs!
1212
*/
13-
final class Version20260123171558 extends AbstractMigration
13+
final class Version20260129200432 extends AbstractMigration
1414
{
1515
public function getDescription(): string
1616
{
@@ -114,7 +114,7 @@ public function up(Schema $schema): void
114114
$this->addSql('CREATE INDEX IDX_B6DF5289A76ED395 ON stu_buoy (user_id)');
115115
$this->addSql('CREATE TABLE stu_colonies_classes (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, name VARCHAR(255) NOT NULL, type INTEGER NOT NULL, database_id INTEGER DEFAULT NULL, colonizeable_fields CLOB NOT NULL, bev_growth_rate SMALLINT NOT NULL, special SMALLINT NOT NULL, allow_start BOOLEAN NOT NULL, min_rot INTEGER NOT NULL, max_rot INTEGER NOT NULL, CONSTRAINT FK_D116D262F0AA09DB FOREIGN KEY (database_id) REFERENCES stu_database_entrys (id) NOT DEFERRABLE INITIALLY IMMEDIATE)');
116116
$this->addSql('CREATE UNIQUE INDEX UNIQ_D116D262F0AA09DB ON stu_colonies_classes (database_id)');
117-
$this->addSql('CREATE TABLE stu_colonies_fielddata (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, colonies_id INTEGER DEFAULT NULL, colony_sandbox_id INTEGER DEFAULT NULL, field_id SMALLINT NOT NULL, type_id INTEGER NOT NULL, buildings_id INTEGER DEFAULT NULL, terraforming_id INTEGER DEFAULT NULL, integrity SMALLINT NOT NULL, aktiv INTEGER NOT NULL, activate_after_build BOOLEAN NOT NULL, CONSTRAINT FK_7E4F10971485E613 FOREIGN KEY (buildings_id) REFERENCES stu_buildings (id) NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_7E4F1097BD31079C FOREIGN KEY (terraforming_id) REFERENCES stu_terraforming (id) NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_7E4F109774EB5CC8 FOREIGN KEY (colonies_id) REFERENCES stu_colony (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_7E4F1097A0222FA4 FOREIGN KEY (colony_sandbox_id) REFERENCES stu_colony_sandbox (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE)');
117+
$this->addSql('CREATE TABLE stu_colonies_fielddata (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, colonies_id INTEGER DEFAULT NULL, colony_sandbox_id INTEGER DEFAULT NULL, field_id SMALLINT NOT NULL, type_id INTEGER NOT NULL, buildings_id INTEGER DEFAULT NULL, terraforming_id INTEGER DEFAULT NULL, integrity SMALLINT NOT NULL, aktiv INTEGER NOT NULL, activate_after_build BOOLEAN NOT NULL, reactivate_after_upgrade INTEGER DEFAULT NULL, CONSTRAINT FK_7E4F10971485E613 FOREIGN KEY (buildings_id) REFERENCES stu_buildings (id) NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_7E4F1097BD31079C FOREIGN KEY (terraforming_id) REFERENCES stu_terraforming (id) NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_7E4F109774EB5CC8 FOREIGN KEY (colonies_id) REFERENCES stu_colony (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_7E4F1097A0222FA4 FOREIGN KEY (colony_sandbox_id) REFERENCES stu_colony_sandbox (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE)');
118118
$this->addSql('CREATE INDEX IDX_7E4F10971485E613 ON stu_colonies_fielddata (buildings_id)');
119119
$this->addSql('CREATE INDEX IDX_7E4F1097BD31079C ON stu_colonies_fielddata (terraforming_id)');
120120
$this->addSql('CREATE INDEX IDX_7E4F109774EB5CC8 ON stu_colonies_fielddata (colonies_id)');
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Stu\Migrations\Pgsql;
6+
7+
use Doctrine\DBAL\Schema\Schema;
8+
use Doctrine\Migrations\AbstractMigration;
9+
10+
/**
11+
* Auto-generated Migration: Please modify to your needs!
12+
*/
13+
final class Version20260129200431 extends AbstractMigration
14+
{
15+
public function getDescription(): string
16+
{
17+
return '';
18+
}
19+
20+
public function up(Schema $schema): void
21+
{
22+
// this up() migration is auto-generated, please modify it to your needs
23+
$this->addSql('ALTER TABLE stu_colonies_fielddata ADD reactivate_after_upgrade INT DEFAULT NULL');
24+
}
25+
26+
public function down(Schema $schema): void
27+
{
28+
// this down() migration is auto-generated, please modify it to your needs
29+
$this->addSql('ALTER TABLE stu_colonies_fielddata DROP reactivate_after_upgrade');
30+
}
31+
}

0 commit comments

Comments
 (0)