Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 139 additions & 0 deletions inserter/src/algorithm/data/birth_points.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
use super::random::DspRandom;
use super::vector_f3::VectorF3;
use crate::algorithm::data::planet_raw_data::PlanetRawData;

/// Return value for gen_birth_points, containing the three birth positions.
#[derive(Debug, Clone)]
pub struct BirthPoints {
/// Main spawn point on the planet surface
pub birth_point: VectorF3,
/// First resource point
pub birth_resource_point0: VectorF3,
/// Second resource point
pub birth_resource_point1: VectorF3,
}

impl BirthPoints {
pub fn new(
raw_data: &mut PlanetRawData,
birth_seed: i32,
radius: f32,
star_direction: VectorF3,
) -> Self {
// ---- main GenBirthPoints(PlanetRawData, int) body (C# lines 761-821) --
let mut rand = DspRandom::new(birth_seed);

// vector3_1 is the incoming star_direction (already normalised)
let star_dir = star_direction.normalized();

// C#: Vector3 normalized1 = Vector3.Cross(vector3_1, Vector3.up).normalized
let mut basis1 = VectorF3::cross(&star_dir, &VectorF3::up()).normalized();
// C#: Vector3 normalized2 = Vector3.Cross(normalized1, vector3_1).normalized
let mut basis2 = VectorF3::cross(&basis1, &star_dir).normalized();

let num2 = 256;

// Outer loop – try up to 256 candidate birth directions
for _ in 0..num2 {
// C#: float num3 = (float)(dotNet35Random.NextDouble() * 2.0 - 1.0) * 0.5f
let num3 = (rand.next_f64() * 2.0 - 1.0) as f32 * 0.5;
// C#: float num4 = (float)(dotNet35Random.NextDouble() * 2.0 - 1.0) * 0.5f
let num4 = (rand.next_f64() * 2.0 - 1.0) as f32 * 0.5;

// C#: Vector3 vector3_2 = vector3_1 + num3 * normalized1 + num4 * normalized2
let mut candidate = star_dir + basis1 * num3 + basis2 * num4;
candidate.normalize();

// C#: this.birthPoint = vector3_2 * (realRadius + 0.2f + 1.45f);
// 0.2f + 1.45f = 1.65f, but keep the original constants for clarity
let birth_point = candidate * (radius + 0.2 + 1.45);

// C#: Vector3 vector3_3 = Vector3.Cross(vector3_2, Vector3.up);
// normalized1 = vector3_3.normalized;
let cross_tmp = VectorF3::cross(&candidate, &VectorF3::up());
basis1 = cross_tmp.normalized();
// C#: vector3_3 = Vector3.Cross(normalized1, vector3_2);
// normalized2 = vector3_3.normalized;
let cross_tmp2 = VectorF3::cross(&basis1, &candidate);
basis2 = cross_tmp2.normalized();

// Inner loop – try up to 10 resource-point offsets
for _ in 0..10 {
// C#: Vector2(x, y).normalized * 0.1f
let v2x = (rand.next_f64() * 2.0 - 1.0) as f32;
let v2y = (rand.next_f64() * 2.0 - 1.0) as f32;
let v2len = (v2x * v2x + v2y * v2y).sqrt();
let (v2x, v2y) = if v2len > 1e-10 {
(v2x / v2len * 0.1, v2y / v2len * 0.1)
} else {
(0.0, 0.0)
};

// C#: Vector2 vector2_2 = -vector2_1;
let v2x2 = -v2x;
let v2y2 = -v2y;

// C#: num5 = (float)(dotNet35Random.NextDouble() * 2.0 - 1.0) * 0.06f
let num5 = (rand.next_f64() * 2.0 - 1.0) as f32 * 0.06;
// C#: num6 = (float)(dotNet35Random.NextDouble() * 2.0 - 1.0) * 0.06f
let num6 = (rand.next_f64() * 2.0 - 1.0) as f32 * 0.06;

let v2x2 = v2x2 + num5;
let v2y2 = v2y2 + num6;

// C#: normalized3 = (vector3_2 + vector2_1.x * normalized1 + vector2_1.y * normalized2).normalized
let rp0_dir = (candidate + basis1 * v2x + basis2 * v2y).normalized();

// C#: normalized4 = (vector3_2 + vector2_2.x * normalized1 + vector2_2.y * normalized2).normalized
let rp1_dir = (candidate + basis1 * v2x2 + basis2 * v2y2).normalized();

// height threshold
let height_threshold = radius + 0.2;

// Use normalized variant since candidate, rp0_dir, rp1_dir are already unit-length
if raw_data.query_height_normalized(&candidate) > height_threshold
&& raw_data.query_height_normalized(&rp0_dir) > height_threshold
&& raw_data.query_height_normalized(&rp1_dir) > height_threshold
{
// C#: check 8 surrounding offsets
let vpos1 = rp0_dir + basis1 * 0.03;
let vpos2 = rp0_dir - basis1 * 0.03;
let vpos3 = rp0_dir + basis2 * 0.03;
let vpos4 = rp0_dir - basis2 * 0.03;
let vpos5 = rp1_dir + basis1 * 0.03;
let vpos6 = rp1_dir - basis1 * 0.03;
let vpos7 = rp1_dir + basis2 * 0.03;
let vpos8 = rp1_dir - basis2 * 0.03;

// Offset vectors are not unit-length; use the normalising variant
if raw_data.query_height(&vpos1) > height_threshold
&& raw_data.query_height(&vpos2) > height_threshold
&& raw_data.query_height(&vpos3) > height_threshold
&& raw_data.query_height(&vpos4) > height_threshold
&& raw_data.query_height(&vpos5) > height_threshold
&& raw_data.query_height(&vpos6) > height_threshold
&& raw_data.query_height(&vpos7) > height_threshold
&& raw_data.query_height(&vpos8) > height_threshold
{
// Re‑normalise both resource-point directions
let rp0 = rp0_dir.normalized();
let rp1 = rp1_dir.normalized();

return Self {
birth_point,
birth_resource_point0: rp0,
birth_resource_point1: rp1,
};
}
}
}
}

// ---- fallback (C# line 820) -------------------------------------------
Self {
birth_point: VectorF3(0.0, radius + 5.0, 0.0),
birth_resource_point0: VectorF3::up(),
birth_resource_point1: VectorF3::down(),
}
}
}
24 changes: 13 additions & 11 deletions inserter/src/algorithm/data/enums.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use serde::{Deserialize, Serialize};

