take pos data from lua to make code less stupid, and probably fix some ping issues

This commit is contained in:
bgkillas 2024-08-30 20:33:57 -04:00
parent 93afc1c014
commit d329c318c0
4 changed files with 32 additions and 60 deletions

View file

@ -553,7 +553,12 @@ impl NetManager {
}
// world end
1 => {
state.world.add_end(data[0]);
let pos = if data.len() > 1 {
Some(data[1..].split(|b| *b == b':').map(|s| String::from_utf8_lossy(s).parse::<i32>().unwrap_or(0)).collect::<Vec<i32>>())
} else {
None
};
state.world.add_end(data[0], pos.as_deref());
}
key => {
error!("Unknown bin msg from mod: {:?}", key)

View file

@ -121,6 +121,8 @@ impl ChunkState {
// TODO handle exits.
pub(crate) struct WorldManager {
is_host: bool,
my_pos: (i32, i32),
cam_pos: (i32, i32),
my_peer_id: OmniPeerId,
save_state: SaveState,
/// We receive changes from other clients here, intending to send them to Noita.
@ -149,6 +151,8 @@ impl WorldManager {
let chunk_storage = save_state.load().unwrap_or_default();
WorldManager {
is_host,
my_pos: (i32::MIN + 3, i32::MIN + 3),
cam_pos: (i32::MIN + 3, i32::MIN + 3),
my_peer_id,
save_state,
inbound_model: Default::default(),
@ -167,7 +171,7 @@ impl WorldManager {
self.outbound_model.apply_noita_update(&update);
}
pub(crate) fn add_end(&mut self, priority: u8) {
pub(crate) fn add_end(&mut self, priority: u8, pos: Option<&[i32]>) {
let updated_chunks = self
.outbound_model
.updated_chunks()
@ -176,12 +180,16 @@ impl WorldManager {
.collect::<Vec<_>>();
self.current_update += 1;
for chunk in updated_chunks {
self.chunk_updated_locally(chunk, priority);
self.chunk_updated_locally(chunk, priority, pos);
}
self.outbound_model.reset_change_tracking();
}
fn chunk_updated_locally(&mut self, chunk: ChunkCoord, priority: u8) {
fn chunk_updated_locally(&mut self, chunk: ChunkCoord, priority: u8, pos: Option<&[i32]>) {
if let Some(data) = pos {
self.my_pos = (data[0], data[1]);
self.cam_pos = (data[2], data[3]);
}
let entry = self.chunk_state.entry(chunk).or_insert_with(|| {
debug!("Created entry for {chunk:?}");
ChunkState::RequestAuthority { priority }
@ -237,53 +245,10 @@ impl WorldManager {
}
pub(crate) fn update(&mut self) {
let mut emit_queue = Vec::new();
//TODO probably should just get these from world_sync.lua or something, then my_priority doesn't need to exist
let (mut my_x, mut my_y) = (i32::MIN + 3, i32::MIN + 3);
let (mut cam_x, mut cam_y) = (i32::MIN + 3, i32::MIN + 3);
let mut dont_kill = false;
let mut n = 0;
let mut nc = 0;
let mut no_cam = false;
for (&chunk, state) in self.chunk_state.iter() {
match state {
ChunkState::Listening { my_priority: priority, .. } | ChunkState::Authority { priority, .. } => {
if *priority == 0 || *priority == 32
{
if *priority == 0 {
no_cam = true
}
n += 1;
if my_x < chunk.0 || my_y < chunk.1 {
(my_x, my_y) = (chunk.0, chunk.1)
}
} else if *priority == 16
{
nc += 1;
if cam_x < chunk.0 || cam_y < chunk.1 {
(cam_x, cam_y) = (chunk.0, chunk.1)
}
}
}
_ => {
dont_kill = true;
break
},
}
}
if no_cam {
(cam_x, cam_y) = (i32::MIN + 3, i32::MIN + 3);
nc = 0;
}
if n < 4 || (nc != 0 && nc < 4) {
dont_kill = true
}
fn should_kill(x: i32, y: i32, cx: i32, cy: i32, chx: i32, chy: i32) -> bool {
if x == i32::MIN + 3
{
false
} else if cx == i32::MIN + 3 {
fn should_kill(my_pos: (i32, i32), cam_pos: (i32, i32), chx: i32, chy: i32) -> bool {
let (x, y) = my_pos;
let (cx, cy) = cam_pos;
if (x - cx).abs() <= 2 && (y - cy).abs() <= 2 {
!(chx <= x + 2 && chx >= x - 3
&& chy <= y + 2 && chy >= y - 3)
} else {
@ -293,6 +258,7 @@ impl WorldManager {
&& chy <= cy + 1 && chy >= cy - 2)
}
}
let mut emit_queue = Vec::new();
for (&chunk, state) in self.chunk_state.iter_mut() {
let chunk_last_update = self
@ -314,7 +280,7 @@ impl WorldManager {
// This state doesn't have much to do.
ChunkState::WaitingForAuthority => {}
ChunkState::Listening { authority, .. } => {
if !dont_kill && should_kill(my_x, my_y, cam_x, cam_y, chunk.0, chunk.1)
if should_kill(self.my_pos, self.cam_pos, chunk.0, chunk.1)
{
debug!("Unloading [listening] chunk {chunk:?}");
emit_queue.push((
@ -325,7 +291,7 @@ impl WorldManager {
}
}
ChunkState::Authority { .. } => {
if !dont_kill && should_kill(my_x, my_y, cam_x, cam_y, chunk.0, chunk.1)
if should_kill(self.my_pos, self.cam_pos, chunk.0, chunk.1)
{
debug!("Unloading [authority] chunk {chunk:?} (updates: {chunk_last_update} {})", self.current_update);
emit_queue.push((

View file

@ -41,4 +41,4 @@ impl WorldInfo {
}
})
}
}
}

View file

@ -57,7 +57,7 @@ local function send_chunks(cx, cy, chunk_map)
end
end
local function get_all_chunks(ocx, ocy, priority)
local function get_all_chunks(ocx, ocy, pos_data, priority)
local grid_world = world_ffi.get_grid_world()
local chunk_map = grid_world.vtable.get_chunk_map(grid_world)
--local thread_impl = grid_world.mThreadImpl
@ -68,7 +68,7 @@ local function get_all_chunks(ocx, ocy, priority)
send_chunks(cx, cy, chunk_map)
end
end
net.proxy_bin_send(KEY_WORLD_END, string.char(priority))
net.proxy_bin_send(KEY_WORLD_END, string.char(priority) .. pos_data)
elseif GameGetFrameNum() % (int * 2) == 1 then
local nx = ocx
if iter_fast then
@ -118,18 +118,19 @@ function world_sync.on_world_update()
local px, py = EntityGetTransform(player_data.entity)
-- Original Chunk x/y
local ocx, ocy = round(px / CHUNK_SIZE), round(py / CHUNK_SIZE)
local pos_data = ocx..":"..ocy..":"..cx..":"..cy
if math.abs(cx - ocx) > 2 or math.abs(cy - ocy) > 2 then
if iter_cam then
get_all_chunks(cx, cy, 16)
get_all_chunks(cx, cy, pos_data, 16)
else
get_all_chunks(ocx, ocy, 32)
get_all_chunks(ocx, ocy, pos_data, 32)
end
local int = 3 -- ctx.proxy_opt.world_sync_interval
if GameGetFrameNum() % (int * 8) == 0 then
if GameGetFrameNum() % (int * 4) == 0 then
iter_cam = not iter_cam
end
else
get_all_chunks(ocx, ocy, 0)
get_all_chunks(ocx, ocy, pos_data, 0)
end
end