mirror of
https://github.com/IntQuant/noita_entangled_worlds.git
synced 2025-10-19 15:13:16 +00:00
make types a bit nicer
This commit is contained in:
parent
6b15e58202
commit
3fdd72c363
6 changed files with 123 additions and 138 deletions
|
@ -1,5 +1,4 @@
|
|||
use crate::chunk::Chunks;
|
||||
use crate::chunk::SCALE;
|
||||
use crate::chunk::{CellType, ChunkPos, Pos};
|
||||
use crate::{CHUNK_AMOUNT, State};
|
||||
#[cfg(target_arch = "x86")]
|
||||
|
@ -24,16 +23,14 @@ impl State {
|
|||
let mean = blob.mean();
|
||||
blob.update_pos()?;
|
||||
let start = Pos::new(mean.0, mean.1).to_chunk();
|
||||
if !unsafe { self.particle_world_state.assume_init_ref() }
|
||||
.exists::<SCALE>(start.x, start.y)
|
||||
|| self
|
||||
.world
|
||||
.read(
|
||||
unsafe { self.particle_world_state.assume_init_ref() },
|
||||
self.blob_guy,
|
||||
start,
|
||||
)
|
||||
.is_err()
|
||||
if self
|
||||
.world
|
||||
.read(
|
||||
unsafe { self.particle_world_state.assume_init_ref() },
|
||||
self.blob_guy,
|
||||
start,
|
||||
)
|
||||
.is_err()
|
||||
{
|
||||
blob.update(start, &mut self.world, mean, false)?;
|
||||
continue 'upper;
|
||||
|
|
|
@ -154,7 +154,6 @@ impl ChunkOps for ParticleWorldState {
|
|||
let Some(pixel_array) = unsafe { self.world_ptr.as_mut() }
|
||||
.wrap_err("no world")?
|
||||
.chunk_map
|
||||
.chunk_array
|
||||
.get(x >> SCALE, y >> SCALE)
|
||||
else {
|
||||
return Err(eyre!("chunk not loaded"));
|
||||
|
@ -164,7 +163,7 @@ impl ChunkOps for ParticleWorldState {
|
|||
.flat_map(|i| (0..CHUNK_SIZE as isize).map(move |j| (i, j)))
|
||||
.zip(chunk.iter_mut())
|
||||
{
|
||||
*pixel = if let Some(cell) = pixel_array.data.get(shift_x + i, shift_y + j) {
|
||||
*pixel = if let Some(cell) = pixel_array.get(shift_x + i, shift_y + j) {
|
||||
match cell.material.cell_type {
|
||||
types::CellType::Liquid => {
|
||||
if cell.material.material_type as u16 == blob {
|
||||
|
@ -206,7 +205,6 @@ impl ChunkOps for ParticleWorldState {
|
|||
let Some(pixel_array) = unsafe { self.world_ptr.as_mut() }
|
||||
.wrap_err("no world")?
|
||||
.chunk_map
|
||||
.chunk_array
|
||||
.get_mut(cx >> SCALE, cy >> SCALE)
|
||||
else {
|
||||
return Err(eyre!("chunk not loaded"));
|
||||
|
@ -229,17 +227,15 @@ impl ChunkOps for ParticleWorldState {
|
|||
CellType::Blob => {
|
||||
let world_x = x + i;
|
||||
let world_y = y + j;
|
||||
if let Some(cell) = pixel_array.data.get_mut(shift_x + i, shift_y + j) {
|
||||
let new = Box::leak(blob_cell.clone());
|
||||
new.x = world_x;
|
||||
new.y = world_y;
|
||||
cell.0 = (new as *mut types::LiquidCell).cast();
|
||||
}
|
||||
let cell = pixel_array.get_mut_raw(shift_x + i, shift_y + j);
|
||||
let new = Box::leak(blob_cell.clone());
|
||||
new.x = world_x;
|
||||
new.y = world_y;
|
||||
*cell = (new as *mut types::LiquidCell).cast();
|
||||
}
|
||||
CellType::Remove => {
|
||||
if let Some(cell) = pixel_array.data.get_mut(shift_x + i, shift_y + j) {
|
||||
cell.0 = std::ptr::null_mut()
|
||||
}
|
||||
let cell = pixel_array.get_mut_raw(shift_x + i, shift_y + j);
|
||||
*cell = std::ptr::null_mut();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ use noita_api::add_lua_fn;
|
|||
use noita_api::addr_grabber::Globals;
|
||||
use noita_api::noita::world::ParticleWorldState;
|
||||
use noita_api::{
|
||||
DamageModelComponent, EntityID, VariableStorageComponent,
|
||||
EntityID, VariableStorageComponent,
|
||||
lua::{
|
||||
LUA, LuaGetValue, LuaState, RawString,
|
||||
lua_bindings::{LUA_REGISTRYINDEX, lua_State},
|
||||
|
@ -27,7 +27,6 @@ use std::{
|
|||
cell::RefCell,
|
||||
ffi::c_int,
|
||||
sync::{LazyLock, Mutex, OnceLock, TryLockError},
|
||||
time::Instant,
|
||||
};
|
||||
use std::{num::NonZero, sync::MutexGuard};
|
||||
mod modules;
|
||||
|
@ -281,7 +280,7 @@ fn module_on_projectile_fired(lua: LuaState) -> eyre::Result<()> {
|
|||
})
|
||||
}
|
||||
|
||||
fn bench_fn(_lua: LuaState) -> eyre::Result<()> {
|
||||
/*fn bench_fn(_lua: LuaState) -> eyre::Result<()> {
|
||||
let start = Instant::now();
|
||||
let iters = 10000;
|
||||
for _ in 0..iters {
|
||||
|
@ -297,9 +296,9 @@ fn bench_fn(_lua: LuaState) -> eyre::Result<()> {
|
|||
));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}*/
|
||||
|
||||
fn test_fn(_lua: LuaState) -> eyre::Result<()> {
|
||||
/*fn test_fn(_lua: LuaState) -> eyre::Result<()> {
|
||||
let player = EntityID::get_closest_with_tag(0.0, 0.0, "player_unit")?;
|
||||
let damage_model: DamageModelComponent = player.get_first_component(None)?;
|
||||
let hp = damage_model.hp()?;
|
||||
|
@ -319,16 +318,16 @@ fn test_fn(_lua: LuaState) -> eyre::Result<()> {
|
|||
// noita::api::raw::entity_set_transform(player, 0.0, 0.0, 0.0, 1.0, 1.0)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}*/
|
||||
|
||||
fn probe(_lua: LuaState) {
|
||||
/*fn probe(_lua: LuaState) {
|
||||
backtrace::trace(|frame| {
|
||||
let _ip = frame.ip() as usize;
|
||||
#[cfg(debug_assertions)]
|
||||
println!("Probe: 0x{_ip:x}");
|
||||
false
|
||||
});
|
||||
}
|
||||
}*/
|
||||
|
||||
pub(crate) fn print_error(error: eyre::Report) -> eyre::Result<()> {
|
||||
let lua = LuaState::current()?;
|
||||
|
@ -376,9 +375,9 @@ pub unsafe extern "C" fn luaopen_ewext(lua: *mut lua_State) -> c_int {
|
|||
|
||||
add_lua_fn!(make_ephemerial);
|
||||
add_lua_fn!(set_world_num);
|
||||
add_lua_fn!(test_fn);
|
||||
add_lua_fn!(bench_fn);
|
||||
add_lua_fn!(probe);
|
||||
//add_lua_fn!(test_fn);
|
||||
//add_lua_fn!(bench_fn);
|
||||
//add_lua_fn!(probe);
|
||||
|
||||
add_lua_fn!(netmanager_connect);
|
||||
add_lua_fn!(netmanager_recv);
|
||||
|
|
|
@ -68,7 +68,6 @@ impl WorldData for ParticleWorldState {
|
|||
let Some(pixel_array) = unsafe { self.world_ptr.as_mut() }
|
||||
.wrap_err("no world")?
|
||||
.chunk_map
|
||||
.chunk_array
|
||||
.get(cx >> SCALE, cy >> SCALE)
|
||||
else {
|
||||
return Err(eyre!("chunk not loaded"));
|
||||
|
@ -78,7 +77,7 @@ impl WorldData for ParticleWorldState {
|
|||
.flat_map(|i| (shift_y..shift_y + CHUNK_SIZE as isize).map(move |j| (i, j)))
|
||||
.zip(chunk.iter_mut())
|
||||
{
|
||||
*p = pixel_array.data.get_compact_pixel(i, j);
|
||||
*p = pixel_array.get_compact_pixel(i, j);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -88,7 +87,6 @@ impl WorldData for ParticleWorldState {
|
|||
let Some(pixel_array) = unsafe { self.world_ptr.as_mut() }
|
||||
.wrap_err("no world")?
|
||||
.chunk_map
|
||||
.chunk_array
|
||||
.get_mut(cx >> SCALE, cy >> SCALE)
|
||||
else {
|
||||
return Err(eyre!("chunk not loaded"));
|
||||
|
@ -100,50 +98,49 @@ impl WorldData for ParticleWorldState {
|
|||
let mut y = 0;
|
||||
for run in chunk.runs {
|
||||
for _ in 0..run.length {
|
||||
if let Some(cell) = pixel_array.data.get_mut(shift_x + x, shift_y + y) {
|
||||
let xs = start_x + x;
|
||||
let ys = start_y + y;
|
||||
let mat = &self
|
||||
.material_list
|
||||
.get_static(run.data.material as usize)
|
||||
.unwrap();
|
||||
match mat.cell_type {
|
||||
CellType::None => {
|
||||
cell.0 = ptr::null_mut();
|
||||
}
|
||||
CellType::Liquid => {
|
||||
let liquid = Box::leak(Box::new(unsafe {
|
||||
LiquidCell::create(mat, self.cell_vtables.liquid(), self.world_ptr)
|
||||
}));
|
||||
liquid.x = xs;
|
||||
liquid.y = ys;
|
||||
cell.0 = (liquid as *mut LiquidCell).cast();
|
||||
}
|
||||
CellType::Gas => {
|
||||
let gas = Box::leak(Box::new(unsafe {
|
||||
GasCell::create(mat, self.cell_vtables.gas(), self.world_ptr)
|
||||
}));
|
||||
gas.x = xs;
|
||||
gas.y = ys;
|
||||
cell.0 = (gas as *mut GasCell).cast();
|
||||
}
|
||||
CellType::Solid => {}
|
||||
CellType::Fire => {
|
||||
let fire = Box::leak(Box::new(unsafe {
|
||||
FireCell::create(mat, self.cell_vtables.fire(), self.world_ptr)
|
||||
}));
|
||||
fire.x = xs;
|
||||
fire.y = ys;
|
||||
cell.0 = (fire as *mut FireCell).cast();
|
||||
}
|
||||
let cell = pixel_array.get_mut_raw(shift_x + x, shift_y + y);
|
||||
let xs = start_x + x;
|
||||
let ys = start_y + y;
|
||||
let mat = &self
|
||||
.material_list
|
||||
.get_static(run.data.material as usize)
|
||||
.unwrap();
|
||||
match mat.cell_type {
|
||||
CellType::None => {
|
||||
*cell = ptr::null_mut();
|
||||
}
|
||||
CellType::Liquid => {
|
||||
let liquid = Box::leak(Box::new(unsafe {
|
||||
LiquidCell::create(mat, self.cell_vtables.liquid(), self.world_ptr)
|
||||
}));
|
||||
liquid.x = xs;
|
||||
liquid.y = ys;
|
||||
*cell = (liquid as *mut LiquidCell).cast();
|
||||
}
|
||||
CellType::Gas => {
|
||||
let gas = Box::leak(Box::new(unsafe {
|
||||
GasCell::create(mat, self.cell_vtables.gas(), self.world_ptr)
|
||||
}));
|
||||
gas.x = xs;
|
||||
gas.y = ys;
|
||||
*cell = (gas as *mut GasCell).cast();
|
||||
}
|
||||
CellType::Solid => {}
|
||||
CellType::Fire => {
|
||||
let fire = Box::leak(Box::new(unsafe {
|
||||
FireCell::create(mat, self.cell_vtables.fire(), self.world_ptr)
|
||||
}));
|
||||
fire.x = xs;
|
||||
fire.y = ys;
|
||||
*cell = (fire as *mut FireCell).cast();
|
||||
}
|
||||
}
|
||||
if x == CHUNK_SIZE as isize {
|
||||
x = 0;
|
||||
y += 1;
|
||||
} else {
|
||||
x += 1;
|
||||
}
|
||||
}
|
||||
if x == CHUNK_SIZE as isize {
|
||||
x = 0;
|
||||
y += 1;
|
||||
} else {
|
||||
x += 1;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
|
|
@ -318,12 +318,6 @@ impl Cell {
|
|||
}
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
#[derive(Debug)]
|
||||
pub struct CellPtr(pub *mut Cell);
|
||||
unsafe impl Sync for CellPtr {}
|
||||
unsafe impl Send for CellPtr {}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct FireCell {
|
||||
|
@ -641,30 +635,20 @@ pub struct Color {
|
|||
pub a: u8,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[repr(transparent)]
|
||||
pub struct CellArray(pub *mut CellPtr);
|
||||
unsafe impl Sync for CellArray {}
|
||||
unsafe impl Send for CellArray {}
|
||||
|
||||
impl CellArray {
|
||||
#[inline]
|
||||
pub fn iter(&self) -> impl Iterator<Item = &CellPtr> {
|
||||
unsafe { slice::from_raw_parts(self.0, 512 * 512) }.iter()
|
||||
}
|
||||
impl Chunk {
|
||||
#[inline]
|
||||
pub fn get(&self, x: isize, y: isize) -> Option<&Cell> {
|
||||
let index = (y << 9) | x;
|
||||
unsafe { self.0.offset(index).as_ref()?.0.as_ref() }
|
||||
unsafe { self.data[index.cast_unsigned()].as_ref() }
|
||||
}
|
||||
#[inline]
|
||||
pub fn get_mut(&mut self, x: isize, y: isize) -> Option<&mut CellPtr> {
|
||||
pub fn get_mut(&mut self, x: isize, y: isize) -> Option<&mut Cell> {
|
||||
unsafe { self.get_mut_raw(x, y).as_mut() }
|
||||
}
|
||||
#[inline]
|
||||
pub fn get_mut_raw(&mut self, x: isize, y: isize) -> *mut CellPtr {
|
||||
pub fn get_mut_raw(&mut self, x: isize, y: isize) -> &mut *mut Cell {
|
||||
let index = (y << 9) | x;
|
||||
unsafe { self.0.offset(index) }
|
||||
&mut self.data[index.cast_unsigned()]
|
||||
}
|
||||
#[inline]
|
||||
pub fn get_raw_pixel(&self, x: isize, y: isize) -> RawPixel {
|
||||
|
@ -713,53 +697,72 @@ impl CellArray {
|
|||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct ChunkMap {
|
||||
pub len: usize,
|
||||
unknown: isize,
|
||||
pub chunk_array: ChunkArrayPtr,
|
||||
pub chunk_array: &'static mut [*mut Chunk; 512 * 512],
|
||||
pub chunk_count: usize,
|
||||
pub min_chunk: Vec2i,
|
||||
pub max_chunk: Vec2i,
|
||||
pub min_pixel: Vec2i,
|
||||
pub max_pixel: Vec2i,
|
||||
}
|
||||
impl Debug for ChunkMap {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("ChunkMap")
|
||||
.field("len", &self.len)
|
||||
.field("unknown", &self.unknown)
|
||||
.field(
|
||||
"chunk_array",
|
||||
&self
|
||||
.chunk_array
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter_map(|(i, a)| unsafe {
|
||||
a.as_ref().map(|a| (i % 512 - 256, i / 512 - 256, a))
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
.field("chunk_count", &self.chunk_count)
|
||||
.field("min_chunk", &self.min_chunk)
|
||||
.field("max_chunk", &self.max_chunk)
|
||||
.field("min_pixel", &self.min_pixel)
|
||||
.field("max_pixel", &self.max_pixel)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct Chunk {
|
||||
pub data: CellArray,
|
||||
//thought it might make sense if more data but seems like garbage
|
||||
pub data: &'static mut [*mut Cell; 512 * 512],
|
||||
}
|
||||
impl Debug for Chunk {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_tuple("Chunk")
|
||||
.field(
|
||||
&self
|
||||
.data
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter_map(|(i, a)| {
|
||||
unsafe { a.as_ref() }.map(|a| (i % 512, i / 512, a.material.material_type))
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
unsafe impl Sync for Chunk {}
|
||||
unsafe impl Send for Chunk {}
|
||||
#[repr(transparent)]
|
||||
#[derive(Debug)]
|
||||
pub struct ChunkPtr(pub *mut Chunk);
|
||||
unsafe impl Sync for ChunkPtr {}
|
||||
unsafe impl Send for ChunkPtr {}
|
||||
#[repr(transparent)]
|
||||
#[derive(Debug)]
|
||||
pub struct ChunkArrayPtr(pub *mut ChunkPtr);
|
||||
unsafe impl Sync for ChunkArrayPtr {}
|
||||
unsafe impl Send for ChunkArrayPtr {}
|
||||
impl ChunkArrayPtr {
|
||||
#[inline]
|
||||
pub fn iter(&self) -> impl Iterator<Item = &ChunkPtr> {
|
||||
self.slice().iter()
|
||||
}
|
||||
#[inline]
|
||||
pub fn slice(&self) -> &'static [ChunkPtr] {
|
||||
unsafe { slice::from_raw_parts(self.0, 512 * 512) }
|
||||
}
|
||||
impl ChunkMap {
|
||||
#[inline]
|
||||
pub fn get(&self, x: isize, y: isize) -> Option<&Chunk> {
|
||||
let index = (((y - 256) & 511) << 9) | ((x - 256) & 511);
|
||||
unsafe { self.0.offset(index).as_ref()?.0.as_ref() }
|
||||
unsafe { self.chunk_array[index.cast_unsigned()].as_ref() }
|
||||
}
|
||||
#[inline]
|
||||
pub fn get_mut(&mut self, x: isize, y: isize) -> Option<&mut Chunk> {
|
||||
let index = (((y - 256) & 511) << 9) | ((x - 256) & 511);
|
||||
unsafe { self.0.offset(index).as_mut()?.0.as_mut() }
|
||||
unsafe { self.chunk_array[index.cast_unsigned()].as_mut() }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use crate::noita::types;
|
||||
use crate::noita::types::StdVec;
|
||||
use eyre::ContextCompat;
|
||||
use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator};
|
||||
#[derive(Debug)]
|
||||
pub struct ParticleWorldState {
|
||||
pub world_ptr: *mut types::GridWorld,
|
||||
|
@ -20,11 +19,7 @@ impl ParticleWorldState {
|
|||
let Some(world) = (unsafe { self.world_ptr.as_mut() }) else {
|
||||
return false;
|
||||
};
|
||||
world
|
||||
.chunk_map
|
||||
.chunk_array
|
||||
.get(cx >> SCALE, cy >> SCALE)
|
||||
.is_some()
|
||||
world.chunk_map.get(cx >> SCALE, cy >> SCALE).is_some()
|
||||
}
|
||||
///# Safety
|
||||
#[allow(clippy::type_complexity)]
|
||||
|
@ -35,11 +30,10 @@ impl ParticleWorldState {
|
|||
world
|
||||
.chunk_map
|
||||
.chunk_array
|
||||
.slice()
|
||||
.par_iter()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter_map(|(i, c)| {
|
||||
unsafe { c.0.as_ref() }.map(|c| {
|
||||
unsafe { c.as_ref() }.map(|c| {
|
||||
let x = i as isize % 512 - 256;
|
||||
let y = i as isize / 512 - 256;
|
||||
(
|
||||
|
@ -47,7 +41,7 @@ impl ParticleWorldState {
|
|||
c.data
|
||||
.iter()
|
||||
.map(|p| {
|
||||
unsafe { p.0.as_ref() }
|
||||
unsafe { p.as_ref() }
|
||||
.map(types::FullCell::from)
|
||||
.unwrap_or_default()
|
||||
})
|
||||
|
@ -65,10 +59,9 @@ impl ParticleWorldState {
|
|||
if let Some(pixel_array) = unsafe { self.world_ptr.as_mut() }
|
||||
.wrap_err("no world")?
|
||||
.chunk_map
|
||||
.chunk_array
|
||||
.get_mut(x.div_euclid(512), y.div_euclid(512))
|
||||
{
|
||||
if let Some(cell) = pixel_array.data.get(x.rem_euclid(512), y.rem_euclid(512)) {
|
||||
if let Some(cell) = pixel_array.get(x.rem_euclid(512), y.rem_euclid(512)) {
|
||||
let full = types::FullCell::from(cell);
|
||||
crate::print!("{full:?}");
|
||||
} else {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue