save
This commit is contained in:
parent
5cfaf975d1
commit
2fd0fb9fc3
281
assets/horse.svg
Normal file
281
assets/horse.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 468 KiB |
@ -7,14 +7,14 @@ use crate::state::State;
|
|||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Clone, Copy, Zeroable, Pod, Debug)]
|
#[derive(Clone, Copy, Zeroable, Pod, Debug)]
|
||||||
pub struct Vertex {
|
pub struct Vertex {
|
||||||
pub pos: [f32; 3],
|
pub pos: [f32; 2],
|
||||||
pub color: [f32; 4]
|
pub color: [f32; 4]
|
||||||
}
|
}
|
||||||
impl Vertex {
|
impl Vertex {
|
||||||
const DESC: VertexBufferLayout<'static> = VertexBufferLayout {
|
const DESC: VertexBufferLayout<'static> = VertexBufferLayout {
|
||||||
array_stride: std::mem::size_of::<Vertex>() as wgpu::BufferAddress,
|
array_stride: std::mem::size_of::<Vertex>() as wgpu::BufferAddress,
|
||||||
step_mode: wgpu::VertexStepMode::Vertex,
|
step_mode: wgpu::VertexStepMode::Vertex,
|
||||||
attributes: &wgpu::vertex_attr_array![0 => Float32x3, 1 => Float32x4],
|
attributes: &wgpu::vertex_attr_array![0 => Float32x2, 1 => Float32x4],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,13 +33,6 @@ impl Default for Uniforms {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Uniforms {
|
|
||||||
const DESC: VertexBufferLayout<'static> = VertexBufferLayout {
|
|
||||||
array_stride: std::mem::size_of::<Vertex>() as wgpu::BufferAddress,
|
|
||||||
step_mode: wgpu::VertexStepMode::Vertex,
|
|
||||||
attributes: &wgpu::vertex_attr_array![0 => Float32x3, 1 => Float32],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Graphics<'a> {
|
pub struct Graphics<'a> {
|
||||||
state: State,
|
state: State,
|
||||||
@ -91,13 +84,13 @@ impl<'a> Graphics<'a> {
|
|||||||
|
|
||||||
let vertex_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
let vertex_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||||
label: Some("Vertex Buffer"),
|
label: Some("Vertex Buffer"),
|
||||||
contents: &[bytemuck::cast_slice::<Vertex, _>(&state.vertices), &[0; 1024]].concat(),
|
contents: &[bytemuck::cast_slice::<Vertex, _>(&state.vertices), &[0; 100000]].concat(),
|
||||||
usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST,
|
usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST,
|
||||||
});
|
});
|
||||||
|
|
||||||
let index_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
let index_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||||
label: Some("Index Buffer"),
|
label: Some("Index Buffer"),
|
||||||
contents: &[bytemuck::cast_slice::<u32, _>(&state.indices), &[0; 1024]].concat(),
|
contents: &[bytemuck::cast_slice::<u32, _>(&state.indices), &[0; 100000]].concat(),
|
||||||
usage: wgpu::BufferUsages::INDEX | wgpu::BufferUsages::COPY_DST,
|
usage: wgpu::BufferUsages::INDEX | wgpu::BufferUsages::COPY_DST,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -11,13 +11,13 @@ struct VertexOutput {
|
|||||||
|
|
||||||
@vertex
|
@vertex
|
||||||
fn vs_main(
|
fn vs_main(
|
||||||
@location(0) pos: vec3f,
|
@location(0) pos: vec2f,
|
||||||
@location(1) color: vec4f
|
@location(1) color: vec4f
|
||||||
) -> VertexOutput {
|
) -> VertexOutput {
|
||||||
var out: VertexOutput;
|
var out: VertexOutput;
|
||||||
out.color = color;
|
out.color = color;
|
||||||
// out.color[3] -= uniforms.darkness;
|
// out.color[3] -= uniforms.darkness;
|
||||||
out.pos = vec4f(pos.xy-uniforms.camera.xy, pos.z, uniforms.camera.z);
|
out.pos = vec4f((pos.xy-uniforms.camera.xy)/uniforms.camera.z, 0, 1);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
251
src/state.rs
251
src/state.rs
@ -1,23 +1,23 @@
|
|||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
use log::info;
|
||||||
use noise::{Fbm, MultiFractal, NoiseFn, Perlin};
|
use noise::{Fbm, MultiFractal, NoiseFn, Perlin};
|
||||||
use rand::prelude::*;
|
use rand::prelude::*;
|
||||||
use voronoice::{BoundingBox, Point, Voronoi, VoronoiBuilder};
|
use voronoice::{BoundingBox, Point, Voronoi, VoronoiBuilder};
|
||||||
use winit::{event::{DeviceEvent, Event, MouseButton, MouseScrollDelta, WindowEvent}, window::Window};
|
use winit::{event::{DeviceEvent, ElementState, Event, KeyEvent, MouseButton, MouseScrollDelta, RawKeyEvent, WindowEvent}, keyboard::{KeyCode, PhysicalKey}, window::Window};
|
||||||
|
|
||||||
use crate::graphics::{Uniforms, Vertex};
|
use crate::graphics::{Uniforms, Vertex};
|
||||||
|
|
||||||
const FRAMERATE: usize = 10; // Update per second
|
const FRAMERATE: usize = 10; // Update per second
|
||||||
|
|
||||||
#[repr(u8)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
enum CellKind {
|
enum CellKind {
|
||||||
Void,
|
Void,
|
||||||
Sea,
|
Sea,
|
||||||
Plain,
|
|
||||||
Beach,
|
Beach,
|
||||||
Forest,
|
Forest,
|
||||||
Dirt,
|
Dirt,
|
||||||
Stone
|
Stone,
|
||||||
|
Grass
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CellData {
|
struct CellData {
|
||||||
@ -41,11 +41,11 @@ impl CellData {
|
|||||||
match self.kind {
|
match self.kind {
|
||||||
CellKind::Void => [0.; 4],
|
CellKind::Void => [0.; 4],
|
||||||
CellKind::Sea => [0., 0., 1., 1.],
|
CellKind::Sea => [0., 0., 1., 1.],
|
||||||
CellKind::Plain => [0., 1., 0., 1.],
|
|
||||||
CellKind::Beach => [0.82, 0.84, 0.51, 1.],
|
CellKind::Beach => [0.82, 0.84, 0.51, 1.],
|
||||||
CellKind::Forest => [0., 0.5 - (self.moisture*0.4), 0., 1.],
|
CellKind::Forest => [0., 0.5 - (self.moisture*0.4), 0., 1.],
|
||||||
CellKind::Dirt => [0.53 - (self.moisture*0.4), 0.38-(self.moisture*0.4), 0.29-(self.moisture*0.4), 1.],
|
CellKind::Dirt => [0.53 - (self.moisture*0.4), 0.38-(self.moisture*0.4), 0.29-(self.moisture*0.4), 1.],
|
||||||
CellKind::Stone => [0.5, 0.5, 0.5, 1.]
|
CellKind::Stone => [0.5, 0.5, 0.5, 1.],
|
||||||
|
CellKind::Grass => [(136./255.) - (self.moisture*0.4), (204./255.) - (self.moisture*0.4), (59./255.) - (self.moisture*0.4), 1.]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -105,11 +105,165 @@ impl Map {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
enum EntityKind {
|
||||||
|
Horse
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
enum EntityState {
|
||||||
|
Walking(Instant), // Start of walk
|
||||||
|
Resting
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Entity {
|
||||||
|
pos: [f32; 3],
|
||||||
|
kind: EntityKind,
|
||||||
|
start: Instant,
|
||||||
|
state: EntityState
|
||||||
|
}
|
||||||
|
impl Entity {
|
||||||
|
fn new(pos: [f32; 3], kind: EntityKind) -> Self {
|
||||||
|
Self {
|
||||||
|
pos,
|
||||||
|
kind,
|
||||||
|
start: Instant::now(),
|
||||||
|
state: EntityState::Resting
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn render(&self, vertices: &mut Vec<Vertex>, indices: &mut Vec<u32>) {
|
||||||
|
match self.kind {
|
||||||
|
EntityKind::Horse => {
|
||||||
|
let color = [171./255., 122./255., 50./255., 1.];
|
||||||
|
let dark = [color[0]-0.3, color[1]-0.3, color[2]-0.3, 1.];
|
||||||
|
let (vs, is) = match self.state {
|
||||||
|
EntityState::Walking(now) => {
|
||||||
|
let now = now.elapsed().as_secs_f32()*5.;
|
||||||
|
(
|
||||||
|
[
|
||||||
|
// back left leg
|
||||||
|
Vertex { pos: [-0.5, 0.3], color: dark },
|
||||||
|
Vertex { pos: [-0.4 + (now.sin()*0.1), -0.7 + (now.cos().max(-0.5)*0.1)], color: dark },
|
||||||
|
Vertex { pos: [-0.25, 0.1], color: dark },
|
||||||
|
|
||||||
|
// back right leg
|
||||||
|
Vertex { pos: [-0.5, 0.3], color },
|
||||||
|
Vertex { pos: [-0.4 + ((now + 1.).sin()*0.1), -0.7 + ((now + 1.).cos().max(-0.5)*0.1)], color },
|
||||||
|
Vertex { pos: [-0.25, 0.1], color },
|
||||||
|
|
||||||
|
// front left leg
|
||||||
|
Vertex { pos: [0.3, 0.2], color: dark },
|
||||||
|
Vertex { pos: [0.4 + ((now-1.).sin()*0.1), -0.7 + ((now-1.).cos().max(-0.5)*0.1)], color: dark },
|
||||||
|
Vertex { pos: [0.5, 0.3], color: dark },
|
||||||
|
|
||||||
|
// front right leg
|
||||||
|
Vertex { pos: [0.3, 0.2], color },
|
||||||
|
Vertex { pos: [0.4 + ((now-2.).sin()*0.1), -0.7 + ((now-2.).cos().max(-0.5)*0.1)], color },
|
||||||
|
Vertex { pos: [0.5, 0.3], color },
|
||||||
|
|
||||||
|
// body
|
||||||
|
// 3
|
||||||
|
Vertex { pos: [-0.3, 0.], color },
|
||||||
|
Vertex { pos: [0.4, -0.1], color },
|
||||||
|
// 11
|
||||||
|
Vertex { pos: [0.3, 0.4], color },
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0,1,2,
|
||||||
|
3,4,5,
|
||||||
|
6,7,8,
|
||||||
|
9,10,11,
|
||||||
|
3,12,13,
|
||||||
|
3,13,11,
|
||||||
|
3,11,14
|
||||||
|
]
|
||||||
|
)
|
||||||
|
},
|
||||||
|
EntityState::Resting => {
|
||||||
|
(
|
||||||
|
[
|
||||||
|
// back left leg
|
||||||
|
Vertex { pos: [-0.5, 0.3], color: dark },
|
||||||
|
Vertex { pos: [-0.4, -0.75], color: dark },
|
||||||
|
Vertex { pos: [-0.25, 0.1], color: dark },
|
||||||
|
|
||||||
|
// back right leg
|
||||||
|
Vertex { pos: [-0.5, 0.3], color },
|
||||||
|
Vertex { pos: [-0.4, -0.75], color },
|
||||||
|
Vertex { pos: [-0.25, 0.1], color },
|
||||||
|
|
||||||
|
// front left leg
|
||||||
|
Vertex { pos: [0.3, 0.2], color: dark },
|
||||||
|
Vertex { pos: [0.4, -0.75], color: dark },
|
||||||
|
Vertex { pos: [0.5, 0.3], color: dark },
|
||||||
|
|
||||||
|
// front right leg
|
||||||
|
Vertex { pos: [0.3, 0.2], color },
|
||||||
|
Vertex { pos: [0.4, -0.75], color },
|
||||||
|
Vertex { pos: [0.5, 0.3], color },
|
||||||
|
|
||||||
|
// body
|
||||||
|
// 3
|
||||||
|
Vertex { pos: [-0.3, 0.], color },
|
||||||
|
Vertex { pos: [0.4, -0.1], color },
|
||||||
|
// 11
|
||||||
|
Vertex { pos: [0.3, 0.4], color },
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0,1,2,
|
||||||
|
3,4,5,
|
||||||
|
6,7,8,
|
||||||
|
9,10,11,
|
||||||
|
3,12,13,
|
||||||
|
3,13,11,
|
||||||
|
3,11,14
|
||||||
|
]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
vertices.reserve(vs.len());
|
||||||
|
let base = vertices.len() as u32;
|
||||||
|
for mut v in vs {
|
||||||
|
v.pos[0] = v.pos[0]/50. + self.pos[0];
|
||||||
|
v.pos[1] = (v.pos[1] + 0.75)/50. + self.pos[1];
|
||||||
|
vertices.push(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
indices.reserve(is.len());
|
||||||
|
for i in is {
|
||||||
|
indices.push(base + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// let vs = vec![
|
||||||
|
// Vertex { pos: [-0.5, 0.3, 0.], color },
|
||||||
|
// Vertex { pos: [-0.3, 0., 0.], color },
|
||||||
|
// Vertex { pos: [0.4, -0.1, 0.], color },
|
||||||
|
// Vertex { pos: [0.5, 0.3, 0.], color },
|
||||||
|
// Vertex { pos: [0.3, 0.4, 0.], color },
|
||||||
|
// ];
|
||||||
|
// let i = self.vertices.len() as u32;
|
||||||
|
// for v in vs.iter() {
|
||||||
|
// self.vertices.push(*v);
|
||||||
|
// }
|
||||||
|
// for v in 1..(vs.len()-1) as u32 {
|
||||||
|
// self.indices.push(i);
|
||||||
|
// self.indices.push(i+v);
|
||||||
|
// self.indices.push(i+v+1);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct State {
|
pub struct State {
|
||||||
pub vertices: Vec<Vertex>,
|
pub vertices: Vec<Vertex>,
|
||||||
pub indices: Vec<u32>,
|
pub indices: Vec<u32>,
|
||||||
pub uniforms: Uniforms,
|
pub uniforms: Uniforms,
|
||||||
map: Map,
|
map: Map,
|
||||||
|
entities: Vec<Entity>,
|
||||||
start: Instant,
|
start: Instant,
|
||||||
frame: usize,
|
frame: usize,
|
||||||
selected_tile: usize,
|
selected_tile: usize,
|
||||||
@ -124,6 +278,7 @@ impl State {
|
|||||||
start: Instant::now(),
|
start: Instant::now(),
|
||||||
frame: 0,
|
frame: 0,
|
||||||
map: Map::new(0),
|
map: Map::new(0),
|
||||||
|
entities: Vec::new(),
|
||||||
selected_tile: 0,
|
selected_tile: 0,
|
||||||
mouse_pressed: false
|
mouse_pressed: false
|
||||||
};
|
};
|
||||||
@ -153,17 +308,19 @@ impl State {
|
|||||||
Event::WindowEvent { event: WindowEvent::CursorMoved { position, .. }, ..} => {
|
Event::WindowEvent { event: WindowEvent::CursorMoved { position, .. }, ..} => {
|
||||||
let w_size = window.inner_size();
|
let w_size = window.inner_size();
|
||||||
let pos = Point {
|
let pos = Point {
|
||||||
x: ((2.*position.x/(w_size.width as f64))-1.)*(self.uniforms.camera[2] as f64),
|
x: ((2.*position.x/(w_size.width as f64))-1.)*(self.uniforms.camera[2] as f64) + self.uniforms.camera[0] as f64,
|
||||||
y: (1.-(2.*position.y/(w_size.height as f64)))*(self.uniforms.camera[2] as f64)
|
y: (1.-(2.*position.y/(w_size.height as f64)))*(self.uniforms.camera[2] as f64) + self.uniforms.camera[1] as f64
|
||||||
};
|
};
|
||||||
let c = self.map.voronoi.cell(self.selected_tile);
|
let c = self.map.voronoi.cell(self.selected_tile);
|
||||||
if self.mouse_pressed {
|
if self.mouse_pressed {
|
||||||
for i in c.iter_path(pos) {
|
for i in c.iter_path(pos.clone()) {
|
||||||
self.selected_tile = i;
|
self.selected_tile = i;
|
||||||
let cd = &mut self.map.cells_data[self.selected_tile];
|
let cd = &mut self.map.cells_data[self.selected_tile];
|
||||||
if let CellKind::Dirt = cd.kind {
|
if let CellKind::Dirt = cd.kind {
|
||||||
cd.kind = CellKind::Forest;
|
cd.kind = CellKind::Forest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.entities.push(Entity::new([pos.x as f32, pos.y as f32, 0.9], EntityKind::Horse));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.selected_tile = c.iter_path(pos).last().unwrap();
|
self.selected_tile = c.iter_path(pos).last().unwrap();
|
||||||
@ -174,15 +331,36 @@ impl State {
|
|||||||
MouseScrollDelta::PixelDelta(pos) => pos.y as f32,
|
MouseScrollDelta::PixelDelta(pos) => pos.y as f32,
|
||||||
MouseScrollDelta::LineDelta(_, y) => y
|
MouseScrollDelta::LineDelta(_, y) => y
|
||||||
};
|
};
|
||||||
|
self.uniforms.camera[2] = self.uniforms.camera[2].clamp(0.1, 1.);
|
||||||
|
},
|
||||||
|
Event::WindowEvent { event: WindowEvent::KeyboardInput { event: KeyEvent { physical_key: PhysicalKey::Code(kc), state, .. }, .. }, .. } => {
|
||||||
|
if state.is_pressed() {
|
||||||
|
match kc {
|
||||||
|
KeyCode::KeyW => {
|
||||||
|
self.uniforms.camera[1] += 0.1;
|
||||||
|
},
|
||||||
|
KeyCode::KeyS => {
|
||||||
|
self.uniforms.camera[1] -= 0.1;
|
||||||
|
},
|
||||||
|
KeyCode::KeyA => {
|
||||||
|
self.uniforms.camera[0] -= 0.1;
|
||||||
|
},
|
||||||
|
KeyCode::KeyD => {
|
||||||
|
self.uniforms.camera[0] += 0.1;
|
||||||
|
},
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn render(&mut self) {
|
pub fn render(&mut self) {
|
||||||
|
info!("render");
|
||||||
self.vertices = Vec::new();
|
self.vertices = Vec::new();
|
||||||
self.indices = Vec::new();
|
self.indices = Vec::new();
|
||||||
|
|
||||||
for (c, cd) in self.map.voronoi.iter_cells().zip(self.map.cells_data.iter()) {
|
for (c, cd) in self.map.voronoi.iter_cells().zip(self.map.cells_data.iter()).filter(|(_,cd)| cd.kind != CellKind::Forest) {
|
||||||
let mut color = cd.color();
|
let mut color = cd.color();
|
||||||
if c.site() == self.selected_tile {
|
if c.site() == self.selected_tile {
|
||||||
color[0] = (color[0]+0.4).clamp(0., 1.);
|
color[0] = (color[0]+0.4).clamp(0., 1.);
|
||||||
@ -192,7 +370,30 @@ impl State {
|
|||||||
let vs = c.iter_vertices().collect::<Vec<_>>();
|
let vs = c.iter_vertices().collect::<Vec<_>>();
|
||||||
let i = self.vertices.len() as u32;
|
let i = self.vertices.len() as u32;
|
||||||
for v in vs.iter() {
|
for v in vs.iter() {
|
||||||
self.vertices.push(Vertex { pos: [v.x as f32, v.y as f32, cd.z], color });
|
self.vertices.push(Vertex { pos: [v.x as f32, v.y as f32], color });
|
||||||
|
}
|
||||||
|
for v in 1..(vs.len()-1) as u32 {
|
||||||
|
self.indices.push(i);
|
||||||
|
self.indices.push(i+v);
|
||||||
|
self.indices.push(i+v+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for e in self.entities.iter() {
|
||||||
|
e.render(&mut self.vertices, &mut self.indices);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (c, cd) in self.map.voronoi.iter_cells().zip(self.map.cells_data.iter()).filter(|(_,cd)| cd.kind == CellKind::Forest) {
|
||||||
|
let mut color = cd.color();
|
||||||
|
if c.site() == self.selected_tile {
|
||||||
|
color[0] = (color[0]+0.4).clamp(0., 1.);
|
||||||
|
color[1] = (color[1]+0.4).clamp(0., 1.);
|
||||||
|
color[2] = (color[2]+0.4).clamp(0., 1.);
|
||||||
|
}
|
||||||
|
let vs = c.iter_vertices().collect::<Vec<_>>();
|
||||||
|
let i = self.vertices.len() as u32;
|
||||||
|
for v in vs.iter() {
|
||||||
|
self.vertices.push(Vertex { pos: [v.x as f32, v.y as f32], color });
|
||||||
}
|
}
|
||||||
for v in 1..(vs.len()-1) as u32 {
|
for v in 1..(vs.len()-1) as u32 {
|
||||||
self.indices.push(i);
|
self.indices.push(i);
|
||||||
@ -207,22 +408,30 @@ impl State {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn update(&mut self) {
|
pub fn update(&mut self) {
|
||||||
|
info!("update");
|
||||||
let mut rng = thread_rng();
|
let mut rng = thread_rng();
|
||||||
let mut new_forest = Vec::new();
|
let mut new_kind = Vec::new();
|
||||||
for cd in self.map.cells_data.iter() {
|
for cd in self.map.cells_data.iter() {
|
||||||
if let CellKind::Forest = cd.kind {
|
if cd.kind == CellKind::Forest || cd.kind == CellKind::Grass {
|
||||||
if rng.gen::<f32>() < (0.03*cd.moisture) {
|
let r = rng.gen::<f32>();
|
||||||
|
if r < (0.035*cd.moisture) {
|
||||||
let c = self.map.voronoi.cell(cd.cell);
|
let c = self.map.voronoi.cell(cd.cell);
|
||||||
let n = c.iter_neighbors().choose(&mut rng).unwrap();
|
let n = c.iter_neighbors().choose(&mut rng).unwrap();
|
||||||
new_forest.push(n);
|
let k = if r < (0.005*cd.moisture) && (self.map.cells_data[n].kind == CellKind::Dirt || self.map.cells_data[n].kind == CellKind::Grass) && cd.kind == CellKind::Forest {
|
||||||
|
Some(CellKind::Forest)
|
||||||
|
} else if self.map.cells_data[n].kind == CellKind::Dirt {
|
||||||
|
Some(CellKind::Grass)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
if let Some(k) = k {
|
||||||
|
new_kind.push((n, k));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for i in new_forest {
|
for (n, k) in new_kind {
|
||||||
let cd = &mut self.map.cells_data[i];
|
self.map.cells_data[n].kind = k;
|
||||||
if let CellKind::Dirt = cd.kind {
|
|
||||||
cd.kind = CellKind::Forest;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.frame += 1;
|
self.frame += 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user