diff --git a/app/Factories/PlanetServiceFactory.php b/app/Factories/PlanetServiceFactory.php index 2916674c..96cfcf23 100644 --- a/app/Factories/PlanetServiceFactory.php +++ b/app/Factories/PlanetServiceFactory.php @@ -395,7 +395,9 @@ private function createPlanet(PlayerService $player, Coordinate $new_position, s if ($planet_type === PlanetType::Moon) { $this->setupMoonProperties($planet); } else { - $this->setupPlanetProperties($planet); + $is_first_planet = $player->planets->planetCount() == 0; + + $this->setupPlanetProperties($planet, $is_first_planet); } $planet->save(); @@ -428,13 +430,16 @@ private function setupMoonProperties(Planet $planet): void * Sets up planet-specific properties. * @param Planet $planet */ - private function setupPlanetProperties(Planet $planet): void + private function setupPlanetProperties(Planet $planet, bool $is_first_planet = false): void { - $planet->diameter = 300; - $planet->field_max = rand(140, 250); - // TODO: temperature range should be dependent on the planet position. - $planet->temp_min = rand(0, 100); + $planet_data = $this->planetData($planet->planet, $is_first_planet); + + // Random field count between the min and max values and add the Server planet fields bonus setting. + $planet->field_max = rand($planet_data['fields'][0], $planet_data['fields'][1]) + $this->settings->planetFieldsBonus(); + $planet->diameter = (int) (36.14 * $planet->field_max + 5697.23); + + $planet->temp_min = rand($planet_data['temperature'][0], $planet_data['temperature'][1]); $planet->temp_max = $planet->temp_min + 40; // Starting resources for planets. @@ -450,4 +455,116 @@ private function setupPlanetProperties(Planet $planet): void $planet->fusion_plant_percent = 10; $planet->solar_satellite_percent = 10; } + + /** + * Returns an array of planet data: + * - fields => int[] + * - temperature => int[] + * + * @return array{ + * fields: int[], + * temperature: int[], + * } + */ + public function planetData(int $planetPosition, bool $is_first_planet): array + { + // Each planet position (1-15) has its own data: field range, temperature range, + // and production bonuses for metal, crystal, and deuterium. + // The base production percent is 10 (which is effectively 100%). + // "Max Deterium production" on position 15 is interpreted as a higher deuterium bonus. + // You can tweak these values according to your game's balance. + + $data = [ + // Position 1 + 1 => [ + 'fields' => [96, 172], // min:96, max:172 + 'temperature' => [220, 260], // min:220°C, max:260°C + ], + // Position 2 + 2 => [ + 'fields' => [104, 176], + 'temperature' => [170, 210], + ], + // Position 3 + 3 => [ + 'fields' => [112, 182], + 'temperature' => [120, 160], + ], + // Position 4 + 4 => [ + 'fields' => [118, 208], + 'temperature' => [70, 110], + ], + // Position 5 + 5 => [ + 'fields' => [133, 232], + 'temperature' => [60, 100], + ], + // Position 6 + 6 => [ + 'fields' => [146, 242], + 'temperature' => [50, 90], + ], + // Position 7 + 7 => [ + 'fields' => [152, 248], + 'temperature' => [40, 80], + ], + // Position 8 + 8 => [ + 'fields' => [156, 252], + 'temperature' => [30, 70], + ], + // Position 9 + 9 => [ + 'fields' => [150, 246], + 'temperature' => [20, 60], + ], + // Position 10 + 10 => [ + 'fields' => [142, 232], + 'temperature' => [10, 50], + ], + // Position 11 + 11 => [ + 'fields' => [136, 210], + 'temperature' => [0, 40], + ], + // Position 12 + 12 => [ + 'fields' => [125, 186], + 'temperature' => [-10, 30], + ], + // Position 13 + 13 => [ + 'fields' => [114, 172], + 'temperature' => [-50, -10], + ], + // Position 14 + 14 => [ + 'fields' => [100, 168], + 'temperature' => [-90, -50], + ], + // Position 15 + 15 => [ + 'fields' => [90, 164], + 'temperature' => [-130, -90], + ], + ]; + + //first_planet static data + if ($is_first_planet) { + return $data[$planetPosition] ?? [ + 'fields' => [163, 163], + 'temperature' => [20, 60], + ]; + } + + // If the position doesn't exist, return some default values + // Deuterium can be adjusted according to planet temperature as needed + return $data[$planetPosition] ?? [ + 'fields' => [100, 150], + 'temperature' => [0, 40], + ]; + } } diff --git a/app/Services/PlanetService.php b/app/Services/PlanetService.php index 9cf54be7..a37ac923 100644 --- a/app/Services/PlanetService.php +++ b/app/Services/PlanetService.php @@ -1435,6 +1435,7 @@ public function updateResourceProductionStats(bool $save_planet = true): void */ public function getPlanetBasicIncome(): Resources { + // Moons do not have mines and therefore also do not have basic income. if ($this->isMoon()) { return new Resources(0, 0, 0, 0); @@ -1442,12 +1443,77 @@ public function getPlanetBasicIncome(): Resources $universe_resource_multiplier = $this->settingsService->economySpeed(); - return new Resources( + $baseIncome = new Resources( $this->settingsService->basicIncomeMetal() * $universe_resource_multiplier, $this->settingsService->basicIncomeCrystal() * $universe_resource_multiplier, $this->settingsService->basicIncomeDeuterium() * $universe_resource_multiplier, $this->settingsService->basicIncomeEnergy() * $universe_resource_multiplier ); + + return $this->calculatePlanetBonuses($baseIncome); + + } + + /** + * Calculate the planet bonuses. + * + * @param Resources $baseIncome + * @return Resources + */ + public function calculatePlanetBonuses(Resources $baseIncome): Resources + { + // Calculate the planet position production bonuses. + $baseIncome = $this->calculatePlanetProductionBonuses($baseIncome); + return $baseIncome; + } + + /** + * Calculate the planet position production bonuses. + * + * @param Resources $baseIncome + * @return Resources + */ + public function calculatePlanetProductionBonuses(Resources $baseIncome): Resources + { + $position = $this->planet->planet; + + $bonus = $this->getProductionForPositionBonuses($position); + + $metalMultiplier = $bonus['metal']; + $crystalMultiplier = $bonus['crystal']; + $deuteriumMultiplier = $bonus['deuterium']; + + // Apply multipliers to the base income + $baseIncome->metal->set($baseIncome->metal->get() * $metalMultiplier); + $baseIncome->crystal->set($baseIncome->crystal->get() * $crystalMultiplier); + $baseIncome->deuterium->set($baseIncome->deuterium->get() * $deuteriumMultiplier); + + return $baseIncome; + + } + + /** + * Retrieves production bonuses for a given position. + * + * @param int $position + * @return array{metal: float, crystal: float, deuterium: float} + */ + public function getProductionForPositionBonuses(int $position): array + { + // Define production bonuses by position + $productionBonuses = [ + 1 => ['metal' => 1, 'crystal' => 1.4, 'deuterium' => 1], + 2 => ['metal' => 1, 'crystal' => 1.3, 'deuterium' => 1], + 3 => ['metal' => 1, 'crystal' => 1.2, 'deuterium' => 1], + 6 => ['metal' => 1.17, 'crystal' => 1, 'deuterium' => 1], + 7 => ['metal' => 1.23, 'crystal' => 1, 'deuterium' => 1], + 8 => ['metal' => 1.35, 'crystal' => 1, 'deuterium' => 1], + 9 => ['metal' => 1.23, 'crystal' => 1, 'deuterium' => 1], + 10 => ['metal' => 1.17, 'crystal' => 1, 'deuterium' => 1], + ]; + + // Return bonuses or default values + return $productionBonuses[$position] ?? ['metal' => 1, 'crystal' => 1, 'deuterium' => 1]; } /** @@ -1479,7 +1545,6 @@ private function updateResourceProductionStatsInner(Resources $production_total, // Combine values to one array, so we have the total production. $production_total->add($production); } - // Write values to planet $this->planet->metal_production = (int)$production_total->metal->get(); $this->planet->crystal_production = (int)$production_total->crystal->get(); diff --git a/tests/Unit/ResourceProductionTest.php b/tests/Unit/ResourceProductionTest.php index 7ad7f9c2..c6d3bb80 100644 --- a/tests/Unit/ResourceProductionTest.php +++ b/tests/Unit/ResourceProductionTest.php @@ -37,6 +37,7 @@ public function testMineProduction(): void ]); // Assertions for production values with positive energy + $this->assertGreaterThan(1000, $this->planetService->getMetalProductionPerHour()); $this->assertGreaterThan(1000, $this->planetService->getCrystalProductionPerHour()); $this->assertGreaterThan(500, $this->planetService->getDeuteriumProductionPerHour()); @@ -58,9 +59,12 @@ public function testMineProductionNoEnergy(): void 'solar_plant_percent' => 10, ]); + $position = $this->planetService->getPlanetCoordinates()->position; + // Get the bonus for the planet position + $bonus_planet_position_bonuses = $this->planetService->getProductionForPositionBonuses($position); // Assertions for production values with zero energy - $this->assertEquals(240, $this->planetService->getMetalProductionPerHour()); - $this->assertEquals(120, $this->planetService->getCrystalProductionPerHour()); + $this->assertEquals(240 * $bonus_planet_position_bonuses["metal"], $this->planetService->getMetalProductionPerHour()); + $this->assertEquals(120 * $bonus_planet_position_bonuses["crystal"], $this->planetService->getCrystalProductionPerHour()); $this->assertEquals(0, $this->planetService->getDeuteriumProductionPerHour()); }