mirror of
https://github.com/IntQuant/noita_entangled_worlds.git
synced 2025-10-19 15:13:16 +00:00
Refactor player cosmetics handling a bit, properly create temp model if one wasn't sent.
This commit is contained in:
parent
603c56c2d0
commit
17103adc97
5 changed files with 77 additions and 48 deletions
2
noita-proxy/Cargo.lock
generated
2
noita-proxy/Cargo.lock
generated
|
@ -1949,7 +1949,7 @@ checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "noita-proxy"
|
name = "noita-proxy"
|
||||||
version = "0.26.2"
|
version = "0.26.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"argh",
|
"argh",
|
||||||
"bincode",
|
"bincode",
|
||||||
|
|
|
@ -19,6 +19,7 @@ use net::{
|
||||||
steam_networking::{ExtraPeerState, PerPeerStatusEntry},
|
steam_networking::{ExtraPeerState, PerPeerStatusEntry},
|
||||||
NetManagerInit, RunInfo,
|
NetManagerInit, RunInfo,
|
||||||
};
|
};
|
||||||
|
use player_cosmetics::PlayerPngDesc;
|
||||||
use self_update::SelfUpdateManager;
|
use self_update::SelfUpdateManager;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
@ -395,6 +396,10 @@ impl App {
|
||||||
mod_path,
|
mod_path,
|
||||||
player_path: player_path(self.modmanager_settings.mod_path()),
|
player_path: player_path(self.modmanager_settings.mod_path()),
|
||||||
modmanager_settings: self.modmanager_settings.clone(),
|
modmanager_settings: self.modmanager_settings.clone(),
|
||||||
|
player_png_desc: PlayerPngDesc {
|
||||||
|
cosmetics: cosmetics.into(),
|
||||||
|
colors: self.appearance.player_color,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1274,6 +1279,10 @@ fn cli_setup() -> (steam_helper::SteamState, NetManagerInit) {
|
||||||
mod_path: mod_manager.mod_path(),
|
mod_path: mod_manager.mod_path(),
|
||||||
player_path,
|
player_path,
|
||||||
modmanager_settings: mod_manager,
|
modmanager_settings: mod_manager,
|
||||||
|
player_png_desc: PlayerPngDesc {
|
||||||
|
cosmetics: cosmetics.into(),
|
||||||
|
colors: PlayerColor::default(),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
(state, netmaninit)
|
(state, netmaninit)
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,13 +23,13 @@ use tangled::Reliability;
|
||||||
use tracing::{error, info, warn};
|
use tracing::{error, info, warn};
|
||||||
use tungstenite::{accept, WebSocket};
|
use tungstenite::{accept, WebSocket};
|
||||||
|
|
||||||
use crate::player_cosmetics::create_player_png;
|
use crate::mod_manager::ModmanagerSettings;
|
||||||
|
use crate::player_cosmetics::{create_player_png, PlayerPngDesc};
|
||||||
use crate::{
|
use crate::{
|
||||||
bookkeeping::save_state::{SaveState, SaveStateEntry},
|
bookkeeping::save_state::{SaveState, SaveStateEntry},
|
||||||
recorder::Recorder,
|
recorder::Recorder,
|
||||||
GameSettings, PlayerColor,
|
GameSettings, PlayerColor,
|
||||||
};
|
};
|
||||||
use crate::mod_manager::ModmanagerSettings;
|
|
||||||
pub mod messages;
|
pub mod messages;
|
||||||
mod proxy_opt;
|
mod proxy_opt;
|
||||||
pub mod steam_networking;
|
pub mod steam_networking;
|
||||||
|
@ -110,7 +110,8 @@ pub struct NetManagerInit {
|
||||||
pub cosmetics: (bool, bool, bool),
|
pub cosmetics: (bool, bool, bool),
|
||||||
pub mod_path: PathBuf,
|
pub mod_path: PathBuf,
|
||||||
pub player_path: PathBuf,
|
pub player_path: PathBuf,
|
||||||
pub modmanager_settings: ModmanagerSettings
|
pub modmanager_settings: ModmanagerSettings,
|
||||||
|
pub player_png_desc: PlayerPngDesc,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct NetManager {
|
pub struct NetManager {
|
||||||
|
@ -170,7 +171,11 @@ impl NetManager {
|
||||||
create_dir(tmp).unwrap();
|
create_dir(tmp).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn start_inner(self: Arc<NetManager>, player_path: PathBuf, mut cli: bool) -> io::Result<()> {
|
pub(crate) fn start_inner(
|
||||||
|
self: Arc<NetManager>,
|
||||||
|
player_path: PathBuf,
|
||||||
|
mut cli: bool,
|
||||||
|
) -> io::Result<()> {
|
||||||
Self::clean_dir(player_path.clone());
|
Self::clean_dir(player_path.clone());
|
||||||
if !self.init_settings.cosmetics.0 {
|
if !self.init_settings.cosmetics.0 {
|
||||||
File::create(player_path.parent().unwrap().join("tmp/no_crown"))?;
|
File::create(player_path.parent().unwrap().join("tmp/no_crown"))?;
|
||||||
|
@ -227,15 +232,13 @@ impl NetManager {
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
let mut last_iter = Instant::now();
|
let mut last_iter = Instant::now();
|
||||||
|
// Create appearance files for local player.
|
||||||
create_player_png(
|
create_player_png(
|
||||||
|
self.peer.my_id().unwrap(),
|
||||||
&self.init_settings.mod_path,
|
&self.init_settings.mod_path,
|
||||||
&self.init_settings.player_path,
|
&self.init_settings.player_path,
|
||||||
(
|
&self.init_settings.player_png_desc,
|
||||||
self.peer.my_id().unwrap().to_string(),
|
self.is_host(),
|
||||||
self.init_settings.cosmetics,
|
|
||||||
self.init_settings.player_color,
|
|
||||||
),
|
|
||||||
self.is_host()
|
|
||||||
);
|
);
|
||||||
while self.continue_running.load(atomic::Ordering::Relaxed) {
|
while self.continue_running.load(atomic::Ordering::Relaxed) {
|
||||||
if cli {
|
if cli {
|
||||||
|
@ -283,7 +286,7 @@ impl NetManager {
|
||||||
match net_event {
|
match net_event {
|
||||||
omni::OmniNetworkEvent::PeerConnected(id) => {
|
omni::OmniNetworkEvent::PeerConnected(id) => {
|
||||||
self.broadcast(&NetMsg::Welcome, Reliability::Reliable);
|
self.broadcast(&NetMsg::Welcome, Reliability::Reliable);
|
||||||
info!("Peer connected");
|
info!("Peer connected {id}");
|
||||||
if self.peer.my_id() == Some(self.peer.host_id()) {
|
if self.peer.my_id() == Some(self.peer.host_id()) {
|
||||||
info!("Sending start game message");
|
info!("Sending start game message");
|
||||||
self.send(
|
self.send(
|
||||||
|
@ -293,25 +296,23 @@ impl NetManager {
|
||||||
},
|
},
|
||||||
Reliability::Reliable,
|
Reliability::Reliable,
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
if id != self.peer.my_id().unwrap() {
|
||||||
|
// Create temporary appearance files for new player.
|
||||||
create_player_png(
|
create_player_png(
|
||||||
|
id,
|
||||||
&self.init_settings.mod_path,
|
&self.init_settings.mod_path,
|
||||||
&self.init_settings.player_path,
|
&self.init_settings.player_path,
|
||||||
(
|
&PlayerPngDesc::default(),
|
||||||
self.peer.my_id().unwrap().to_string(),
|
self.is_host(),
|
||||||
self.init_settings.cosmetics,
|
|
||||||
self.init_settings.player_color,
|
|
||||||
),
|
|
||||||
self.is_host()
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
state.try_ws_write(ws_encode_proxy("join", id.as_hex()));
|
state.try_ws_write(ws_encode_proxy("join", id.as_hex()));
|
||||||
self.send(
|
self.send(
|
||||||
id,
|
id,
|
||||||
&NetMsg::PlayerColor((
|
&NetMsg::PlayerColor(
|
||||||
self.peer.my_id().unwrap().to_string(),
|
self.init_settings.player_png_desc,
|
||||||
self.init_settings.cosmetics,
|
self.is_host(),
|
||||||
self.init_settings.player_color),
|
|
||||||
self.is_host()
|
|
||||||
),
|
),
|
||||||
Reliability::Reliable,
|
Reliability::Reliable,
|
||||||
);
|
);
|
||||||
|
@ -350,11 +351,14 @@ impl NetManager {
|
||||||
}
|
}
|
||||||
NetMsg::WorldMessage(msg) => state.world.handle_msg(src, msg),
|
NetMsg::WorldMessage(msg) => state.world.handle_msg(src, msg),
|
||||||
NetMsg::PlayerColor(rgb, host) => {
|
NetMsg::PlayerColor(rgb, host) => {
|
||||||
|
info!("Player appearance created for {}", src);
|
||||||
|
// Create proper appearance files for new player.
|
||||||
create_player_png(
|
create_player_png(
|
||||||
|
src,
|
||||||
&self.init_settings.mod_path,
|
&self.init_settings.mod_path,
|
||||||
&self.init_settings.player_path,
|
&self.init_settings.player_path,
|
||||||
rgb,
|
&rgb,
|
||||||
host
|
host,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -458,7 +462,10 @@ impl NetManager {
|
||||||
state.try_ws_write_option("health_per_player", settings.health_per_player);
|
state.try_ws_write_option("health_per_player", settings.health_per_player);
|
||||||
state.try_ws_write_option("enemy_sync_interval", settings.enemy_sync_interval);
|
state.try_ws_write_option("enemy_sync_interval", settings.enemy_sync_interval);
|
||||||
let rgb = self.init_settings.player_color.player_main;
|
let rgb = self.init_settings.player_color.player_main;
|
||||||
state.try_ws_write_option("mina_color", rgb[0] as u32 + ((rgb[1] as u32) << 8) + ((rgb[2] as u32) << 16));
|
state.try_ws_write_option(
|
||||||
|
"mina_color",
|
||||||
|
rgb[0] as u32 + ((rgb[1] as u32) << 8) + ((rgb[2] as u32) << 16),
|
||||||
|
);
|
||||||
let progress = settings.progress.join(",");
|
let progress = settings.progress.join(",");
|
||||||
state.try_ws_write_option("progress", progress.as_str());
|
state.try_ws_write_option("progress", progress.as_str());
|
||||||
|
|
||||||
|
@ -595,7 +602,11 @@ impl NetManager {
|
||||||
settings.seed = rand::random();
|
settings.seed = rand::random();
|
||||||
}
|
}
|
||||||
info!("New seed: {}", settings.seed);
|
info!("New seed: {}", settings.seed);
|
||||||
settings.progress = self.init_settings.modmanager_settings.get_progress().unwrap_or_default();
|
settings.progress = self
|
||||||
|
.init_settings
|
||||||
|
.modmanager_settings
|
||||||
|
.get_progress()
|
||||||
|
.unwrap_or_default();
|
||||||
*self.settings.lock().unwrap() = settings;
|
*self.settings.lock().unwrap() = settings;
|
||||||
state.world.reset()
|
state.world.reset()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use bitcode::{Decode, Encode};
|
use bitcode::{Decode, Encode};
|
||||||
|
|
||||||
use crate::{GameSettings, PlayerColor};
|
use crate::{player_cosmetics::PlayerPngDesc, GameSettings};
|
||||||
|
|
||||||
use super::{omni::OmniPeerId, world::WorldNetMessage};
|
use super::{omni::OmniPeerId, world::WorldNetMessage};
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ pub(crate) enum NetMsg {
|
||||||
ModRaw { data: Vec<u8> },
|
ModRaw { data: Vec<u8> },
|
||||||
ModCompressed { data: Vec<u8> },
|
ModCompressed { data: Vec<u8> },
|
||||||
WorldMessage(WorldNetMessage),
|
WorldMessage(WorldNetMessage),
|
||||||
PlayerColor((String, (bool, bool, bool), PlayerColor), bool),
|
PlayerColor(PlayerPngDesc, bool),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<MessageRequest<WorldNetMessage>> for MessageRequest<NetMsg> {
|
impl From<MessageRequest<WorldNetMessage>> for MessageRequest<NetMsg> {
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
use crate::lang::tr;
|
use crate::lang::tr;
|
||||||
|
use crate::net::omni::OmniPeerId;
|
||||||
use crate::{App, PlayerColor, PlayerPicker};
|
use crate::{App, PlayerColor, PlayerPicker};
|
||||||
|
use bitcode::{Decode, Encode};
|
||||||
use eframe::egui;
|
use eframe::egui;
|
||||||
use eframe::egui::color_picker::{color_picker_color32, Alpha};
|
use eframe::egui::color_picker::{color_picker_color32, Alpha};
|
||||||
use eframe::egui::{Color32, TextureHandle, TextureOptions, Ui};
|
use eframe::egui::{Color32, TextureHandle, TextureOptions, Ui};
|
||||||
|
@ -25,7 +27,11 @@ pub fn arrows_path(path: PathBuf, is_host: bool) -> PathBuf {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cursor_path(path: PathBuf) -> PathBuf {
|
pub fn cursor_path(path: PathBuf) -> PathBuf {
|
||||||
path.parent().unwrap().parent().unwrap().join("resource/sprites/cursor.png")
|
path.parent()
|
||||||
|
.unwrap()
|
||||||
|
.parent()
|
||||||
|
.unwrap()
|
||||||
|
.join("resource/sprites/cursor.png")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn replace_color(image: &mut RgbaImage, main: Rgba<u8>, alt: Rgba<u8>, arm: Rgba<u8>) {
|
pub fn replace_color(image: &mut RgbaImage, main: Rgba<u8>, alt: Rgba<u8>, arm: Rgba<u8>) {
|
||||||
|
@ -228,19 +234,22 @@ pub fn create_arm(arm: Rgba<u8>) -> RgbaImage {
|
||||||
img
|
img
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Decode, Encode, Default)]
|
||||||
|
pub struct PlayerPngDesc {
|
||||||
|
pub(crate) cosmetics: [bool; 3],
|
||||||
|
pub(crate) colors: PlayerColor,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn create_player_png(
|
pub fn create_player_png(
|
||||||
|
peer: OmniPeerId,
|
||||||
mod_path: &Path,
|
mod_path: &Path,
|
||||||
player_path: &Path,
|
player_path: &Path,
|
||||||
rgb: (String, (bool, bool, bool), PlayerColor),
|
rgb: &PlayerPngDesc,
|
||||||
is_host: bool
|
is_host: bool,
|
||||||
) {
|
) {
|
||||||
let id = if rgb.0.len() < 5 {
|
let id = peer.as_hex();
|
||||||
format!("{:01$}", rgb.0.parse::<usize>().unwrap(), 16)
|
let cosmetics = rgb.cosmetics;
|
||||||
} else {
|
let rgb = rgb.colors;
|
||||||
format!("{:01$X}", rgb.0.parse::<u64>().unwrap(), 16).to_ascii_lowercase()
|
|
||||||
};
|
|
||||||
let cosmetics = rgb.1;
|
|
||||||
let rgb = rgb.2;
|
|
||||||
let tmp_path = player_path.parent().unwrap();
|
let tmp_path = player_path.parent().unwrap();
|
||||||
let arrows_path = arrows_path(tmp_path.into(), is_host);
|
let arrows_path = arrows_path(tmp_path.into(), is_host);
|
||||||
let cursor_path = cursor_path(tmp_path.into());
|
let cursor_path = cursor_path(tmp_path.into());
|
||||||
|
@ -303,7 +312,7 @@ pub fn create_player_png(
|
||||||
&[
|
&[
|
||||||
(
|
(
|
||||||
"MARKER_HAT2_ENABLED",
|
"MARKER_HAT2_ENABLED",
|
||||||
(if cosmetics.0 {
|
(if cosmetics[0] {
|
||||||
"image_file=\"data/enemies_gfx/player_hat2.xml\""
|
"image_file=\"data/enemies_gfx/player_hat2.xml\""
|
||||||
} else {
|
} else {
|
||||||
""
|
""
|
||||||
|
@ -312,7 +321,7 @@ pub fn create_player_png(
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"MARKER_AMULET_ENABLED",
|
"MARKER_AMULET_ENABLED",
|
||||||
(if cosmetics.1 {
|
(if cosmetics[1] {
|
||||||
"image_file=\"data/enemies_gfx/player_amulet.xml\""
|
"image_file=\"data/enemies_gfx/player_amulet.xml\""
|
||||||
} else {
|
} else {
|
||||||
""
|
""
|
||||||
|
@ -321,7 +330,7 @@ pub fn create_player_png(
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"MARKER_AMULET_GEM_ENABLED",
|
"MARKER_AMULET_GEM_ENABLED",
|
||||||
(if cosmetics.2 {
|
(if cosmetics[2] {
|
||||||
"image_file=\"data/enemies_gfx/player_amulet_gem.xml\""
|
"image_file=\"data/enemies_gfx/player_amulet_gem.xml\""
|
||||||
} else {
|
} else {
|
||||||
""
|
""
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue