mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'crabman/map_tweaks' into 'master'
Map tweaks & new default map See merge request veloren/veloren!4383
This commit is contained in:
commit
3ce82874a3
@ -105,6 +105,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Dropped items now merge dynamically (including non-stackables).
|
- Dropped items now merge dynamically (including non-stackables).
|
||||||
- You no longer need to unlock health, energy and roll skills to get to max.
|
- You no longer need to unlock health, energy and roll skills to get to max.
|
||||||
- Rolls now don't skip recovery, and instead have increased buildup during ability interrupts.
|
- Rolls now don't skip recovery, and instead have increased buildup during ability interrupts.
|
||||||
|
- Changed default world map
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
|
BIN
assets/world/map/veloren_0_16_0_0.bin
(Stored with Git LFS)
Normal file
BIN
assets/world/map/veloren_0_16_0_0.bin
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -17,3 +17,37 @@ pub enum BiomeKind {
|
|||||||
Savannah,
|
Savannah,
|
||||||
Taiga,
|
Taiga,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl BiomeKind {
|
||||||
|
/// Roughly represents the difficulty of a biome (value between 1 and 5)
|
||||||
|
pub fn difficulty(&self) -> i32 {
|
||||||
|
match self {
|
||||||
|
BiomeKind::Void => 1,
|
||||||
|
BiomeKind::Lake => 1,
|
||||||
|
BiomeKind::Grassland => 2,
|
||||||
|
BiomeKind::Ocean => 1,
|
||||||
|
BiomeKind::Mountain => 1,
|
||||||
|
BiomeKind::Snowland => 2,
|
||||||
|
BiomeKind::Desert => 5,
|
||||||
|
BiomeKind::Swamp => 2,
|
||||||
|
BiomeKind::Jungle => 3,
|
||||||
|
BiomeKind::Forest => 1,
|
||||||
|
BiomeKind::Savannah => 2,
|
||||||
|
BiomeKind::Taiga => 2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
#[test]
|
||||||
|
fn test_biome_difficulty() {
|
||||||
|
use strum::IntoEnumIterator;
|
||||||
|
|
||||||
|
for biome_kind in BiomeKind::iter() {
|
||||||
|
assert!(
|
||||||
|
(1..=5).contains(&biome_kind.difficulty()),
|
||||||
|
"Biome {biome_kind:?} has invalid difficulty {}",
|
||||||
|
biome_kind.difficulty()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -316,17 +316,7 @@ impl Data {
|
|||||||
// Try a few times to find a location that's not underwater
|
// Try a few times to find a location that's not underwater
|
||||||
if let Some((wpos, chunk)) = (0..100)
|
if let Some((wpos, chunk)) = (0..100)
|
||||||
.map(|_| world.sim().get_size().map(|sz| rng.gen_range(0..sz as i32)))
|
.map(|_| world.sim().get_size().map(|sz| rng.gen_range(0..sz as i32)))
|
||||||
.find_map(|pos| {
|
.find_map(|pos| Some((pos, world.sim().get(pos).filter(|c| !c.is_underwater())?)))
|
||||||
Some((
|
|
||||||
pos,
|
|
||||||
world
|
|
||||||
.sim()
|
|
||||||
.get(pos)
|
|
||||||
// This is currently a workaround to force Frost Gigas spawning in cold areas
|
|
||||||
// TODO: Once more Gigas are implemented remove this
|
|
||||||
.filter(|c| !c.is_underwater() && c.temp < CONFIG.snow_temp)?,
|
|
||||||
))
|
|
||||||
})
|
|
||||||
.map(|(pos, chunk)| {
|
.map(|(pos, chunk)| {
|
||||||
let wpos2d = pos.cpos_to_wpos_center();
|
let wpos2d = pos.cpos_to_wpos_center();
|
||||||
(
|
(
|
||||||
|
@ -146,7 +146,7 @@ use crate::{chat::ChatCache, persistence::character_loader::CharacterScreenRespo
|
|||||||
use common::comp::Anchor;
|
use common::comp::Anchor;
|
||||||
#[cfg(feature = "worldgen")]
|
#[cfg(feature = "worldgen")]
|
||||||
pub use world::{
|
pub use world::{
|
||||||
sim::{FileOpts, GenOpts, WorldOpts, DEFAULT_WORLD_MAP},
|
sim::{FileOpts, GenOpts, WorldOpts, DEFAULT_WORLD_MAP, DEFAULT_WORLD_SEED},
|
||||||
IndexOwned, World,
|
IndexOwned, World,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -30,11 +30,10 @@ use std::{
|
|||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
};
|
};
|
||||||
use tracing::{error, warn};
|
use tracing::{error, warn};
|
||||||
use world::sim::FileOpts;
|
use world::sim::{FileOpts, DEFAULT_WORLD_SEED};
|
||||||
|
|
||||||
use self::server_description::ServerDescription;
|
use self::server_description::ServerDescription;
|
||||||
|
|
||||||
const DEFAULT_WORLD_SEED: u32 = 230;
|
|
||||||
const CONFIG_DIR: &str = "server_config";
|
const CONFIG_DIR: &str = "server_config";
|
||||||
const SETTINGS_FILENAME: &str = "settings.ron";
|
const SETTINGS_FILENAME: &str = "settings.ron";
|
||||||
const WHITELIST_FILENAME: &str = "whitelist.ron";
|
const WHITELIST_FILENAME: &str = "whitelist.ron";
|
||||||
|
@ -15,7 +15,7 @@ pub fn criterion_benchmark(c: &mut Criterion) {
|
|||||||
let pool = rayon::ThreadPoolBuilder::new().build().unwrap();
|
let pool = rayon::ThreadPoolBuilder::new().build().unwrap();
|
||||||
// Generate chunks here to test
|
// Generate chunks here to test
|
||||||
let (world, index) = World::generate(
|
let (world, index) = World::generate(
|
||||||
42,
|
sim::DEFAULT_WORLD_SEED,
|
||||||
sim::WorldOpts {
|
sim::WorldOpts {
|
||||||
// NOTE: If this gets too expensive, we can turn it off.
|
// NOTE: If this gets too expensive, we can turn it off.
|
||||||
// TODO: Consider an option to turn off all erosion as well, or even provide altitude
|
// TODO: Consider an option to turn off all erosion as well, or even provide altitude
|
||||||
|
@ -32,6 +32,7 @@ use common::{
|
|||||||
};
|
};
|
||||||
use common_net::msg::world_msg::{SiteId, SiteInfo};
|
use common_net::msg::world_msg::{SiteId, SiteInfo};
|
||||||
use i18n::{Localization, LocalizationHandle};
|
use i18n::{Localization, LocalizationHandle};
|
||||||
|
use rand::{thread_rng, Rng};
|
||||||
//ImageFrame, Tooltip,
|
//ImageFrame, Tooltip,
|
||||||
use crate::settings::Settings;
|
use crate::settings::Settings;
|
||||||
//use std::time::Duration;
|
//use std::time::Duration;
|
||||||
@ -194,7 +195,7 @@ enum Mode {
|
|||||||
/// mode as opposed to create mode.
|
/// mode as opposed to create mode.
|
||||||
// TODO: Something less janky? Express the problem domain better!
|
// TODO: Something less janky? Express the problem domain better!
|
||||||
character_id: Option<CharacterId>,
|
character_id: Option<CharacterId>,
|
||||||
start_site_idx: usize,
|
start_site_idx: Option<usize>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,7 +249,7 @@ impl Mode {
|
|||||||
prev_starting_site_button: Default::default(),
|
prev_starting_site_button: Default::default(),
|
||||||
next_starting_site_button: Default::default(),
|
next_starting_site_button: Default::default(),
|
||||||
character_id: None,
|
character_id: None,
|
||||||
start_site_idx: 0,
|
start_site_idx: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,7 +279,7 @@ impl Mode {
|
|||||||
prev_starting_site_button: Default::default(),
|
prev_starting_site_button: Default::default(),
|
||||||
next_starting_site_button: Default::default(),
|
next_starting_site_button: Default::default(),
|
||||||
character_id: Some(character_id),
|
character_id: Some(character_id),
|
||||||
start_site_idx: 0,
|
start_site_idx: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1362,10 +1363,12 @@ impl Controls {
|
|||||||
//TODO: Add text-outline here whenever we updated iced to a version supporting
|
//TODO: Add text-outline here whenever we updated iced to a version supporting
|
||||||
// this
|
// this
|
||||||
|
|
||||||
let map = if let Some(info) = self.possible_starting_sites.get(*start_site_idx)
|
let map = if let Some(info) = self
|
||||||
|
.possible_starting_sites
|
||||||
|
.get(start_site_idx.unwrap_or_default())
|
||||||
{
|
{
|
||||||
let site_name = Text::new(
|
let site_name = Text::new(
|
||||||
self.possible_starting_sites[*start_site_idx]
|
self.possible_starting_sites[start_site_idx.unwrap_or_default()]
|
||||||
.name
|
.name
|
||||||
.as_deref()
|
.as_deref()
|
||||||
.unwrap_or("Unknown"),
|
.unwrap_or("Unknown"),
|
||||||
@ -1405,12 +1408,16 @@ impl Controls {
|
|||||||
if self.possible_starting_sites.is_empty() {
|
if self.possible_starting_sites.is_empty() {
|
||||||
vec![map]
|
vec![map]
|
||||||
} else {
|
} else {
|
||||||
|
let selected = start_site_idx.get_or_insert_with(|| {
|
||||||
|
thread_rng().gen_range(0..self.possible_starting_sites.len())
|
||||||
|
});
|
||||||
|
|
||||||
let site_slider = starter_slider(
|
let site_slider = starter_slider(
|
||||||
i18n.get_msg("char_selection-starting_site").into_owned(),
|
i18n.get_msg("char_selection-starting_site").into_owned(),
|
||||||
30,
|
30,
|
||||||
&mut sliders.starting_site,
|
&mut sliders.starting_site,
|
||||||
self.possible_starting_sites.len() as u32 - 1,
|
self.possible_starting_sites.len() as u32 - 1,
|
||||||
*start_site_idx as u32,
|
*selected as u32,
|
||||||
|x| Message::StartingSite(x as usize),
|
|x| Message::StartingSite(x as usize),
|
||||||
imgs,
|
imgs,
|
||||||
);
|
);
|
||||||
@ -1801,7 +1808,7 @@ impl Controls {
|
|||||||
body: comp::Body::Humanoid(*body),
|
body: comp::Body::Humanoid(*body),
|
||||||
start_site: self
|
start_site: self
|
||||||
.possible_starting_sites
|
.possible_starting_sites
|
||||||
.get(*start_site_idx)
|
.get(start_site_idx.unwrap_or_default())
|
||||||
.map(|info| info.id),
|
.map(|info| info.id),
|
||||||
});
|
});
|
||||||
self.mode = Mode::select(Some(InfoContent::CreatingCharacter));
|
self.mode = Mode::select(Some(InfoContent::CreatingCharacter));
|
||||||
@ -1863,7 +1870,6 @@ impl Controls {
|
|||||||
//Todo: Add species and body type to randomization.
|
//Todo: Add species and body type to randomization.
|
||||||
Message::RandomizeCharacter => {
|
Message::RandomizeCharacter => {
|
||||||
if let Mode::CreateOrEdit { body, .. } = &mut self.mode {
|
if let Mode::CreateOrEdit { body, .. } = &mut self.mode {
|
||||||
use rand::Rng;
|
|
||||||
let body_type = body.body_type;
|
let body_type = body.body_type;
|
||||||
let species = body.species;
|
let species = body.species;
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
@ -1930,24 +1936,30 @@ impl Controls {
|
|||||||
},
|
},
|
||||||
Message::StartingSite(idx) => {
|
Message::StartingSite(idx) => {
|
||||||
if let Mode::CreateOrEdit { start_site_idx, .. } = &mut self.mode {
|
if let Mode::CreateOrEdit { start_site_idx, .. } = &mut self.mode {
|
||||||
*start_site_idx = idx;
|
*start_site_idx = Some(idx);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Message::PrevStartingSite => {
|
Message::PrevStartingSite => {
|
||||||
if let Mode::CreateOrEdit { start_site_idx, .. } = &mut self.mode {
|
if let Mode::CreateOrEdit { start_site_idx, .. } = &mut self.mode {
|
||||||
if !self.possible_starting_sites.is_empty() {
|
if !self.possible_starting_sites.is_empty() {
|
||||||
*start_site_idx = (*start_site_idx + self.possible_starting_sites.len()
|
*start_site_idx = Some(
|
||||||
- 1)
|
(start_site_idx.unwrap_or_default()
|
||||||
% self.possible_starting_sites.len();
|
+ self.possible_starting_sites.len()
|
||||||
|
- 1)
|
||||||
|
% self.possible_starting_sites.len(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Message::NextStartingSite => {
|
Message::NextStartingSite => {
|
||||||
if let Mode::CreateOrEdit { start_site_idx, .. } = &mut self.mode {
|
if let Mode::CreateOrEdit { start_site_idx, .. } = &mut self.mode {
|
||||||
if !self.possible_starting_sites.is_empty() {
|
if !self.possible_starting_sites.is_empty() {
|
||||||
*start_site_idx =
|
*start_site_idx = Some(
|
||||||
(*start_site_idx + self.possible_starting_sites.len() + 1)
|
(start_site_idx.unwrap_or_default()
|
||||||
% self.possible_starting_sites.len();
|
+ self.possible_starting_sites.len()
|
||||||
|
+ 1)
|
||||||
|
% self.possible_starting_sites.len(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -6,7 +6,7 @@ use std::{
|
|||||||
|
|
||||||
use common::{assets::ASSETS_PATH, consts::DAY_LENGTH_DEFAULT};
|
use common::{assets::ASSETS_PATH, consts::DAY_LENGTH_DEFAULT};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use server::{FileOpts, GenOpts, DEFAULT_WORLD_MAP};
|
use server::{FileOpts, GenOpts, DEFAULT_WORLD_MAP, DEFAULT_WORLD_SEED};
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, Serialize)]
|
#[derive(Clone, Deserialize, Serialize)]
|
||||||
@ -84,7 +84,7 @@ fn migrate_old_singleplayer(from: &Path, to: &Path) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut seed = 0;
|
let mut seed = DEFAULT_WORLD_SEED;
|
||||||
let mut day_length = DAY_LENGTH_DEFAULT;
|
let mut day_length = DAY_LENGTH_DEFAULT;
|
||||||
let (map_file, gen_opts) = fs::read_to_string(to.join("server_config/settings.ron"))
|
let (map_file, gen_opts) = fs::read_to_string(to.join("server_config/settings.ron"))
|
||||||
.ok()
|
.ok()
|
||||||
@ -238,7 +238,7 @@ impl SingleplayerWorlds {
|
|||||||
name: "New World".to_string(),
|
name: "New World".to_string(),
|
||||||
gen_opts: None,
|
gen_opts: None,
|
||||||
day_length: DAY_LENGTH_DEFAULT,
|
day_length: DAY_LENGTH_DEFAULT,
|
||||||
seed: 0,
|
seed: DEFAULT_WORLD_SEED,
|
||||||
is_generated: false,
|
is_generated: false,
|
||||||
map_path: path.join("map.bin"),
|
map_path: path.join("map.bin"),
|
||||||
path,
|
path,
|
||||||
|
@ -3,14 +3,14 @@ use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
|||||||
use rayon::ThreadPoolBuilder;
|
use rayon::ThreadPoolBuilder;
|
||||||
use veloren_world::{
|
use veloren_world::{
|
||||||
layer,
|
layer,
|
||||||
sim::{FileOpts, WorldOpts, DEFAULT_WORLD_MAP},
|
sim::{FileOpts, WorldOpts, DEFAULT_WORLD_MAP, DEFAULT_WORLD_SEED},
|
||||||
CanvasInfo, Land, World,
|
CanvasInfo, Land, World,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn cave(c: &mut Criterion) {
|
fn cave(c: &mut Criterion) {
|
||||||
let pool = ThreadPoolBuilder::new().build().unwrap();
|
let pool = ThreadPoolBuilder::new().build().unwrap();
|
||||||
let (world, index) = World::generate(
|
let (world, index) = World::generate(
|
||||||
230,
|
DEFAULT_WORLD_SEED,
|
||||||
WorldOpts {
|
WorldOpts {
|
||||||
seed_elements: true,
|
seed_elements: true,
|
||||||
world_file: FileOpts::LoadAsset(DEFAULT_WORLD_MAP.into()),
|
world_file: FileOpts::LoadAsset(DEFAULT_WORLD_MAP.into()),
|
||||||
|
@ -6,14 +6,14 @@ use veloren_world::{
|
|||||||
self,
|
self,
|
||||||
cave::{Biome, LAYERS},
|
cave::{Biome, LAYERS},
|
||||||
},
|
},
|
||||||
sim::{FileOpts, WorldOpts, DEFAULT_WORLD_MAP},
|
sim::{FileOpts, WorldOpts, DEFAULT_WORLD_MAP, DEFAULT_WORLD_SEED},
|
||||||
CanvasInfo, Land, World,
|
CanvasInfo, Land, World,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let pool = ThreadPoolBuilder::new().build().unwrap();
|
let pool = ThreadPoolBuilder::new().build().unwrap();
|
||||||
let (world, index) = World::generate(
|
let (world, index) = World::generate(
|
||||||
230,
|
DEFAULT_WORLD_SEED,
|
||||||
WorldOpts {
|
WorldOpts {
|
||||||
seed_elements: true,
|
seed_elements: true,
|
||||||
world_file: FileOpts::LoadAsset(DEFAULT_WORLD_MAP.into()),
|
world_file: FileOpts::LoadAsset(DEFAULT_WORLD_MAP.into()),
|
||||||
|
@ -29,7 +29,7 @@ use tracing::{debug, trace};
|
|||||||
use vek::*;
|
use vek::*;
|
||||||
use veloren_world::{
|
use veloren_world::{
|
||||||
civ::SiteKind,
|
civ::SiteKind,
|
||||||
sim::{FileOpts, WorldOpts, DEFAULT_WORLD_MAP},
|
sim::{FileOpts, WorldOpts, DEFAULT_WORLD_MAP, DEFAULT_WORLD_SEED},
|
||||||
World,
|
World,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -682,7 +682,7 @@ fn main() {
|
|||||||
common_frontend::init_stdout(None);
|
common_frontend::init_stdout(None);
|
||||||
println!("Loading world");
|
println!("Loading world");
|
||||||
let (world, index) = World::generate(
|
let (world, index) = World::generate(
|
||||||
59686,
|
DEFAULT_WORLD_SEED,
|
||||||
WorldOpts {
|
WorldOpts {
|
||||||
seed_elements: true,
|
seed_elements: true,
|
||||||
world_file: FileOpts::LoadAsset(DEFAULT_WORLD_MAP.into()),
|
world_file: FileOpts::LoadAsset(DEFAULT_WORLD_MAP.into()),
|
||||||
|
@ -12,7 +12,7 @@ use common::{
|
|||||||
use rayon::ThreadPoolBuilder;
|
use rayon::ThreadPoolBuilder;
|
||||||
use vek::{Vec2, Vec3};
|
use vek::{Vec2, Vec3};
|
||||||
use veloren_world::{
|
use veloren_world::{
|
||||||
sim::{FileOpts, WorldOpts, DEFAULT_WORLD_MAP},
|
sim::{FileOpts, WorldOpts, DEFAULT_WORLD_MAP, DEFAULT_WORLD_SEED},
|
||||||
site2::{plot::PlotKind, Fill, Structure},
|
site2::{plot::PlotKind, Fill, Structure},
|
||||||
CanvasInfo, Land, World,
|
CanvasInfo, Land, World,
|
||||||
};
|
};
|
||||||
@ -25,7 +25,7 @@ fn main() -> Result {
|
|||||||
let pool = ThreadPoolBuilder::new().build().unwrap();
|
let pool = ThreadPoolBuilder::new().build().unwrap();
|
||||||
println!("Loading world");
|
println!("Loading world");
|
||||||
let (world, index) = World::generate(
|
let (world, index) = World::generate(
|
||||||
59686,
|
DEFAULT_WORLD_SEED,
|
||||||
WorldOpts {
|
WorldOpts {
|
||||||
seed_elements: true,
|
seed_elements: true,
|
||||||
world_file: FileOpts::LoadAsset(DEFAULT_WORLD_MAP.into()),
|
world_file: FileOpts::LoadAsset(DEFAULT_WORLD_MAP.into()),
|
||||||
|
@ -6,7 +6,7 @@ use rayon::ThreadPoolBuilder;
|
|||||||
use std::{fs::File, io::Write};
|
use std::{fs::File, io::Write};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
use veloren_world::{
|
use veloren_world::{
|
||||||
sim::{FileOpts, WorldOpts, DEFAULT_WORLD_MAP},
|
sim::{FileOpts, WorldOpts, DEFAULT_WORLD_MAP, DEFAULT_WORLD_SEED},
|
||||||
Land, World,
|
Land, World,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -120,7 +120,7 @@ fn main() {
|
|||||||
let pool = ThreadPoolBuilder::new().build().unwrap();
|
let pool = ThreadPoolBuilder::new().build().unwrap();
|
||||||
println!("Loading world");
|
println!("Loading world");
|
||||||
let (world, _index) = World::generate(
|
let (world, _index) = World::generate(
|
||||||
59686,
|
DEFAULT_WORLD_SEED,
|
||||||
WorldOpts {
|
WorldOpts {
|
||||||
seed_elements: true,
|
seed_elements: true,
|
||||||
world_file: FileOpts::LoadAsset(DEFAULT_WORLD_MAP.into()),
|
world_file: FileOpts::LoadAsset(DEFAULT_WORLD_MAP.into()),
|
||||||
|
@ -9,7 +9,7 @@ use strum::IntoEnumIterator;
|
|||||||
use vek::Vec2;
|
use vek::Vec2;
|
||||||
use veloren_world::{
|
use veloren_world::{
|
||||||
index::Index,
|
index::Index,
|
||||||
sim::{FileOpts, WorldOpts, DEFAULT_WORLD_MAP},
|
sim::{FileOpts, WorldOpts, DEFAULT_WORLD_MAP, DEFAULT_WORLD_SEED},
|
||||||
World,
|
World,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -162,7 +162,7 @@ fn main() {
|
|||||||
println!("Loading world");
|
println!("Loading world");
|
||||||
let pool = ThreadPoolBuilder::new().build().unwrap();
|
let pool = ThreadPoolBuilder::new().build().unwrap();
|
||||||
let (world, index) = World::generate(
|
let (world, index) = World::generate(
|
||||||
59686,
|
DEFAULT_WORLD_SEED,
|
||||||
WorldOpts {
|
WorldOpts {
|
||||||
seed_elements: true,
|
seed_elements: true,
|
||||||
world_file: FileOpts::LoadAsset(DEFAULT_WORLD_MAP.into()),
|
world_file: FileOpts::LoadAsset(DEFAULT_WORLD_MAP.into()),
|
||||||
|
@ -15,7 +15,7 @@ use tracing_subscriber::{
|
|||||||
};
|
};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
use veloren_world::{
|
use veloren_world::{
|
||||||
sim::{self, get_horizon_map, sample_pos, sample_wpos, WorldOpts},
|
sim::{self, get_horizon_map, sample_pos, sample_wpos, WorldOpts, DEFAULT_WORLD_SEED},
|
||||||
util::Sampler,
|
util::Sampler,
|
||||||
ColumnSample, World, CONFIG,
|
ColumnSample, World, CONFIG,
|
||||||
};
|
};
|
||||||
@ -43,7 +43,7 @@ fn main() {
|
|||||||
_map_file.push(map_file);
|
_map_file.push(map_file);
|
||||||
|
|
||||||
let (world, index) = World::generate(
|
let (world, index) = World::generate(
|
||||||
5284,
|
DEFAULT_WORLD_SEED,
|
||||||
WorldOpts {
|
WorldOpts {
|
||||||
seed_elements: false,
|
seed_elements: false,
|
||||||
world_file: sim::FileOpts::LoadAsset(sim::DEFAULT_WORLD_MAP.into()),
|
world_file: sim::FileOpts::LoadAsset(sim::DEFAULT_WORLD_MAP.into()),
|
||||||
|
@ -21,7 +21,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
use veloren_world::{
|
use veloren_world::{
|
||||||
sim::{FileOpts, WorldOpts, DEFAULT_WORLD_MAP},
|
sim::{FileOpts, WorldOpts, DEFAULT_WORLD_MAP, DEFAULT_WORLD_SEED},
|
||||||
World,
|
World,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -63,7 +63,7 @@ fn generate(db_path: &str, ymin: Option<i32>, ymax: Option<i32>) -> Result<(), B
|
|||||||
println!("Loading world");
|
println!("Loading world");
|
||||||
let pool = ThreadPoolBuilder::new().build().unwrap();
|
let pool = ThreadPoolBuilder::new().build().unwrap();
|
||||||
let (world, index) = World::generate(
|
let (world, index) = World::generate(
|
||||||
59686,
|
DEFAULT_WORLD_SEED,
|
||||||
WorldOpts {
|
WorldOpts {
|
||||||
seed_elements: true,
|
seed_elements: true,
|
||||||
world_file: FileOpts::LoadAsset(DEFAULT_WORLD_MAP.into()),
|
world_file: FileOpts::LoadAsset(DEFAULT_WORLD_MAP.into()),
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use veloren_world::{
|
use veloren_world::{
|
||||||
sim::{FileOpts, WorldOpts, DEFAULT_WORLD_MAP},
|
sim::{FileOpts, WorldOpts, DEFAULT_WORLD_MAP, DEFAULT_WORLD_SEED},
|
||||||
World,
|
World,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -9,7 +9,7 @@ fn main() {
|
|||||||
|
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
let (world, index) = World::generate(
|
let (world, index) = World::generate(
|
||||||
0,
|
DEFAULT_WORLD_SEED,
|
||||||
WorldOpts {
|
WorldOpts {
|
||||||
seed_elements: true,
|
seed_elements: true,
|
||||||
// Load default map from assets.
|
// Load default map from assets.
|
||||||
|
@ -278,7 +278,7 @@ impl Civs {
|
|||||||
let world_dims = ctx.sim.get_aabr();
|
let world_dims = ctx.sim.get_aabr();
|
||||||
for _ in 0..initial_civ_count * 3 {
|
for _ in 0..initial_civ_count * 3 {
|
||||||
attempt(5, || {
|
attempt(5, || {
|
||||||
let (loc, kind) = match ctx.rng.gen_range(0..115) {
|
let (loc, kind) = match ctx.rng.gen_range(0..90) {
|
||||||
0..=4 => {
|
0..=4 => {
|
||||||
if index.features().site2_giant_trees {
|
if index.features().site2_giant_trees {
|
||||||
(
|
(
|
||||||
@ -304,7 +304,7 @@ impl Civs {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
5..=10 => (
|
5..=15 => (
|
||||||
find_site_loc(
|
find_site_loc(
|
||||||
&mut ctx,
|
&mut ctx,
|
||||||
&ProximityRequirementsBuilder::new()
|
&ProximityRequirementsBuilder::new()
|
||||||
@ -314,7 +314,7 @@ impl Civs {
|
|||||||
)?,
|
)?,
|
||||||
SiteKind::Gnarling,
|
SiteKind::Gnarling,
|
||||||
),
|
),
|
||||||
11..=16 => (
|
16..=20 => (
|
||||||
find_site_loc(
|
find_site_loc(
|
||||||
&mut ctx,
|
&mut ctx,
|
||||||
&ProximityRequirementsBuilder::new()
|
&ProximityRequirementsBuilder::new()
|
||||||
@ -324,7 +324,7 @@ impl Civs {
|
|||||||
)?,
|
)?,
|
||||||
SiteKind::ChapelSite,
|
SiteKind::ChapelSite,
|
||||||
),
|
),
|
||||||
17..=22 => (
|
21..=27 => (
|
||||||
find_site_loc(
|
find_site_loc(
|
||||||
&mut ctx,
|
&mut ctx,
|
||||||
&ProximityRequirementsBuilder::new()
|
&ProximityRequirementsBuilder::new()
|
||||||
@ -334,7 +334,7 @@ impl Civs {
|
|||||||
)?,
|
)?,
|
||||||
SiteKind::Adlet,
|
SiteKind::Adlet,
|
||||||
),
|
),
|
||||||
23..=35 => (
|
28..=38 => (
|
||||||
find_site_loc(
|
find_site_loc(
|
||||||
&mut ctx,
|
&mut ctx,
|
||||||
&ProximityRequirementsBuilder::new()
|
&ProximityRequirementsBuilder::new()
|
||||||
@ -344,7 +344,7 @@ impl Civs {
|
|||||||
)?,
|
)?,
|
||||||
SiteKind::PirateHideout,
|
SiteKind::PirateHideout,
|
||||||
),
|
),
|
||||||
36..=42 => (
|
39..=45 => (
|
||||||
find_site_loc(
|
find_site_loc(
|
||||||
&mut ctx,
|
&mut ctx,
|
||||||
&ProximityRequirementsBuilder::new()
|
&ProximityRequirementsBuilder::new()
|
||||||
@ -354,7 +354,7 @@ impl Civs {
|
|||||||
)?,
|
)?,
|
||||||
SiteKind::JungleRuin,
|
SiteKind::JungleRuin,
|
||||||
),
|
),
|
||||||
43..=49 => (
|
46..=55 => (
|
||||||
find_site_loc(
|
find_site_loc(
|
||||||
&mut ctx,
|
&mut ctx,
|
||||||
&ProximityRequirementsBuilder::new()
|
&ProximityRequirementsBuilder::new()
|
||||||
@ -364,7 +364,7 @@ impl Civs {
|
|||||||
)?,
|
)?,
|
||||||
SiteKind::RockCircle,
|
SiteKind::RockCircle,
|
||||||
),
|
),
|
||||||
50..=59 => (
|
56..=66 => (
|
||||||
find_site_loc(
|
find_site_loc(
|
||||||
&mut ctx,
|
&mut ctx,
|
||||||
&ProximityRequirementsBuilder::new()
|
&ProximityRequirementsBuilder::new()
|
||||||
@ -374,7 +374,7 @@ impl Civs {
|
|||||||
)?,
|
)?,
|
||||||
SiteKind::TrollCave,
|
SiteKind::TrollCave,
|
||||||
),
|
),
|
||||||
60..=69 => (
|
67..=72 => (
|
||||||
find_site_loc(
|
find_site_loc(
|
||||||
&mut ctx,
|
&mut ctx,
|
||||||
&ProximityRequirementsBuilder::new()
|
&ProximityRequirementsBuilder::new()
|
||||||
@ -384,7 +384,7 @@ impl Civs {
|
|||||||
)?,
|
)?,
|
||||||
SiteKind::Camp,
|
SiteKind::Camp,
|
||||||
),
|
),
|
||||||
70..=74 => (
|
73..=76 => (
|
||||||
find_site_loc(
|
find_site_loc(
|
||||||
&mut ctx,
|
&mut ctx,
|
||||||
&ProximityRequirementsBuilder::new()
|
&ProximityRequirementsBuilder::new()
|
||||||
@ -394,7 +394,7 @@ impl Civs {
|
|||||||
)?,
|
)?,
|
||||||
SiteKind::Haniwa,
|
SiteKind::Haniwa,
|
||||||
),
|
),
|
||||||
75..=85 => (
|
77..=79 => (
|
||||||
find_site_loc(
|
find_site_loc(
|
||||||
&mut ctx,
|
&mut ctx,
|
||||||
&ProximityRequirementsBuilder::new()
|
&ProximityRequirementsBuilder::new()
|
||||||
@ -404,7 +404,7 @@ impl Civs {
|
|||||||
)?,
|
)?,
|
||||||
SiteKind::Terracotta,
|
SiteKind::Terracotta,
|
||||||
),
|
),
|
||||||
/*86..=91 => (
|
/*80..=86 => (
|
||||||
find_site_loc(
|
find_site_loc(
|
||||||
&mut ctx,
|
&mut ctx,
|
||||||
&ProximityRequirementsBuilder::new()
|
&ProximityRequirementsBuilder::new()
|
||||||
@ -414,7 +414,7 @@ impl Civs {
|
|||||||
)?,
|
)?,
|
||||||
SiteKind::DwarvenMine,
|
SiteKind::DwarvenMine,
|
||||||
),
|
),
|
||||||
92..=97 => (
|
86..=97 => (
|
||||||
find_site_loc(
|
find_site_loc(
|
||||||
&mut ctx,
|
&mut ctx,
|
||||||
&ProximityRequirementsBuilder::new()
|
&ProximityRequirementsBuilder::new()
|
||||||
@ -945,10 +945,10 @@ impl Civs {
|
|||||||
fn birth_civ(&mut self, ctx: &mut GenCtx<impl Rng>) -> Option<Id<Civ>> {
|
fn birth_civ(&mut self, ctx: &mut GenCtx<impl Rng>) -> Option<Id<Civ>> {
|
||||||
// TODO: specify SiteKind based on where a suitable location is found
|
// TODO: specify SiteKind based on where a suitable location is found
|
||||||
let kind = match ctx.rng.gen_range(0..64) {
|
let kind = match ctx.rng.gen_range(0..64) {
|
||||||
0..=10 => SiteKind::CliffTown,
|
0..=8 => SiteKind::CliffTown,
|
||||||
11..=12 => SiteKind::DesertCity,
|
9..=17 => SiteKind::DesertCity,
|
||||||
13..=18 => SiteKind::SavannahPit,
|
18..=23 => SiteKind::SavannahPit,
|
||||||
19..=36 => SiteKind::CoastalTown,
|
24..=33 => SiteKind::CoastalTown,
|
||||||
_ => SiteKind::Refactor,
|
_ => SiteKind::Refactor,
|
||||||
};
|
};
|
||||||
let world_dims = ctx.sim.get_aabr();
|
let world_dims = ctx.sim.get_aabr();
|
||||||
@ -1558,11 +1558,7 @@ impl Civs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn tree_enemies(&self) -> impl Iterator<Item = Vec2<i32>> + '_ {
|
fn tree_enemies(&self) -> impl Iterator<Item = Vec2<i32>> + '_ {
|
||||||
self.sites().filter_map(|s| match s.kind {
|
self.sites().map(|s| s.center)
|
||||||
SiteKind::Castle => Some(s.center),
|
|
||||||
_ if s.is_settlement() => Some(s.center),
|
|
||||||
_ => None,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn castle_enemies(&self) -> impl Iterator<Item = Vec2<i32>> + '_ {
|
fn castle_enemies(&self) -> impl Iterator<Item = Vec2<i32>> + '_ {
|
||||||
|
@ -36,7 +36,7 @@ pub use block::BlockGen;
|
|||||||
use civ::WorldCivStage;
|
use civ::WorldCivStage;
|
||||||
pub use column::ColumnSample;
|
pub use column::ColumnSample;
|
||||||
pub use common::terrain::site::{DungeonKindMeta, SettlementKindMeta};
|
pub use common::terrain::site::{DungeonKindMeta, SettlementKindMeta};
|
||||||
use common::terrain::CoordinateConversions;
|
use common::{spiral::Spiral2d, terrain::CoordinateConversions};
|
||||||
pub use index::{IndexOwned, IndexRef};
|
pub use index::{IndexOwned, IndexRef};
|
||||||
use sim::WorldSimStage;
|
use sim::WorldSimStage;
|
||||||
|
|
||||||
@ -249,7 +249,7 @@ impl World {
|
|||||||
}))
|
}))
|
||||||
.collect(),
|
.collect(),
|
||||||
possible_starting_sites: {
|
possible_starting_sites: {
|
||||||
const STARTING_SITE_COUNT: usize = 4;
|
const STARTING_SITE_COUNT: usize = 5;
|
||||||
|
|
||||||
let mut candidates = self
|
let mut candidates = self
|
||||||
.civs()
|
.civs()
|
||||||
@ -258,21 +258,55 @@ impl World {
|
|||||||
.filter_map(|(_, civ_site)| Some((civ_site, civ_site.site_tmp?)))
|
.filter_map(|(_, civ_site)| Some((civ_site, civ_site.site_tmp?)))
|
||||||
.map(|(civ_site, site_id)| {
|
.map(|(civ_site, site_id)| {
|
||||||
// Score the site according to how suitable it is to be a starting site
|
// Score the site according to how suitable it is to be a starting site
|
||||||
let mut score = 0.0;
|
|
||||||
|
|
||||||
if let SiteKind::Refactor(site2) = &index.sites[site_id].kind {
|
let (site2, mut score) = match &index.sites[site_id].kind {
|
||||||
// Strongly prefer towns
|
SiteKind::Refactor(site2) => (site2, 2.0),
|
||||||
score += 1000.0;
|
// Non-town sites should not be chosen as starting sites and get a score of 0
|
||||||
// Prefer sites of a medium size
|
_ => return (site_id.id(), 0.0)
|
||||||
score += 2.0 / (1.0 + (site2.plots().len() as f32 - 20.0).abs() / 10.0);
|
|
||||||
};
|
};
|
||||||
// Prefer sites in hospitable climates
|
|
||||||
if let Some(chunk) = self.sim().get(civ_site.center) {
|
/// Optimal number of plots in a starter town
|
||||||
score += 1.0 / (1.0 + chunk.temp.abs());
|
const OPTIMAL_STARTER_TOWN_SIZE: f32 = 30.0;
|
||||||
score += 1.0 / (1.0 + (chunk.humidity - CONFIG.forest_hum).abs() * 2.0);
|
|
||||||
}
|
// Prefer sites of a medium size
|
||||||
|
let plots = site2.plots().len() as f32;
|
||||||
|
let size_score = if plots > OPTIMAL_STARTER_TOWN_SIZE {
|
||||||
|
1.0 + (1.0 / (1.0 + ((plots - OPTIMAL_STARTER_TOWN_SIZE) / 15.0).powi(3)))
|
||||||
|
} else {
|
||||||
|
(2.05 / (1.0 + ((OPTIMAL_STARTER_TOWN_SIZE - plots) / 15.0).powi(5))) - 0.05
|
||||||
|
}.max(0.01);
|
||||||
|
|
||||||
|
score *= size_score;
|
||||||
|
|
||||||
// Prefer sites that are close to the centre of the world
|
// Prefer sites that are close to the centre of the world
|
||||||
score += 4.0 / (1.0 + civ_site.center.map2(self.sim().get_size(), |e, sz| (e as f32 / sz as f32 - 0.5).abs() * 2.0).reduce_partial_max());
|
let pos_score = (
|
||||||
|
10.0 / (
|
||||||
|
1.0 + (
|
||||||
|
civ_site.center.map2(self.sim().get_size(),
|
||||||
|
|e, sz|
|
||||||
|
(e as f32 / sz as f32 - 0.5).abs() * 2.0).reduce_partial_max()
|
||||||
|
).powi(6) * 25.0
|
||||||
|
)
|
||||||
|
).max(0.02);
|
||||||
|
score *= pos_score;
|
||||||
|
|
||||||
|
// Check if neighboring biomes are beginner friendly
|
||||||
|
let mut chunk_scores = 2.0;
|
||||||
|
for (chunk, distance) in Spiral2d::with_radius(10)
|
||||||
|
.filter_map(|rel_pos| {
|
||||||
|
let chunk_pos = civ_site.center + rel_pos * 2;
|
||||||
|
self.sim().get(chunk_pos).zip(Some(rel_pos.as_::<f32>().magnitude()))
|
||||||
|
})
|
||||||
|
{
|
||||||
|
let weight = 1.0 / (distance * std::f32::consts::TAU + 1.0);
|
||||||
|
let chunk_difficulty = 20.0 / (20.0 + chunk.get_biome().difficulty().pow(4) as f32 / 5.0);
|
||||||
|
// let chunk_difficulty = 1.0 / chunk.get_biome().difficulty() as f32;
|
||||||
|
|
||||||
|
chunk_scores *= 1.0 - weight + chunk_difficulty * weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
score *= chunk_scores;
|
||||||
|
|
||||||
(site_id.id(), score)
|
(site_id.id(), score)
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
@ -560,7 +560,25 @@ pub type ModernMap = WorldMap_0_7_0;
|
|||||||
/// TODO: Consider using some naming convention to automatically change this
|
/// TODO: Consider using some naming convention to automatically change this
|
||||||
/// with changing versions, or at least keep it in a constant somewhere that's
|
/// with changing versions, or at least keep it in a constant somewhere that's
|
||||||
/// easy to change.
|
/// easy to change.
|
||||||
pub const DEFAULT_WORLD_MAP: &str = "world.map.veloren_0_9_0_0";
|
// Generation parameters:
|
||||||
|
//
|
||||||
|
// gen_opts: (
|
||||||
|
// erosion_quality: 1.0,
|
||||||
|
// map_kind: Circle,
|
||||||
|
// scale: 2.098048498703866,
|
||||||
|
// x_lg: 10,
|
||||||
|
// y_lg: 10,
|
||||||
|
// )
|
||||||
|
// seed: 469876673
|
||||||
|
//
|
||||||
|
// The biome seed can found below
|
||||||
|
pub const DEFAULT_WORLD_MAP: &str = "world.map.veloren_0_16_0_0";
|
||||||
|
/// This is *not* the seed used to generate the default map, this seed was used
|
||||||
|
/// to generate a better set of biomes on it as the original ones were
|
||||||
|
/// unsuitable.
|
||||||
|
///
|
||||||
|
/// See DEFAULT_WORLD_MAP to get the original worldgen parameters.
|
||||||
|
pub const DEFAULT_WORLD_SEED: u32 = 1948292704;
|
||||||
|
|
||||||
impl WorldFileLegacy {
|
impl WorldFileLegacy {
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -336,7 +336,7 @@ mod tests {
|
|||||||
execute_with_tracing(Level::INFO, || {
|
execute_with_tracing(Level::INFO, || {
|
||||||
let threadpool = rayon::ThreadPoolBuilder::new().build().unwrap();
|
let threadpool = rayon::ThreadPoolBuilder::new().build().unwrap();
|
||||||
info!("init");
|
info!("init");
|
||||||
let seed = 59686;
|
let seed = sim::DEFAULT_WORLD_SEED;
|
||||||
let opts = sim::WorldOpts {
|
let opts = sim::WorldOpts {
|
||||||
seed_elements: true,
|
seed_elements: true,
|
||||||
world_file: sim::FileOpts::LoadAsset(sim::DEFAULT_WORLD_MAP.into()),
|
world_file: sim::FileOpts::LoadAsset(sim::DEFAULT_WORLD_MAP.into()),
|
||||||
@ -362,7 +362,7 @@ mod tests {
|
|||||||
execute_with_tracing(Level::INFO, || {
|
execute_with_tracing(Level::INFO, || {
|
||||||
let threadpool = rayon::ThreadPoolBuilder::new().build().unwrap();
|
let threadpool = rayon::ThreadPoolBuilder::new().build().unwrap();
|
||||||
info!("init");
|
info!("init");
|
||||||
let seed = 59686;
|
let seed = sim::DEFAULT_WORLD_SEED;
|
||||||
let opts = sim::WorldOpts {
|
let opts = sim::WorldOpts {
|
||||||
seed_elements: true,
|
seed_elements: true,
|
||||||
world_file: sim::FileOpts::LoadAsset(sim::DEFAULT_WORLD_MAP.into()),
|
world_file: sim::FileOpts::LoadAsset(sim::DEFAULT_WORLD_MAP.into()),
|
||||||
@ -502,7 +502,7 @@ mod tests {
|
|||||||
execute_with_tracing(Level::ERROR, || {
|
execute_with_tracing(Level::ERROR, || {
|
||||||
let threadpool = rayon::ThreadPoolBuilder::new().build().unwrap();
|
let threadpool = rayon::ThreadPoolBuilder::new().build().unwrap();
|
||||||
info!("init");
|
info!("init");
|
||||||
let seed = 59686;
|
let seed = sim::DEFAULT_WORLD_SEED;
|
||||||
let opts = sim::WorldOpts {
|
let opts = sim::WorldOpts {
|
||||||
seed_elements: true,
|
seed_elements: true,
|
||||||
world_file: sim::FileOpts::LoadAsset(sim::DEFAULT_WORLD_MAP.into()),
|
world_file: sim::FileOpts::LoadAsset(sim::DEFAULT_WORLD_MAP.into()),
|
||||||
|
Loading…
Reference in New Issue
Block a user