mirror of
https://github.com/horizon-rust/horizon.git
synced 2026-11-07 11:06:11 -10:00
refactor: biome's spawn-list parsers live in biome.rs
parse_entries, parse_costs and SpawnCost read the biome JSON's natural_mob_spawns and build biome::SpawnEntry; biome.rs reached into mobs::spawn_selection for them, one of the edges that keep the client lib in a single cycle. They move to biome.rs and spawn_selection re-exports them. No behaviour change. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
167c3d14bd
commit
0f565f4e4c
5 files changed
+63
-58
No files matched your search
@@ -20,12 +20,68 @@ pub struct SpawnEntry {
|
||||
/// A `ConstantInt` count (sampling draws nothing).
|
||||
pub constant: bool,
|
||||
}
|
||||
/// A `natural_mob_spawns` / `spawn_overrides` entry list.
|
||||
pub fn parse_entries(list: &Value) -> Vec<SpawnEntry> {
|
||||
list.as_array()
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.filter_map(|e| {
|
||||
let count = &e["count"];
|
||||
let (min, max, constant) = match count {
|
||||
Value::Number(n) => {
|
||||
let n = n.as_u64().unwrap_or(1) as u32;
|
||||
(n, n, true)
|
||||
}
|
||||
c if c["type"].as_str() == Some("minecraft:constant") => {
|
||||
let n = c["value"].as_u64().unwrap_or(1) as u32;
|
||||
(n, n, true)
|
||||
}
|
||||
c => (
|
||||
c["min_inclusive"].as_u64().unwrap_or(1) as u32,
|
||||
c["max_inclusive"].as_u64().unwrap_or(1) as u32,
|
||||
false,
|
||||
),
|
||||
};
|
||||
Some(SpawnEntry {
|
||||
entity: e["type"].as_str()?.to_owned(),
|
||||
weight: e["weight"].as_u64().unwrap_or(1) as u32,
|
||||
min,
|
||||
max,
|
||||
constant,
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
/// `MobSpawnSettings.MobSpawnCost`.
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub struct SpawnCost {
|
||||
pub energy_budget: f64,
|
||||
pub charge: f64,
|
||||
}
|
||||
/// The `spawn_costs` of a `natural_mob_spawns` value.
|
||||
pub fn parse_costs(costs: &Value) -> HashMap<String, SpawnCost> {
|
||||
costs
|
||||
.as_object()
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.map(|(k, c)| {
|
||||
(
|
||||
k.clone(),
|
||||
SpawnCost {
|
||||
energy_budget: c["energy_budget"].as_f64().unwrap_or(0.0),
|
||||
charge: c["charge"].as_f64().unwrap_or(0.0),
|
||||
},
|
||||
)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct BiomeInfo {
|
||||
/// `natural_mob_spawns` by category (creature, monster, ...).
|
||||
pub spawns: HashMap<String, Vec<SpawnEntry>>,
|
||||
/// `natural_mob_spawns` spawn costs by entity type.
|
||||
pub spawn_costs: HashMap<String, crate::mobs::spawn_selection::SpawnCost>,
|
||||
pub spawn_costs: HashMap<String, SpawnCost>,
|
||||
/// The `gameplay/creature_world_gen_spawn_probability` attribute.
|
||||
pub creature_probability: f32,
|
||||
/// The `gameplay/increased_fire_burnout` attribute (jungles, swamps, peaks,
|
||||
@@ -143,12 +199,12 @@ impl Biomes {
|
||||
};
|
||||
let categories = &natural["spawns_by_category"];
|
||||
for (category, entries) in categories.as_object().into_iter().flatten() {
|
||||
let list = crate::mobs::spawn_selection::parse_entries(entries);
|
||||
let list = parse_entries(entries);
|
||||
spawns.insert(category.clone(), list);
|
||||
}
|
||||
list.push(BiomeInfo {
|
||||
spawns,
|
||||
spawn_costs: crate::mobs::spawn_selection::parse_costs(&natural["spawn_costs"]),
|
||||
spawn_costs: parse_costs(&natural["spawn_costs"]),
|
||||
creature_probability:
|
||||
attributes["minecraft:gameplay/creature_world_gen_spawn_probability"]
|
||||
.as_f64()
|
||||
|
||||
@@ -23,61 +23,7 @@ use horizon_core::{
|
||||
use serde_json::Value;
|
||||
use std::{collections::HashMap, fs, path::Path};
|
||||
|
||||
/// A `natural_mob_spawns` / `spawn_overrides` entry list.
|
||||
pub fn parse_entries(list: &Value) -> Vec<SpawnEntry> {
|
||||
list.as_array()
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.filter_map(|e| {
|
||||
let count = &e["count"];
|
||||
let (min, max, constant) = match count {
|
||||
Value::Number(n) => {
|
||||
let n = n.as_u64().unwrap_or(1) as u32;
|
||||
(n, n, true)
|
||||
}
|
||||
c if c["type"].as_str() == Some("minecraft:constant") => {
|
||||
let n = c["value"].as_u64().unwrap_or(1) as u32;
|
||||
(n, n, true)
|
||||
}
|
||||
c => (
|
||||
c["min_inclusive"].as_u64().unwrap_or(1) as u32,
|
||||
c["max_inclusive"].as_u64().unwrap_or(1) as u32,
|
||||
false,
|
||||
),
|
||||
};
|
||||
Some(SpawnEntry {
|
||||
entity: e["type"].as_str()?.to_owned(),
|
||||
weight: e["weight"].as_u64().unwrap_or(1) as u32,
|
||||
min,
|
||||
max,
|
||||
constant,
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
/// `MobSpawnSettings.MobSpawnCost`.
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub struct SpawnCost {
|
||||
pub energy_budget: f64,
|
||||
pub charge: f64,
|
||||
}
|
||||
/// The `spawn_costs` of a `natural_mob_spawns` value.
|
||||
pub fn parse_costs(costs: &Value) -> HashMap<String, SpawnCost> {
|
||||
costs
|
||||
.as_object()
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.map(|(k, c)| {
|
||||
(
|
||||
k.clone(),
|
||||
SpawnCost {
|
||||
energy_budget: c["energy_budget"].as_f64().unwrap_or(0.0),
|
||||
charge: c["charge"].as_f64().unwrap_or(0.0),
|
||||
},
|
||||
)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
pub use crate::biome::{SpawnCost, parse_costs, parse_entries};
|
||||
|
||||
/// `MobCategory`.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
|
||||
@@ -552,6 +552,7 @@ def main():
|
||||
oracle = lab.ROOT / 'mods/horizon/src/test/java/dev/horizonlab/parity/VanillaNaturalSpawnOracle.java'
|
||||
sources = [oracle, Path(__file__), lab.ROOT / 'crates/horizon-client/examples/probe/natural_spawn_fixture.rs',
|
||||
lab.ROOT / 'crates/horizon-client/src/mobs/spawn_selection.rs',
|
||||
lab.ROOT / 'crates/horizon-client/src/biome.rs',
|
||||
lab.ROOT / 'crates/horizon-client/src/mobs/spawn_rules.rs']
|
||||
tested = base.source_hashes(sources)
|
||||
inputs = build / 'inputs.txt'
|
||||
|
||||
@@ -233,6 +233,7 @@ def main():
|
||||
sources = [oracle, Path(__file__), lab.ROOT / 'crates/horizon-client/examples/probe/natural_spawn_fixture.rs',
|
||||
lab.ROOT / 'crates/horizon-client/src/mobs/spawner.rs',
|
||||
lab.ROOT / 'crates/horizon-client/src/mobs/spawn_selection.rs',
|
||||
lab.ROOT / 'crates/horizon-client/src/biome.rs',
|
||||
lab.ROOT / 'crates/horizon-client/src/mobs/spawn_rules.rs']
|
||||
tested = base.source_hashes(sources)
|
||||
inputs = build / 'inputs.txt'
|
||||
|
||||
@@ -198,6 +198,7 @@ def main():
|
||||
lab.ROOT / 'crates/horizon-client/src/mobs/trial_spawner.rs',
|
||||
lab.ROOT / 'crates/horizon-client/src/mobs/spawner.rs',
|
||||
lab.ROOT / 'crates/horizon-client/src/mobs/spawn_selection.rs',
|
||||
lab.ROOT / 'crates/horizon-client/src/biome.rs',
|
||||
lab.ROOT / 'crates/horizon-client/src/mobs/spawn_rules.rs']
|
||||
tested = base.source_hashes(sources)
|
||||
inputs = build / 'inputs.txt'
|
||||
|
||||
Reference in new issue
Block a user