Skip to content
This repository has been archived by the owner on Nov 22, 2023. It is now read-only.

Commit

Permalink
Split apart structure and unit generation
Browse files Browse the repository at this point in the history
  • Loading branch information
alice-i-cecile committed Jun 27, 2023
1 parent af1d5a7 commit b54b4e7
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 82 deletions.
7 changes: 4 additions & 3 deletions emergence_lib/src/world_gen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ use crate::structures::structure_manifest::Structure;
use crate::terrain::terrain_manifest::Terrain;
use crate::units::unit_manifest::Unit;
use crate::utils::noise::SimplexSettings;
use crate::world_gen::structure_generation::{
generate_structures, generate_units, randomize_starting_organisms,
};
use crate::world_gen::structure_generation::generate_structures;
use crate::world_gen::unit_generation::{generate_units, randomize_starting_organisms};

use crate::world_gen::terrain_generation::{
generate_landmarks, generate_terrain, initialize_water_table,
};
Expand All @@ -18,6 +18,7 @@ use bevy_framepace::{FramepaceSettings, Limiter};

mod structure_generation;
mod terrain_generation;
mod unit_generation;

/// Generate the world.
pub(super) struct GenerationPlugin {
Expand Down
82 changes: 3 additions & 79 deletions emergence_lib/src/world_gen/structure_generation.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@
//! Initializes organisms in the world.
use crate::asset_management::manifest::Id;
use crate::crafting::inventories::{CraftingState, InputInventory, OutputInventory};
use crate::crafting::recipe::{ActiveRecipe, RecipeManifest};
use crate::geometry::{Facing, MapGeometry};
use crate::organisms::energy::{EnergyPool, StartingEnergy};
use crate::organisms::energy::StartingEnergy;
use crate::player_interaction::clipboard::ClipboardData;
use crate::simulation::rng::GlobalRng;
use crate::structures::commands::StructureCommandsExt;
use crate::structures::structure_manifest::{Structure, StructureManifest};
use crate::units::unit_assets::UnitHandles;
use crate::units::unit_manifest::UnitManifest;
use crate::units::UnitBundle;
use crate::structures::structure_manifest::StructureManifest;

use bevy::prelude::*;
use rand::{thread_rng, Rng};
use rand::Rng;

use super::GenerationConfig;

Expand Down Expand Up @@ -55,73 +49,3 @@ pub(super) fn generate_structures(
}
}
}

/// Create starting units according to [`GenerationConfig`], and randomly place them on
/// passable tiles.
pub(super) fn generate_units(
mut commands: Commands,
config: Res<GenerationConfig>,
maybe_unit_handles: Option<Res<UnitHandles>>,
unit_manifest: Res<UnitManifest>,
map_geometry: Res<MapGeometry>,
mut rng: ResMut<GlobalRng>,
) {
info!("Generating units...");

// Collect out so we can mutate the height map to flatten the terrain while in the loop
for voxel_pos in map_geometry.walkable_voxels() {
for (&unit_id, &chance) in &config.unit_chances {
if rng.gen::<f32>() < chance {
let unit_bundle = if let Some(ref unit_handles) = maybe_unit_handles {
UnitBundle::randomized(
unit_id,
voxel_pos,
unit_manifest.get(unit_id).clone(),
unit_handles,
rng.get_mut(),
)
} else {
UnitBundle::testing(
unit_id,
voxel_pos,
unit_manifest.get(unit_id).clone(),
rng.get_mut(),
)
};

commands.spawn(unit_bundle);
}
}
}
}

