mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Turn giant trees into proper sites
This commit is contained in:
parent
b6ac4e46fb
commit
db573f6b2d
@ -9,9 +9,11 @@
|
||||
"hud.map.difficulty": "Difficulty",
|
||||
"hud.map.towns": "Towns",
|
||||
"hud.map.castles": "Castles",
|
||||
"hud.map.dungeons": "Dungeons",
|
||||
"hud.map.dungeons": "Dungeons",
|
||||
"hud.map.caves": "Caves",
|
||||
"hud.map.cave": "Cave",
|
||||
"hud.map.trees": "Trees",
|
||||
"hud.map.tree": "Tree",
|
||||
"hud.map.town": "Town",
|
||||
"hud.map.castle": "Castle",
|
||||
"hud.map.dungeon": "Dungeon",
|
||||
|
@ -138,4 +138,5 @@ pub enum SiteKind {
|
||||
Dungeon { difficulty: u32 },
|
||||
Castle,
|
||||
Cave,
|
||||
Tree,
|
||||
}
|
||||
|
@ -49,6 +49,12 @@ widget_ids! {
|
||||
show_dungeons_img,
|
||||
show_dungeons_box,
|
||||
show_dungeons_text,
|
||||
show_caves_img,
|
||||
show_caves_box,
|
||||
show_caves_text,
|
||||
show_trees_img,
|
||||
show_trees_box,
|
||||
show_trees_text,
|
||||
show_difficulty_img,
|
||||
show_difficulty_box,
|
||||
show_difficulty_text,
|
||||
@ -57,9 +63,6 @@ widget_ids! {
|
||||
drag_ico,
|
||||
zoom_txt,
|
||||
zoom_ico,
|
||||
show_caves_img,
|
||||
show_caves_box,
|
||||
show_caves_text,
|
||||
}
|
||||
}
|
||||
|
||||
@ -117,6 +120,7 @@ pub enum Event {
|
||||
ShowCastles(bool),
|
||||
ShowDungeons(bool),
|
||||
ShowCaves(bool),
|
||||
ShowTrees(bool),
|
||||
Close,
|
||||
}
|
||||
|
||||
@ -143,6 +147,7 @@ impl<'a> Widget for Map<'a> {
|
||||
let show_dungeons = self.global_state.settings.gameplay.map_show_dungeons;
|
||||
let show_castles = self.global_state.settings.gameplay.map_show_castles;
|
||||
let show_caves = self.global_state.settings.gameplay.map_show_caves;
|
||||
let show_trees = self.global_state.settings.gameplay.map_show_trees;
|
||||
let mut events = Vec::new();
|
||||
let i18n = &self.localized_strings;
|
||||
// Tooltips
|
||||
@ -471,6 +476,40 @@ impl<'a> Widget for Map<'a> {
|
||||
.graphics_for(state.ids.show_caves_box)
|
||||
.color(TEXT_COLOR)
|
||||
.set(state.ids.show_caves_text, ui);
|
||||
// Trees
|
||||
Image::new(self.imgs.mmap_site_tree)
|
||||
.down_from(state.ids.show_caves_img, 10.0)
|
||||
.w_h(20.0, 20.0)
|
||||
.set(state.ids.show_trees_img, ui);
|
||||
if Button::image(if show_trees {
|
||||
self.imgs.checkbox_checked
|
||||
} else {
|
||||
self.imgs.checkbox
|
||||
})
|
||||
.w_h(18.0, 18.0)
|
||||
.hover_image(if show_trees {
|
||||
self.imgs.checkbox_checked_mo
|
||||
} else {
|
||||
self.imgs.checkbox_mo
|
||||
})
|
||||
.press_image(if show_trees {
|
||||
self.imgs.checkbox_checked
|
||||
} else {
|
||||
self.imgs.checkbox_press
|
||||
})
|
||||
.right_from(state.ids.show_trees_img, 10.0)
|
||||
.set(state.ids.show_trees_box, ui)
|
||||
.was_clicked()
|
||||
{
|
||||
events.push(Event::ShowTrees(!show_trees));
|
||||
}
|
||||
Text::new(i18n.get("hud.map.trees"))
|
||||
.right_from(state.ids.show_trees_box, 10.0)
|
||||
.font_size(self.fonts.cyri.scale(14))
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.graphics_for(state.ids.show_trees_box)
|
||||
.color(TEXT_COLOR)
|
||||
.set(state.ids.show_trees_text, ui);
|
||||
// Map icons
|
||||
if state.ids.mmap_site_icons.len() < self.client.sites().len() {
|
||||
state.update(|state| {
|
||||
@ -512,6 +551,7 @@ impl<'a> Widget for Map<'a> {
|
||||
SiteKind::Dungeon { .. } => i18n.get("hud.map.dungeon"),
|
||||
SiteKind::Castle => i18n.get("hud.map.castle"),
|
||||
SiteKind::Cave => i18n.get("hud.map.cave"),
|
||||
SiteKind::Tree => i18n.get("hud.map.tree"),
|
||||
});
|
||||
let (difficulty, desc) = match &site.kind {
|
||||
SiteKind::Town => (0, i18n.get("hud.map.town").to_string()),
|
||||
@ -522,6 +562,7 @@ impl<'a> Widget for Map<'a> {
|
||||
),
|
||||
SiteKind::Castle => (0, i18n.get("hud.map.castle").to_string()),
|
||||
SiteKind::Cave => (0, i18n.get("hud.map.cave").to_string()),
|
||||
SiteKind::Tree => (0, i18n.get("hud.map.tree").to_string()),
|
||||
};
|
||||
let site_btn = Button::image(match &site.kind {
|
||||
SiteKind::Town => self.imgs.mmap_site_town,
|
||||
@ -648,6 +689,11 @@ impl<'a> Widget for Map<'a> {
|
||||
dif_img.set(state.ids.site_difs[i], ui)
|
||||
}
|
||||
},
|
||||
SiteKind::Tree => {
|
||||
if show_trees {
|
||||
dif_img.set(state.ids.site_difs[i], ui)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -325,6 +325,7 @@ impl<'a> Widget for MiniMap<'a> {
|
||||
_ => Color::Rgba(1.0, 1.0, 1.0, 0.0),
|
||||
},
|
||||
SiteKind::Cave => Color::Rgba(1.0, 1.0, 1.0, 0.0),
|
||||
SiteKind::Tree => Color::Rgba(1.0, 1.0, 1.0, 0.0),
|
||||
}))
|
||||
.parent(state.ids.grid)
|
||||
.set(state.ids.mmap_site_icons_bgs[i], ui);
|
||||
@ -333,6 +334,7 @@ impl<'a> Widget for MiniMap<'a> {
|
||||
SiteKind::Dungeon { .. } => self.imgs.mmap_site_dungeon,
|
||||
SiteKind::Castle => self.imgs.mmap_site_castle,
|
||||
SiteKind::Cave => self.imgs.mmap_site_cave,
|
||||
SiteKind::Tree => self.imgs.mmap_site_tree,
|
||||
_ => self.imgs.mmap_site_excl,
|
||||
})
|
||||
.middle_of(state.ids.mmap_site_icons_bgs[i])
|
||||
|
@ -362,6 +362,7 @@ pub enum Event {
|
||||
MapShowDungeons(bool),
|
||||
MapShowCastles(bool),
|
||||
MapShowCaves(bool),
|
||||
MapShowTrees(bool),
|
||||
AdjustWindowSize([u16; 2]),
|
||||
ChangeFullscreenMode(FullScreenSettings),
|
||||
ToggleParticlesEnabled(bool),
|
||||
@ -2642,6 +2643,9 @@ impl Hud {
|
||||
map::Event::ShowCaves(map_show_caves) => {
|
||||
events.push(Event::MapShowCaves(map_show_caves));
|
||||
},
|
||||
map::Event::ShowTrees(map_show_trees) => {
|
||||
events.push(Event::MapShowTrees(map_show_trees));
|
||||
},
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -1266,6 +1266,10 @@ impl PlayState for SessionState {
|
||||
global_state.settings.gameplay.map_show_caves = map_show_caves;
|
||||
global_state.settings.save_to_file_warn();
|
||||
},
|
||||
HudEvent::MapShowTrees(map_show_trees) => {
|
||||
global_state.settings.gameplay.map_show_trees = map_show_trees;
|
||||
global_state.settings.save_to_file_warn();
|
||||
},
|
||||
HudEvent::ChangeGamma(new_gamma) => {
|
||||
global_state.settings.graphics.gamma = new_gamma;
|
||||
global_state.settings.save_to_file_warn();
|
||||
|
@ -463,6 +463,7 @@ pub struct GameplaySettings {
|
||||
pub map_show_castles: bool,
|
||||
pub loading_tips: bool,
|
||||
pub map_show_caves: bool,
|
||||
pub map_show_trees: bool,
|
||||
pub minimap_show: bool,
|
||||
pub minimap_face_north: bool,
|
||||
}
|
||||
@ -502,6 +503,7 @@ impl Default for GameplaySettings {
|
||||
map_show_castles: true,
|
||||
loading_tips: true,
|
||||
map_show_caves: true,
|
||||
map_show_trees: true,
|
||||
minimap_show: true,
|
||||
minimap_face_north: false,
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ use self::{Occupation::*, Stock::*};
|
||||
use crate::{
|
||||
config::CONFIG,
|
||||
sim::WorldSim,
|
||||
site::{namegen::NameGen, Castle, Dungeon, Settlement, Site as WorldSite},
|
||||
site::{namegen::NameGen, Castle, Dungeon, Settlement, Site as WorldSite, Tree},
|
||||
site2,
|
||||
util::{attempt, seed_expan, MapVec, CARDINALS, NEIGHBORS},
|
||||
Index, Land,
|
||||
@ -106,10 +106,11 @@ impl Civs {
|
||||
|
||||
for _ in 0..initial_civ_count * 3 {
|
||||
attempt(5, || {
|
||||
let (kind, size) = match ctx.rng.gen_range(0..8) {
|
||||
0 => (SiteKind::Castle, 3),
|
||||
1 => (SiteKind::Dungeon, 0),
|
||||
_ => (SiteKind::Refactor, 5),
|
||||
let (kind, size) = match ctx.rng.gen_range(0..16) {
|
||||
0..=1 => (SiteKind::Castle, 3),
|
||||
2..=7 => (SiteKind::Refactor, 6),
|
||||
8 => (SiteKind::Tree, 4),
|
||||
_ => (SiteKind::Dungeon, 0),
|
||||
};
|
||||
let loc = find_site_loc(&mut ctx, None, size)?;
|
||||
this.establish_site(&mut ctx.reseed(), loc, |place| Site {
|
||||
@ -151,6 +152,7 @@ impl Civs {
|
||||
SiteKind::Dungeon => (8i32, 2.0),
|
||||
SiteKind::Castle => (16i32, 5.0),
|
||||
SiteKind::Refactor => (0i32, 0.0),
|
||||
SiteKind::Tree => (12i32, 8.0),
|
||||
};
|
||||
|
||||
let (raise, raise_dist): (f32, i32) = match &site.kind {
|
||||
@ -220,6 +222,9 @@ impl Civs {
|
||||
&mut rng,
|
||||
wpos,
|
||||
)),
|
||||
SiteKind::Tree => {
|
||||
WorldSite::tree(Tree::generate(wpos, &Land::from_sim(&ctx.sim), &mut rng))
|
||||
},
|
||||
});
|
||||
sim_site.site_tmp = Some(site);
|
||||
let site_ref = &index.sites[site];
|
||||
@ -899,6 +904,7 @@ pub enum SiteKind {
|
||||
Dungeon,
|
||||
Castle,
|
||||
Refactor,
|
||||
Tree,
|
||||
}
|
||||
|
||||
impl Site {
|
||||
|
@ -571,6 +571,7 @@ struct Branch {
|
||||
impl Branch {
|
||||
/// Determine whether there are either branches or leaves at the given
|
||||
/// position in the branch.
|
||||
/// (branch, leaves, stairs, forced_air)
|
||||
pub fn is_branch_or_leaves_at(
|
||||
&self,
|
||||
pos: Vec3<f32>,
|
||||
|
@ -122,6 +122,7 @@ impl World {
|
||||
},
|
||||
civ::SiteKind::Castle => world_msg::SiteKind::Castle,
|
||||
civ::SiteKind::Refactor => world_msg::SiteKind::Town,
|
||||
civ::SiteKind::Tree => world_msg::SiteKind::Tree,
|
||||
},
|
||||
wpos: site.center * TerrainChunkSize::RECT_SIZE.map(|e| e as i32),
|
||||
}
|
||||
|
@ -2109,18 +2109,20 @@ impl WorldSim {
|
||||
})
|
||||
});
|
||||
|
||||
let giant_trees = std::array::IntoIter::new(self.gen_ctx.big_structure_gen.get(wpos))
|
||||
// Don't even consider trees if we aren't close
|
||||
.filter(move |(pos, _)| pos.distance_squared(wpos) < 512i32.pow(2))
|
||||
.map(move |(pos, seed)| TreeAttr {
|
||||
pos,
|
||||
seed,
|
||||
scale: 5.0,
|
||||
forest_kind: ForestKind::Giant,
|
||||
inhabited: (seed / 13) % 2 == 0,
|
||||
});
|
||||
// // For testing
|
||||
// let giant_trees =
|
||||
// std::array::IntoIter::new(self.gen_ctx.big_structure_gen.get(wpos))
|
||||
// // Don't even consider trees if we aren't close
|
||||
// .filter(move |(pos, _)| pos.distance_squared(wpos) < 512i32.pow(2))
|
||||
// .map(move |(pos, seed)| TreeAttr {
|
||||
// pos,
|
||||
// seed,
|
||||
// scale: 5.0,
|
||||
// forest_kind: ForestKind::Giant,
|
||||
// inhabited: (seed / 13) % 2 == 0,
|
||||
// });
|
||||
|
||||
normal_trees.chain(giant_trees)
|
||||
normal_trees //.chain(giant_trees)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,11 +4,12 @@ mod dungeon;
|
||||
pub mod economy;
|
||||
pub mod namegen;
|
||||
mod settlement;
|
||||
mod tree;
|
||||
|
||||
// Reexports
|
||||
pub use self::{
|
||||
block_mask::BlockMask, castle::Castle, dungeon::Dungeon, economy::Economy,
|
||||
settlement::Settlement,
|
||||
settlement::Settlement, tree::Tree,
|
||||
};
|
||||
|
||||
use crate::{column::ColumnSample, site2, Canvas, IndexRef};
|
||||
@ -46,6 +47,7 @@ pub enum SiteKind {
|
||||
Dungeon(Dungeon),
|
||||
Castle(Castle),
|
||||
Refactor(site2::Site),
|
||||
Tree(tree::Tree),
|
||||
}
|
||||
|
||||
impl Site {
|
||||
@ -77,12 +79,20 @@ impl Site {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tree(t: tree::Tree) -> Self {
|
||||
Self {
|
||||
kind: SiteKind::Tree(t),
|
||||
economy: Economy::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn radius(&self) -> f32 {
|
||||
match &self.kind {
|
||||
SiteKind::Settlement(s) => s.radius(),
|
||||
SiteKind::Dungeon(d) => d.radius(),
|
||||
SiteKind::Castle(c) => c.radius(),
|
||||
SiteKind::Refactor(s) => s.radius(),
|
||||
SiteKind::Tree(t) => t.radius(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -92,6 +102,7 @@ impl Site {
|
||||
SiteKind::Dungeon(d) => d.get_origin(),
|
||||
SiteKind::Castle(c) => c.get_origin(),
|
||||
SiteKind::Refactor(s) => s.origin,
|
||||
SiteKind::Tree(t) => t.origin,
|
||||
}
|
||||
}
|
||||
|
||||
@ -101,6 +112,7 @@ impl Site {
|
||||
SiteKind::Dungeon(d) => d.spawn_rules(wpos),
|
||||
SiteKind::Castle(c) => c.spawn_rules(wpos),
|
||||
SiteKind::Refactor(s) => s.spawn_rules(wpos),
|
||||
SiteKind::Tree(t) => t.spawn_rules(wpos),
|
||||
}
|
||||
}
|
||||
|
||||
@ -109,7 +121,8 @@ impl Site {
|
||||
SiteKind::Settlement(s) => s.name(),
|
||||
SiteKind::Dungeon(d) => d.name(),
|
||||
SiteKind::Castle(c) => c.name(),
|
||||
SiteKind::Refactor(s) => "Experimental",
|
||||
SiteKind::Refactor(s) => "Town",
|
||||
SiteKind::Tree(t) => "Tree",
|
||||
}
|
||||
}
|
||||
|
||||
@ -120,9 +133,8 @@ impl Site {
|
||||
SiteKind::Settlement(s) => s.apply_to(canvas.index, canvas.wpos, get_col, canvas.chunk),
|
||||
SiteKind::Dungeon(d) => d.apply_to(canvas.index, canvas.wpos, get_col, canvas.chunk),
|
||||
SiteKind::Castle(c) => c.apply_to(canvas.index, canvas.wpos, get_col, canvas.chunk),
|
||||
SiteKind::Refactor(s) => {
|
||||
s.render(canvas, dynamic_rng);
|
||||
},
|
||||
SiteKind::Refactor(s) => s.render(canvas, dynamic_rng),
|
||||
SiteKind::Tree(t) => t.render(canvas, dynamic_rng),
|
||||
}
|
||||
}
|
||||
|
||||
@ -141,6 +153,7 @@ impl Site {
|
||||
SiteKind::Dungeon(d) => d.apply_supplement(dynamic_rng, wpos2d, get_column, supplement),
|
||||
SiteKind::Castle(c) => c.apply_supplement(dynamic_rng, wpos2d, get_column, supplement),
|
||||
SiteKind::Refactor(_) => {},
|
||||
SiteKind::Tree(_) => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
61
world/src/site/tree.rs
Normal file
61
world/src/site/tree.rs
Normal file
@ -0,0 +1,61 @@
|
||||
use crate::{
|
||||
layer::tree::{ProceduralTree, TreeConfig},
|
||||
site::SpawnRules,
|
||||
Canvas, Land,
|
||||
};
|
||||
use common::terrain::{Block, BlockKind};
|
||||
use rand::prelude::*;
|
||||
use vek::*;
|
||||
|
||||
// Temporary, do trees through the new site system later
|
||||
pub struct Tree {
|
||||
pub origin: Vec2<i32>,
|
||||
alt: i32,
|
||||
tree: ProceduralTree,
|
||||
}
|
||||
|
||||
impl Tree {
|
||||
pub fn generate(origin: Vec2<i32>, land: &Land, rng: &mut impl Rng) -> Self {
|
||||
Self {
|
||||
origin,
|
||||
alt: land.get_alt_approx(origin) as i32,
|
||||
tree: {
|
||||
let config = TreeConfig::giant(rng, 4.0, false);
|
||||
ProceduralTree::generate(config, rng)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn radius(&self) -> f32 { 512.0 }
|
||||
|
||||
pub fn spawn_rules(&self, wpos: Vec2<i32>) -> SpawnRules {
|
||||
let trunk_radius = 48i32;
|
||||
SpawnRules {
|
||||
trees: wpos.distance_squared(self.origin) > trunk_radius.pow(2),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render(&self, canvas: &mut Canvas, dynamic_rng: &mut impl Rng) {
|
||||
canvas.foreach_col(|canvas, wpos2d, col| {
|
||||
let rpos2d = wpos2d - self.origin;
|
||||
let bounds = self.tree.get_bounds().map(|e| e as i32);
|
||||
|
||||
if !Aabr::from(bounds).contains_point(rpos2d) {
|
||||
// Skip this column
|
||||
return;
|
||||
}
|
||||
|
||||
for z in (bounds.min.z..bounds.max.z + 1).rev() {
|
||||
let wpos = wpos2d.with_z(self.alt + z);
|
||||
let rposf = (wpos - self.origin.with_z(self.alt)).map(|e| e as f32 + 0.5);
|
||||
|
||||
let (branch, leaves, _, _) = self.tree.is_branch_or_leaves_at(rposf);
|
||||
if leaves {
|
||||
canvas.set(wpos, Block::new(BlockKind::Leaves, Rgb::new(30, 130, 40)));
|
||||
} else if branch {
|
||||
canvas.set(wpos, Block::new(BlockKind::Wood, Rgb::new(80, 32, 0)));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user