Skip to content

Commit

Permalink
Merge pull request #507 from yazilimmz/391-planet-size-calculation
Browse files Browse the repository at this point in the history
planet size calculation #391 fixes
  • Loading branch information
lanedirt authored Dec 24, 2024
2 parents f07b293 + da7bd09 commit 1d05dbc
Show file tree
Hide file tree
Showing 3 changed files with 196 additions and 10 deletions.
129 changes: 123 additions & 6 deletions app/Factories/PlanetServiceFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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.
Expand All @@ -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],
];
}
}
69 changes: 67 additions & 2 deletions app/Services/PlanetService.php
Original file line number Diff line number Diff line change
Expand Up @@ -1435,19 +1435,85 @@ 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);
}

$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];
}

/**
Expand Down Expand Up @@ -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();
Expand Down
8 changes: 6 additions & 2 deletions tests/Unit/ResourceProductionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand All @@ -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());
}

Expand Down

0 comments on commit 1d05dbc

Please sign in to comment.