#[allow(dead_code)]
#[repr(i32)]
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy, Deserialize, Serialize)]
pub enum StarType {
Expand All @@ -15,6 +16,7 @@ impl Default for StarType {
Self::MainSeqStar
}
}

#[allow(dead_code)]
#[repr(i32)]
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy, Deserialize, Serialize)]
Expand All @@ -34,7 +36,7 @@ pub enum SpectrType {
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy, Deserialize, Serialize)]
pub enum PlanetType {
None,
Vocano,
Volcano,
Ocean,
Desert,
Ice,
Expand Down Expand Up @@ -93,18 +95,18 @@ impl Default for VeinType {

impl VeinType {
pub fn is_rare(&self) -> bool {
match self {
matches!(
self,
VeinType::Fireice
| VeinType::Diamond
| VeinType::Fractal
| VeinType::Crysrub
| VeinType::Grat
| VeinType::Bamboo => true,
_ => false,
}
| VeinType::Diamond
| VeinType::Fractal
| VeinType::Crysrub
| VeinType::Grat
| VeinType::Bamboo
| VeinType::Mag
)
}
}

pub const ORES: [VeinType; 16] = [
VeinType::None,
VeinType::Iron,
Expand All @@ -122,4 +124,4 @@ pub const ORES: [VeinType; 16] = [
VeinType::Bamboo,
VeinType::Mag,
VeinType::Max,
];
];
33 changes: 25 additions & 8 deletions inserter/src/algorithm/data/game_desc.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
use std::cell::Cell;

use serde::{Deserialize, Serialize};

#[derive(Default, Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct GameDesc {
#[serde(default)]
pub seed: i32,
#[serde(default = "GameDesc::default_star_count")]
pub star_count: usize,
#[serde(default = "GameDesc::default_resource_multiplier")]
pub resource_multiplier: f32,
#[serde(skip)]
pub habitable_count: Cell<i32>,
#[serde(default = "GameDesc::default_hive_initial_colonize")]
pub hive_initial_colonize: f64,
#[serde(default = "GameDesc::default_hive_max_density")]
pub hive_max_density: f64,
#[serde(default)]
pub use_actual_veins: bool,
}

impl GameDesc {
Expand All @@ -22,6 +22,12 @@ impl GameDesc {
pub fn default_resource_multiplier() -> f32 {
1.0
}
pub fn default_hive_initial_colonize() -> f64 {
1.0
}
pub fn default_hive_max_density() -> f64 {
1.0
}

pub fn is_infinite_resource(&self) -> bool {
self.resource_multiplier >= 99.5
Expand All @@ -31,7 +37,7 @@ impl GameDesc {
self.resource_multiplier <= 0.1001
}

pub fn oil_amount_multipler(&self) -> f32 {
pub fn oil_amount_multiplier(&self) -> f32 {
if self.is_rare_resource() {
0.5
} else {
Expand All @@ -47,3 +53,14 @@ impl GameDesc {
}
}
}
impl Default for GameDesc {
fn default() -> Self {
Self {
star_count: 64,
resource_multiplier: 1.0,
hive_initial_colonize: 1.0,
hive_max_density: 1.0,
use_actual_veins: false
}
}
}
38 changes: 0 additions & 38 deletions inserter/src/algorithm/data/macros.rs

This file was deleted.

77 changes: 77 additions & 0 deletions inserter/src/algorithm/data/math.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/// Mathematical utility functions ported from Maths.cs
/// These are used by PlanetAlgorithm implementations.

/// Clamp a value between min and max (inclusive).
#[inline]
pub fn clamp<T: PartialOrd>(value: T, min: T, max: T) -> T {
if value < min {
min
} else if value > max {
max
} else {
value
}
}

/// Clamp a value between 0.0 and 1.0.
#[inline]
pub fn clamp01(value: f64) -> f64 {
clamp(value, 0.0, 1.0)
}

/// C# Levelize: smoothstep-based levelize
/// f = f / level - offset;
/// num1 = floor(f);
/// num2 = f - num1;
/// num3 = (3.0 - num2 - num2) * num2 * num2; (smoothstep)
/// f = num1 + num3;
/// f = (f + offset) * level;
#[inline]
pub fn levelize(f: f64, level: f64, offset: f64) -> f64 {
let f = f / level - offset;
let num1 = f.floor();
let num2 = f - num1;
let num3 = (3.0 - num2 - num2) * num2 * num2;
let f = num1 + num3;
(f + offset) * level
}

/// C# Levelize2: smoothstep applied twice (smoother steps)
#[inline]
pub fn levelize2(f: f64, level: f64, offset: f64) -> f64 {
let f = f / level - offset;
let num1 = f.floor();
let num2 = f - num1;
let num3 = (3.0 - num2 - num2) * num2 * num2;
let num4 = (3.0 - num3 - num3) * num3 * num3;
let f = num1 + num4;
(f + offset) * level
}

/// C# Levelize3: smoothstep applied three times (even smoother steps)
#[inline]
pub fn levelize3(f: f64, level: f64, offset: f64) -> f64 {
let f = f / level - offset;
let num1 = f.floor();
let num2 = f - num1;
let num3 = (3.0 - num2 - num2) * num2 * num2;
let num4 = (3.0 - num3 - num3) * num3 * num3;
let num5 = (3.0 - num4 - num4) * num4 * num4;
let f = num1 + num5;
(f + offset) * level
}

/// C# Levelize4: smoothstep applied four times (even smoother steps)
/// Uses floor() for correct negative-value handling.
#[inline]
pub fn levelize4(f: f64, level: f64, offset: f64) -> f64 {
let f = f / level - offset;
let num1 = f.floor();
let num2 = f - num1;
let num3 = (3.0 - num2 - num2) * num2 * num2;
let num4 = (3.0 - num3 - num3) * num3 * num3;
let num5 = (3.0 - num4 - num4) * num4 * num4;
let num6 = (3.0 - num5 - num5) * num5 * num5;
let f = num1 + num6;
(f + offset) * level
}
Loading
Loading