/// Sets all the starting organisms to a random state to avoid strange synchronization issues.
pub(super) fn randomize_starting_organisms(
// Energy pools for structures are randomized upon creation
mut energy_pool_query: Query<&mut EnergyPool, Without<Id<Structure>>>,
mut input_inventory_query: Query<&mut InputInventory>,
mut output_inventory_query: Query<&mut OutputInventory>,
mut crafting_state_query: Query<(&mut CraftingState, &ActiveRecipe)>,
recipe_manifest: Res<RecipeManifest>,
) {
let rng = &mut thread_rng();

for mut energy_pool in energy_pool_query.iter_mut() {
energy_pool.randomize(rng)
}

for mut input_inventory in input_inventory_query.iter_mut() {
input_inventory.randomize(rng)
}

for mut output_inventory in output_inventory_query.iter_mut() {
output_inventory.randomize(rng)
}

for (mut crafting_state, active_recipe) in crafting_state_query.iter_mut() {
if let Some(recipe_id) = active_recipe.recipe_id() {
let recipe_data = recipe_manifest.get(*recipe_id);
crafting_state.randomize(rng, recipe_data);
}
}
}
87 changes: 87 additions & 0 deletions emergence_lib/src/world_gen/unit_generation.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
//! Initializes organisms in the world.
use crate::asset_management::manifest::Id;
use crate::crafting::inventories::{CraftingState, InputInventory, OutputInventory};
use crate::crafting::recipe::{ActiveRecipe, RecipeManifest};
use crate::geometry::MapGeometry;
use crate::organisms::energy::EnergyPool;
use crate::simulation::rng::GlobalRng;
use crate::structures::structure_manifest::Structure;
use crate::units::unit_assets::UnitHandles;
use crate::units::unit_manifest::UnitManifest;
use crate::units::UnitBundle;

use bevy::prelude::*;
use rand::{thread_rng, Rng};

use super::GenerationConfig;

/// Create starting units according to [`GenerationConfig`], and randomly place them on
/// passable tiles.
pub(super) fn generate_units(
mut commands: Commands,
config: Res<GenerationConfig>,
maybe_unit_handles: Option<Res<UnitHandles>>,
unit_manifest: Res<UnitManifest>,
map_geometry: Res<MapGeometry>,
mut rng: ResMut<GlobalRng>,
) {
info!("Generating units...");

// Collect out so we can mutate the height map to flatten the terrain while in the loop
for voxel_pos in map_geometry.walkable_voxels() {
for (&unit_id, &chance) in &config.unit_chances {
if rng.gen::<f32>() < chance {
let unit_bundle = if let Some(ref unit_handles) = maybe_unit_handles {
UnitBundle::randomized(
unit_id,
voxel_pos,
unit_manifest.get(unit_id).clone(),
unit_handles,
rng.get_mut(),
)
} else {
UnitBundle::testing(
unit_id,
voxel_pos,
unit_manifest.get(unit_id).clone(),
rng.get_mut(),
)
};

commands.spawn(unit_bundle);
}
}
}
}

/// Sets all the starting organisms to a random state to avoid strange synchronization issues.
pub(super) fn randomize_starting_organisms(
// Energy pools for structures are randomized upon creation
mut energy_pool_query: Query<&mut EnergyPool, Without<Id<Structure>>>,
mut input_inventory_query: Query<&mut InputInventory>,
mut output_inventory_query: Query<&mut OutputInventory>,
mut crafting_state_query: Query<(&mut CraftingState, &ActiveRecipe)>,
recipe_manifest: Res<RecipeManifest>,
) {
let rng = &mut thread_rng();

for mut energy_pool in energy_pool_query.iter_mut() {
energy_pool.randomize(rng)
}

for mut input_inventory in input_inventory_query.iter_mut() {
input_inventory.randomize(rng)
}

for mut output_inventory in output_inventory_query.iter_mut() {
output_inventory.randomize(rng)
}

for (mut crafting_state, active_recipe) in crafting_state_query.iter_mut() {
if let Some(recipe_id) = active_recipe.recipe_id() {
let recipe_data = recipe_manifest.get(*recipe_id);
crafting_state.randomize(rng, recipe_data);
}
}
}

0 comments on commit b54b4e7

Please sign in to comment.