gres/src/simulation.rs

71 lines
3 KiB
Rust

use bevy::{prelude::*,math::UVec3};
use crate::{MAX_VERTICAL_FLOW,MAX_HORIZONTAL_FLOW,grid::{Grid,GridElement}};
enum GridAction{
MoveLiquid{
from: UVec3,
to: UVec3,
amount: u32,
}
}
pub fn tick(mut grid: ResMut<Grid>) {
let mut stack: Vec<GridAction> = Vec::new();
for x in 0..grid.size.x {
for y in 0..grid.size.y {
for z in 0..grid.size.z {
let vector = UVec3::new(x,y,z);
let index = grid.indexify(vector);
match grid.data[index as usize] {
GridElement::Water { amount } => {
let mut transfer_amount = amount.clone();
if let Some(gravity_vector) = vector.checked_sub(UVec3::new(0,1,0)) {
if let Some(gravity_amount) = grid.data
[grid.indexify(gravity_vector)]
.try_fill(transfer_amount.min(MAX_VERTICAL_FLOW)) {
stack.push(GridAction::MoveLiquid { from: vector, to: gravity_vector, amount: gravity_amount });
transfer_amount -= gravity_amount;
}
}
transfer_amount = transfer_amount.min(MAX_HORIZONTAL_FLOW) / 4;
if transfer_amount > 0 {
for lookup_vector in [UVec3::new(1,0,0),UVec3::new(0,0,1)] {
if let Some(toward_vector) = vector.checked_add(lookup_vector) {
if let Some(toward_amount) = grid.data
[grid.indexify(toward_vector)]
.try_fill(transfer_amount.min(MAX_VERTICAL_FLOW)) {
stack.push(GridAction::MoveLiquid { from: vector, to: toward_vector, amount: toward_amount });
}
}
if let Some(toward_vector) = vector.checked_sub(lookup_vector) {
if let Some(toward_amount) = grid.data
[grid.indexify(toward_vector)]
.try_fill(transfer_amount.min(MAX_VERTICAL_FLOW)) {
stack.push(GridAction::MoveLiquid { from: vector, to: toward_vector, amount: toward_amount });
}
}
}
}
},
_ => {},
}
}
}
}
for action in stack {
match action {
GridAction::MoveLiquid { from, to, amount } => {
let (from_index, to_index) = (grid.indexify(from), grid.indexify(to));
grid.tranfer_fluid(from_index, to_index, amount);
},
}
}
}