noita_entangled_worlds/blob_guy/src/blob_guy.rs

92 lines
2.8 KiB
Rust
Raw Normal View History

2025-06-27 23:23:49 -04:00
use crate::chunk::{CellType, Chunk, ChunkPos};
2025-06-29 19:46:10 -04:00
use crate::{CHUNK_AMOUNT, CHUNK_SIZE, State};
2025-06-29 18:31:49 -04:00
#[derive(Default, Debug, Clone, Copy)]
2025-06-27 10:26:09 -04:00
pub struct Pos {
x: f64,
y: f64,
}
impl Pos {
pub fn new(x: f64, y: f64) -> Self {
Self { x, y }
}
2025-06-29 18:31:49 -04:00
pub fn to_chunk(self) -> ChunkPos {
2025-06-27 14:11:41 -04:00
ChunkPos::new(self.x as i32, self.y as i32)
}
2025-06-29 18:31:49 -04:00
pub fn to_chunk_inner(self) -> usize {
2025-06-28 15:20:06 -04:00
self.x.rem_euclid(CHUNK_SIZE as f64) as usize * CHUNK_SIZE
+ self.y.rem_euclid(CHUNK_SIZE as f64) as usize
2025-06-27 14:11:41 -04:00
}
}
2025-06-29 19:46:10 -04:00
const OFFSET: i32 = CHUNK_AMOUNT as i32 / 2;
2025-06-27 14:11:41 -04:00
impl State {
2025-06-27 23:23:49 -04:00
pub fn update(&mut self) -> eyre::Result<()> {
if self.blobs.is_empty() {
2025-06-29 19:46:10 -04:00
self.blobs.push(Blob::new(128.0 + 16.0, -128.0 - 16.0));
2025-06-27 23:23:49 -04:00
}
2025-06-29 18:31:49 -04:00
'upper: for blob in self.blobs.iter_mut() {
let c = blob.pos.to_chunk();
2025-06-29 19:46:10 -04:00
for (k, (x, y)) in (-OFFSET..=OFFSET)
.flat_map(|i| (-OFFSET..=OFFSET).map(move |j| (i, j)))
2025-06-29 18:31:49 -04:00
.enumerate()
{
if unsafe {
!self
.particle_world_state
.encode_area(c.x + x, c.y + y, &mut self.world[k])
} {
continue 'upper;
2025-06-27 23:23:49 -04:00
}
2025-06-29 18:31:49 -04:00
}
blob.update(&mut self.world);
2025-06-29 19:46:10 -04:00
for (k, (x, y)) in (-OFFSET..=OFFSET)
.flat_map(|i| (-OFFSET..=OFFSET).map(move |j| (i, j)))
2025-06-29 18:31:49 -04:00
.enumerate()
{
unsafe {
self.particle_world_state
.decode_area(c.x + x, c.y + y, &self.world[k]);
2025-06-27 14:11:41 -04:00
}
}
}
2025-06-27 23:23:49 -04:00
Ok(())
2025-06-27 14:11:41 -04:00
}
2025-06-27 10:26:09 -04:00
}
2025-06-29 19:46:10 -04:00
const SIZE: usize = 8;
2025-06-27 10:26:09 -04:00
pub struct Blob {
pub pos: Pos,
2025-06-27 14:11:41 -04:00
pixels: [Pos; SIZE * SIZE],
2025-06-27 10:26:09 -04:00
}
impl Blob {
2025-06-27 23:23:49 -04:00
pub fn update(&mut self, map: &mut [Chunk; 9]) {
2025-06-27 14:11:41 -04:00
let mut last = ChunkPos::new(i32::MAX, i32::MAX);
2025-06-27 23:23:49 -04:00
let mut k = 0;
let start = self.pos.to_chunk();
2025-06-29 19:46:10 -04:00
for p in self.pixels.iter_mut() {
//p.y += 1.0;
2025-06-27 14:11:41 -04:00
let c = p.to_chunk();
if c != last {
2025-06-29 19:46:10 -04:00
k = ((c.x - start.x + OFFSET) * CHUNK_AMOUNT as i32 + c.y - start.y + OFFSET)
as usize;
2025-06-27 14:11:41 -04:00
last = c;
}
2025-06-27 23:23:49 -04:00
let n = p.to_chunk_inner();
2025-06-28 15:20:06 -04:00
map[k][n] = if matches!(map[k][n], CellType::Remove) {
CellType::Ignore
} else {
CellType::Blob
}
2025-06-27 14:11:41 -04:00
}
}
pub fn new(x: f64, y: f64) -> Self {
Blob {
pos: Pos::new(x, y),
pixels: std::array::from_fn(|i| {
2025-06-28 15:20:06 -04:00
let a = (i / SIZE) as f64 - SIZE as f64 / 2.0 + 0.5;
let b = (i % SIZE) as f64 - SIZE as f64 / 2.0 + 0.5;
2025-06-27 14:11:41 -04:00
Pos::new(x + a, y + b)
}),
}
2025-06-27 10:26:09 -04:00
}
}