Basic boss spawning in dungeons, better AO

This commit is contained in:
Joshua Barretto 2020-04-16 22:01:13 +01:00
parent c4879e991d
commit fd14223c33
7 changed files with 91 additions and 10 deletions

View File

@ -30,7 +30,7 @@ void main() {
// Use an array to avoid conditional branching
vec3 f_norm = normals[(f_pos_norm >> 29) & 0x7u];
float ao = pow(f_ao, 0.5) * 0.9 + 0.1;
float ao = pow(f_ao, 0.6) * 0.9 + 0.1;
vec3 light, diffuse_light, ambient_light;
get_sun_diffuse(f_norm, time_of_day.x, light, diffuse_light, ambient_light, 1.0);

View File

@ -17,8 +17,7 @@ pub struct ChunkSupplement {
}
impl ChunkSupplement {
pub fn with_entity(mut self, entity: EntityInfo) -> Self {
pub fn add_entity(&mut self, entity: EntityInfo) {
self.entities.push(entity);
self
}
}

View File

@ -31,11 +31,10 @@ impl Meshable<FigurePipeline, FigurePipeline> for Segment {
offs + pos.map(|e| e as f32),
&[[[Rgba::from_opaque(col); 3]; 3]; 3],
|origin, norm, col, ao, light| {
let ao = ao * 0.95 + 0.05;
FigureVertex::new(
origin,
norm,
linear_to_srgb(srgb_to_linear(col) * light.min(ao)),
linear_to_srgb(srgb_to_linear(col) * light.min(ao.powf(0.5) * 0.75 + 0.25)),
0,
)
},
@ -85,11 +84,10 @@ impl Meshable<SpritePipeline, SpritePipeline> for Segment {
offs + pos.map(|e| e as f32),
&[[[Rgba::from_opaque(col); 3]; 3]; 3],
|origin, norm, col, ao, light| {
let ao = ao * 0.95 + 0.05;
SpriteVertex::new(
origin,
norm,
linear_to_srgb(srgb_to_linear(col) * light.min(ao)),
linear_to_srgb(srgb_to_linear(col) * light.min(ao.powf(0.5) * 0.75 + 0.25)),
)
},
&{

View File

@ -194,12 +194,27 @@ impl World {
};
if sim_chunk.contains_waypoint {
supplement = supplement.with_entity(EntityInfo {
supplement.add_entity(EntityInfo {
pos: gen_entity_pos(),
kind: EntityKind::Waypoint,
});
}
// Apply site supplementary information
sim_chunk.sites.iter().for_each(|site| {
site.apply_supplement(
chunk_wpos2d,
|offs| {
zcache_grid
.get(grid_border + offs)
.map(Option::as_ref)
.flatten()
.map(|zc| &zc.sample)
},
&mut supplement,
)
});
Ok((chunk, supplement))
}
}

View File

@ -12,6 +12,7 @@ use common::{
terrain::{Block, BlockKind, TerrainChunkSize},
vol::{BaseVol, RectSizedVol, RectVolSize, ReadVol, WriteVol, Vox},
store::{Id, Store},
generation::{ChunkSupplement, EntityInfo, EntityKind},
};
use hashbrown::{HashMap, HashSet};
use rand::prelude::*;
@ -50,7 +51,7 @@ impl Dungeon {
let mut ctx = GenCtx { sim, rng };
let mut this = Self {
origin: wpos,
alt: ctx.sim.and_then(|sim| sim.get_alt_approx(wpos)).unwrap_or(0.0) as i32,
alt: ctx.sim.and_then(|sim| sim.get_alt_approx(wpos)).unwrap_or(0.0) as i32 + 6,
noise: RandomField::new(ctx.rng.gen()),
floors: (0..6)
.scan(Vec2::zero(), |stair_tile, level| {
@ -98,7 +99,7 @@ impl Dungeon {
let tile_pos = rpos.map(|e| e.div_euclid(TILE_SIZE));
let tile_center = tile_pos * TILE_SIZE + TILE_SIZE / 2;
let mut z = self.alt + 6;
let mut z = self.alt;
for floor in &self.floors {
let mut sampler = floor.col_sampler(rpos);
@ -112,6 +113,26 @@ impl Dungeon {
}
}
}
pub fn apply_supplement<'a>(
&'a self,
wpos2d: Vec2<i32>,
mut get_column: impl FnMut(Vec2<i32>) -> Option<&'a ColumnSample<'a>>,
supplement: &mut ChunkSupplement,
) {
let rpos = wpos2d - self.origin;
let area = Aabr {
min: rpos,
max: rpos + TerrainChunkSize::RECT_SIZE.map(|e| e as i32),
};
let mut z = self.alt;
for floor in &self.floors {
z -= floor.total_depth();
let origin = Vec3::new(self.origin.x, self.origin.y, z);
floor.apply_supplement(area, origin, supplement);
}
}
}
const CARDINALS: [Vec2<i32>; 4] = [
@ -271,6 +292,31 @@ impl Floor {
}
}
pub fn apply_supplement(&self, area: Aabr<i32>, origin: Vec3<i32>, supplement: &mut ChunkSupplement) {
let align = |e: i32| e.div_euclid(TILE_SIZE) + if e.rem_euclid(TILE_SIZE) > TILE_SIZE / 2 {
1
} else {
0
};
let aligned_area = Aabr {
min: area.min.map(align) + self.tile_offset,
max: area.max.map(align) + self.tile_offset,
};
for x in aligned_area.min.x..aligned_area.max.x {
for y in aligned_area.min.y..aligned_area.max.y {
let tile_pos = Vec2::new(x, y);
if let Some(Tile::Room) = self.tiles.get(tile_pos) {
if tile_pos.x % 4 != 0 || tile_pos.y % 4 != 0 { continue; } // This is so bad
supplement.add_entity(EntityInfo {
pos: (origin + Vec3::from(self.tile_offset + tile_pos) * TILE_SIZE).map(|e| e as f32),
kind: EntityKind::Boss,
});
}
}
}
}
pub fn total_depth(&self) -> i32 {
self.solid_depth + self.hollow_depth
}

View File

@ -12,6 +12,7 @@ use crate::{
use common::{
terrain::Block,
vol::{Vox, BaseVol, RectSizedVol, ReadVol, WriteVol},
generation::ChunkSupplement,
};
use std::{fmt, sync::Arc};
use vek::*;
@ -100,6 +101,18 @@ impl Site {
Site::Dungeon(dungeon) => dungeon.apply_to(wpos2d, get_column, vol),
}
}
pub fn apply_supplement<'a>(
&'a self,
wpos2d: Vec2<i32>,
get_column: impl FnMut(Vec2<i32>) -> Option<&'a ColumnSample<'a>>,
supplement: &mut ChunkSupplement,
) {
match self {
Site::Settlement(settlement) => settlement.apply_supplement(wpos2d, get_column, supplement),
Site::Dungeon(dungeon) => dungeon.apply_supplement(wpos2d, get_column, supplement),
}
}
}
impl From<Settlement> for Site {

View File

@ -14,6 +14,7 @@ use common::{
terrain::{Block, BlockKind, TerrainChunkSize},
vol::{BaseVol, RectSizedVol, RectVolSize, ReadVol, WriteVol, Vox},
store::{Id, Store},
generation::ChunkSupplement,
};
use hashbrown::{HashMap, HashSet};
use rand::prelude::*;
@ -676,6 +677,15 @@ impl Settlement {
}
}
pub fn apply_supplement<'a>(
&'a self,
wpos2d: Vec2<i32>,
mut get_column: impl FnMut(Vec2<i32>) -> Option<&'a ColumnSample<'a>>,
supplement: &mut ChunkSupplement,
) {
// TODO
}
pub fn get_color(&self, pos: Vec2<i32>) -> Option<Rgb<u8>> {
let sample = self.land.get_at_block(pos);