mirror of
https://github.com/IntQuant/noita_entangled_worlds.git
synced 2025-10-19 15:13:16 +00:00
make and enable chunk map on clients
This commit is contained in:
parent
eaa74dd772
commit
3dcd6b4ec8
5 changed files with 147 additions and 90 deletions
|
@ -2062,9 +2062,7 @@ impl App {
|
|||
ConnectedMenu::VoIP,
|
||||
"VoIP Settings",
|
||||
);
|
||||
if netman.peer.is_host() {
|
||||
ui.selectable_value(&mut self.connected_menu, ConnectedMenu::Map, "Chunk Map");
|
||||
}
|
||||
ui.selectable_value(&mut self.connected_menu, ConnectedMenu::Map, "Chunk Map");
|
||||
if netman.peer.is_steam() {
|
||||
ui.selectable_value(
|
||||
&mut self.connected_menu,
|
||||
|
|
|
@ -29,8 +29,8 @@ use world::{NoitaWorldUpdate, WorldManager};
|
|||
|
||||
use crate::lobby_code::LobbyKind;
|
||||
use crate::mod_manager::{ModmanagerSettings, get_mods};
|
||||
use crate::net::world::world_model::ChunkCoord;
|
||||
use crate::net::world::world_model::chunk::{Pixel, PixelFlags};
|
||||
use crate::net::world::world_model::{ChunkCoord, ChunkData};
|
||||
use crate::player_cosmetics::{PlayerPngDesc, create_player_png, get_player_skin};
|
||||
use crate::steam_helper::LobbyExtraData;
|
||||
use crate::{
|
||||
|
@ -378,7 +378,7 @@ impl NetManager {
|
|||
let audio_settings = self.audio.lock().unwrap().clone();
|
||||
let audio_state = AudioManager::new(audio_settings);
|
||||
|
||||
let (world, rx, sendm) = WorldManager::new(
|
||||
let (world, rx, recv, sendm, tx) = WorldManager::new(
|
||||
is_host,
|
||||
self.peer.my_id(),
|
||||
self.init_settings.save_state.clone(),
|
||||
|
@ -493,11 +493,16 @@ impl NetManager {
|
|||
to_kick.clear();
|
||||
for net_event in self.peer.recv() {
|
||||
self.clone()
|
||||
.handle_network_event(&mut state, &player_image, net_event);
|
||||
.handle_network_event(&mut state, &player_image, net_event, &tx);
|
||||
}
|
||||
for net_msg in self.loopback_channel.1.try_iter() {
|
||||
self.clone()
|
||||
.handle_net_msg(&mut state, &player_image, self.peer.my_id(), net_msg);
|
||||
self.clone().handle_net_msg(
|
||||
&mut state,
|
||||
&player_image,
|
||||
self.peer.my_id(),
|
||||
net_msg,
|
||||
&tx,
|
||||
);
|
||||
}
|
||||
// Handle all available messages from Noita.
|
||||
while let Some(ws) = &mut state.ms {
|
||||
|
@ -576,16 +581,24 @@ impl NetManager {
|
|||
self.broadcast(&data, Reliability::Reliable);
|
||||
}
|
||||
}
|
||||
let mut map = FxHashMap::default();
|
||||
while let Ok((ch, img)) = rx.try_recv() {
|
||||
map.insert(ch, img);
|
||||
}
|
||||
if !map.is_empty() {
|
||||
let chunk_map = &mut self.chunk_map.lock().unwrap();
|
||||
for (ch, img) in map {
|
||||
chunk_map.insert(ch, img);
|
||||
}
|
||||
}
|
||||
if self.is_host() {
|
||||
let mut map = FxHashMap::default();
|
||||
while let Ok((ch, img)) = rx.try_recv() {
|
||||
map.insert(ch, img);
|
||||
while let Ok((ch, c)) = recv.try_recv() {
|
||||
map.insert(ch, c);
|
||||
}
|
||||
if !map.is_empty() {
|
||||
let chunk_map = &mut self.chunk_map.lock().unwrap();
|
||||
for (ch, img) in map {
|
||||
chunk_map.insert(ch, img);
|
||||
}
|
||||
let data = NetMsg::MapData(map);
|
||||
self.broadcast(&data, Reliability::Reliable)
|
||||
}
|
||||
}
|
||||
// Don't do excessive busy-waiting;
|
||||
|
@ -603,6 +616,7 @@ impl NetManager {
|
|||
state: &mut NetInnerState,
|
||||
player_image: &ImageBuffer<Rgba<u8>, Vec<u8>>,
|
||||
net_event: omni::OmniNetworkEvent,
|
||||
tx: &Sender<(ChunkCoord, ChunkData)>,
|
||||
) {
|
||||
match net_event {
|
||||
omni::OmniNetworkEvent::PeerConnected(id) => {
|
||||
|
@ -661,7 +675,7 @@ impl NetManager {
|
|||
else {
|
||||
return;
|
||||
};
|
||||
self.handle_net_msg(state, player_image, src, net_msg);
|
||||
self.handle_net_msg(state, player_image, src, net_msg, tx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -673,6 +687,7 @@ impl NetManager {
|
|||
player_image: &ImageBuffer<Rgba<u8>, Vec<u8>>,
|
||||
src: OmniPeerId,
|
||||
net_msg: NetMsg,
|
||||
tx: &Sender<(ChunkCoord, ChunkData)>,
|
||||
) {
|
||||
match net_msg {
|
||||
NetMsg::AudioData(data, global, tx, ty, vol) => {
|
||||
|
@ -694,6 +709,11 @@ impl NetManager {
|
|||
.play_audio(audio, pos, src, data, global, (tx, ty), vol);
|
||||
}
|
||||
}
|
||||
NetMsg::MapData(chunks) => {
|
||||
for (ch, c) in chunks {
|
||||
let _ = tx.send((ch, c));
|
||||
}
|
||||
}
|
||||
NetMsg::RequestMods => {
|
||||
if let Some(n) = &self.init_settings.modmanager_settings.game_save_path {
|
||||
let res = get_mods(n);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use bitcode::{Decode, Encode};
|
||||
|
||||
use crate::{GameSettings, player_cosmetics::PlayerPngDesc};
|
||||
|
||||
use super::{omni::OmniPeerId, world::WorldNetMessage};
|
||||
use crate::net::world::world_model::{ChunkCoord, ChunkData};
|
||||
use crate::{GameSettings, player_cosmetics::PlayerPngDesc};
|
||||
use bitcode::{Decode, Encode};
|
||||
use rustc_hash::FxHashMap;
|
||||
|
||||
pub(crate) type Destination = shared::Destination<OmniPeerId>;
|
||||
|
||||
|
@ -35,6 +35,7 @@ pub(crate) enum NetMsg {
|
|||
RespondFlagMoon(i32, i32, bool),
|
||||
RespondFlagStevari(i32, i32, OmniPeerId),
|
||||
AudioData(Vec<Vec<u8>>, bool, i32, i32, f32),
|
||||
MapData(FxHashMap<ChunkCoord, ChunkData>),
|
||||
}
|
||||
|
||||
impl From<MessageRequest<WorldNetMessage>> for MessageRequest<NetMsg> {
|
||||
|
|
|
@ -225,55 +225,96 @@ impl WorldManager {
|
|||
) -> (
|
||||
Self,
|
||||
Receiver<(ChunkCoord, RgbaImage)>,
|
||||
Receiver<(ChunkCoord, ChunkData)>,
|
||||
Sender<FxHashMap<u16, u32>>,
|
||||
Sender<(ChunkCoord, ChunkData)>,
|
||||
) {
|
||||
let (send, rx) = mpsc::channel::<(ChunkCoord, RgbaImage)>();
|
||||
let (sendm, rxm) = mpsc::channel::<FxHashMap<u16, u32>>();
|
||||
let (tx, recv) = mpsc::channel::<(ChunkCoord, ChunkData)>();
|
||||
if is_host {
|
||||
thread::spawn(move || {
|
||||
let mut mats = Default::default();
|
||||
loop {
|
||||
while let Ok(mat) = rxm.try_recv() {
|
||||
mats = mat;
|
||||
}
|
||||
while let Ok((c, data)) = recv.try_recv() {
|
||||
let _ = send.send((c, create_image(data, &mats)));
|
||||
}
|
||||
thread::sleep(Duration::from_millis(16));
|
||||
let (tsx, recv2) = mpsc::channel::<(ChunkCoord, ChunkData)>();
|
||||
thread::spawn(move || {
|
||||
let mut mats = Default::default();
|
||||
loop {
|
||||
while let Ok(mat) = rxm.try_recv() {
|
||||
mats = mat;
|
||||
}
|
||||
});
|
||||
}
|
||||
while let Ok((c, data)) = recv.try_recv() {
|
||||
if is_host {
|
||||
let _ = tsx.send((c, data.clone()));
|
||||
}
|
||||
let _ = send.send((c, create_image(data, &mats)));
|
||||
}
|
||||
thread::sleep(Duration::from_millis(16));
|
||||
}
|
||||
});
|
||||
let chunk_storage = save_state.load().unwrap_or_default();
|
||||
(
|
||||
WorldManager {
|
||||
nice_terraforming: true,
|
||||
is_host,
|
||||
my_pos: (i32::MIN / 2, i32::MIN / 2),
|
||||
cam_pos: (i32::MIN / 2, i32::MIN / 2),
|
||||
is_notplayer: false,
|
||||
my_peer_id,
|
||||
save_state,
|
||||
inbound_model: Default::default(),
|
||||
outbound_model: Default::default(),
|
||||
authority_map: Default::default(),
|
||||
chunk_storage,
|
||||
chunk_state: Default::default(),
|
||||
emitted_messages: Default::default(),
|
||||
current_update: 0,
|
||||
chunk_last_update: Default::default(),
|
||||
last_request_priority: Default::default(),
|
||||
world_num: 0,
|
||||
materials: Default::default(),
|
||||
is_storage_recent: Default::default(),
|
||||
explosion_pointer: Default::default(),
|
||||
explosion_data: Default::default(),
|
||||
explosion_heap: Default::default(),
|
||||
let (fx, _) = mpsc::channel::<(ChunkCoord, ChunkData)>();
|
||||
if is_host {
|
||||
(
|
||||
WorldManager {
|
||||
nice_terraforming: true,
|
||||
is_host,
|
||||
my_pos: (i32::MIN / 2, i32::MIN / 2),
|
||||
cam_pos: (i32::MIN / 2, i32::MIN / 2),
|
||||
is_notplayer: false,
|
||||
my_peer_id,
|
||||
save_state,
|
||||
inbound_model: Default::default(),
|
||||
outbound_model: Default::default(),
|
||||
authority_map: Default::default(),
|
||||
chunk_storage,
|
||||
chunk_state: Default::default(),
|
||||
emitted_messages: Default::default(),
|
||||
current_update: 0,
|
||||
chunk_last_update: Default::default(),
|
||||
last_request_priority: Default::default(),
|
||||
world_num: 0,
|
||||
materials: Default::default(),
|
||||
is_storage_recent: Default::default(),
|
||||
explosion_pointer: Default::default(),
|
||||
explosion_data: Default::default(),
|
||||
explosion_heap: Default::default(),
|
||||
tx,
|
||||
},
|
||||
rx,
|
||||
recv2,
|
||||
sendm,
|
||||
fx,
|
||||
)
|
||||
} else {
|
||||
(
|
||||
WorldManager {
|
||||
nice_terraforming: true,
|
||||
is_host,
|
||||
my_pos: (i32::MIN / 2, i32::MIN / 2),
|
||||
cam_pos: (i32::MIN / 2, i32::MIN / 2),
|
||||
is_notplayer: false,
|
||||
my_peer_id,
|
||||
save_state,
|
||||
inbound_model: Default::default(),
|
||||
outbound_model: Default::default(),
|
||||
authority_map: Default::default(),
|
||||
chunk_storage,
|
||||
chunk_state: Default::default(),
|
||||
emitted_messages: Default::default(),
|
||||
current_update: 0,
|
||||
chunk_last_update: Default::default(),
|
||||
last_request_priority: Default::default(),
|
||||
world_num: 0,
|
||||
materials: Default::default(),
|
||||
is_storage_recent: Default::default(),
|
||||
explosion_pointer: Default::default(),
|
||||
explosion_data: Default::default(),
|
||||
explosion_heap: Default::default(),
|
||||
tx: fx,
|
||||
},
|
||||
rx,
|
||||
recv2,
|
||||
sendm,
|
||||
tx,
|
||||
},
|
||||
rx,
|
||||
sendm,
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn add_update(&mut self, update: NoitaWorldUpdate) {
|
||||
|
@ -2467,7 +2508,7 @@ fn get_ray(r: u64) -> u64 {
|
|||
#[test]
|
||||
#[serial]
|
||||
fn test_explosion_img() {
|
||||
let (mut world, _, _) = WorldManager::new(
|
||||
let (mut world, _, _, _, _) = WorldManager::new(
|
||||
true,
|
||||
OmniPeerId(0),
|
||||
SaveState::new("/tmp/ew_tmp_save".parse().unwrap()),
|
||||
|
@ -2569,7 +2610,7 @@ fn test_explosion_img() {
|
|||
#[test]
|
||||
#[serial]
|
||||
fn test_explosion_img_big() {
|
||||
let (mut world, _, _) = WorldManager::new(
|
||||
let (mut world, _, _, _, _) = WorldManager::new(
|
||||
true,
|
||||
OmniPeerId(0),
|
||||
SaveState::new("/tmp/ew_tmp_save".parse().unwrap()),
|
||||
|
@ -2638,7 +2679,7 @@ fn test_explosion_img_big() {
|
|||
#[test]
|
||||
#[serial]
|
||||
fn test_explosion_img_big_br() {
|
||||
let (mut world, _, _) = WorldManager::new(
|
||||
let (mut world, _, _, _, _) = WorldManager::new(
|
||||
true,
|
||||
OmniPeerId(0),
|
||||
SaveState::new("/tmp/ew_tmp_save".parse().unwrap()),
|
||||
|
@ -2714,7 +2755,7 @@ fn test_explosion_img_big_br() {
|
|||
#[test]
|
||||
#[serial]
|
||||
fn test_explosion_img_big_empty() {
|
||||
let (mut world, _, _) = WorldManager::new(
|
||||
let (mut world, _, _, _, _) = WorldManager::new(
|
||||
true,
|
||||
OmniPeerId(0),
|
||||
SaveState::new("/tmp/ew_tmp_save".parse().unwrap()),
|
||||
|
@ -2773,7 +2814,7 @@ fn test_explosion_img_big_empty() {
|
|||
#[test]
|
||||
#[serial]
|
||||
fn test_explosion_large() {
|
||||
let (mut world, _, _) = WorldManager::new(
|
||||
let (mut world, _, _, _, _) = WorldManager::new(
|
||||
true,
|
||||
OmniPeerId(0),
|
||||
SaveState::new("/tmp/ew_tmp_save".parse().unwrap()),
|
||||
|
@ -2818,7 +2859,7 @@ fn test_explosion_large() {
|
|||
#[test]
|
||||
#[serial]
|
||||
fn test_cut_img() {
|
||||
let (mut world, _, _) = WorldManager::new(
|
||||
let (mut world, _, _, _, _) = WorldManager::new(
|
||||
true,
|
||||
OmniPeerId(0),
|
||||
SaveState::new("/tmp/ew_tmp_save".parse().unwrap()),
|
||||
|
@ -2861,7 +2902,7 @@ fn test_cut_img() {
|
|||
#[test]
|
||||
#[serial]
|
||||
fn test_line_img() {
|
||||
let (mut world, _, _) = WorldManager::new(
|
||||
let (mut world, _, _, _, _) = WorldManager::new(
|
||||
true,
|
||||
OmniPeerId(0),
|
||||
SaveState::new("/tmp/ew_tmp_save".parse().unwrap()),
|
||||
|
@ -2948,7 +2989,7 @@ fn test_line_img() {
|
|||
#[test]
|
||||
#[serial]
|
||||
fn test_circ_img() {
|
||||
let (mut world, _, _) = WorldManager::new(
|
||||
let (mut world, _, _, _, _) = WorldManager::new(
|
||||
true,
|
||||
OmniPeerId(0),
|
||||
SaveState::new("/tmp/ew_tmp_save".parse().unwrap()),
|
||||
|
@ -2991,7 +3032,7 @@ fn test_circ_img() {
|
|||
#[test]
|
||||
#[serial]
|
||||
fn test_explosion_img_big_many() {
|
||||
let (mut world, _, _) = WorldManager::new(
|
||||
let (mut world, _, _, _, _) = WorldManager::new(
|
||||
true,
|
||||
OmniPeerId(0),
|
||||
SaveState::new("/tmp/ew_tmp_save".parse().unwrap()),
|
||||
|
@ -3099,7 +3140,7 @@ fn test_explosion_perf() {
|
|||
let mut total = 0;
|
||||
let iters = 64;
|
||||
for _ in 0..iters {
|
||||
let (mut world, _, _) = WorldManager::new(
|
||||
let (mut world, _, _, _, _) = WorldManager::new(
|
||||
true,
|
||||
OmniPeerId(0),
|
||||
SaveState::new("/tmp/ew_tmp_save".parse().unwrap()),
|
||||
|
@ -3151,7 +3192,7 @@ fn test_explosion_perf_unloaded() {
|
|||
let iters = 4;
|
||||
let mut n = 0;
|
||||
for _ in 0..iters {
|
||||
let (mut world, _, _) = WorldManager::new(
|
||||
let (mut world, _, _, _, _) = WorldManager::new(
|
||||
true,
|
||||
OmniPeerId(0),
|
||||
SaveState::new("/tmp/ew_tmp_save".parse().unwrap()),
|
||||
|
@ -3219,7 +3260,7 @@ fn test_explosion_perf_large() {
|
|||
let mut total = 0;
|
||||
let iters = 16;
|
||||
for _ in 0..iters {
|
||||
let (mut world, _, _) = WorldManager::new(
|
||||
let (mut world, _, _, _, _) = WorldManager::new(
|
||||
true,
|
||||
OmniPeerId(0),
|
||||
SaveState::new("/tmp/ew_tmp_save".parse().unwrap()),
|
||||
|
@ -3270,7 +3311,7 @@ fn test_line_perf() {
|
|||
let mut total = 0;
|
||||
let iters = 64;
|
||||
for _ in 0..iters {
|
||||
let (mut world, _, _) = WorldManager::new(
|
||||
let (mut world, _, _, _, _) = WorldManager::new(
|
||||
true,
|
||||
OmniPeerId(0),
|
||||
SaveState::new("/tmp/ew_tmp_save".parse().unwrap()),
|
||||
|
@ -3309,7 +3350,7 @@ fn test_circle_perf() {
|
|||
let mut total = 0;
|
||||
let iters = 64;
|
||||
for _ in 0..iters {
|
||||
let (mut world, _, _) = WorldManager::new(
|
||||
let (mut world, _, _, _, _) = WorldManager::new(
|
||||
true,
|
||||
OmniPeerId(0),
|
||||
SaveState::new("/tmp/ew_tmp_save".parse().unwrap()),
|
||||
|
@ -3348,7 +3389,7 @@ fn test_cut_perf() {
|
|||
let mut total = 0;
|
||||
let iters = 64;
|
||||
for _ in 0..iters {
|
||||
let (mut world, _, _) = WorldManager::new(
|
||||
let (mut world, _, _, _, _) = WorldManager::new(
|
||||
true,
|
||||
OmniPeerId(0),
|
||||
SaveState::new("/tmp/ew_tmp_save".parse().unwrap()),
|
||||
|
|
|
@ -3,6 +3,18 @@ local module = {}
|
|||
local ptt = 0
|
||||
|
||||
function module.on_world_update()
|
||||
if GameGetFrameNum() % 8 == 7 then
|
||||
local s = ""
|
||||
for peer, data in pairs(ctx.players) do
|
||||
local x, y = EntityGetTransform(data.entity)
|
||||
if x == nil then
|
||||
return
|
||||
end
|
||||
s = s .. " " .. tostring(peer) .. " " .. math.floor(x) .. " " .. math.floor(y)
|
||||
end
|
||||
net.proxy_send("players_pos", string.sub(s, 2, -1))
|
||||
end
|
||||
|
||||
if GameGetFrameNum() % 4 ~= 2 then
|
||||
return
|
||||
end
|
||||
|
@ -62,19 +74,4 @@ function module.on_world_update()
|
|||
)
|
||||
end
|
||||
|
||||
function module.on_world_update_host()
|
||||
if GameGetFrameNum() % 8 ~= 2 then
|
||||
return
|
||||
end
|
||||
local s = ""
|
||||
for peer, data in pairs(ctx.players) do
|
||||
local x, y = EntityGetTransform(data.entity)
|
||||
if x == nil then
|
||||
return
|
||||
end
|
||||
s = s .. " " .. tostring(peer) .. " " .. math.floor(x) .. " " .. math.floor(y)
|
||||
end
|
||||
net.proxy_send("players_pos", string.sub(s, 2, -1))
|
||||
end
|
||||
|
||||
return module
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue