Refactor player cosmetics handling a bit, properly create temp model if one wasn't sent.

This commit is contained in:
IQuant 2024-10-13 11:58:00 +03:00
parent 603c56c2d0
commit 17103adc97
5 changed files with 77 additions and 48 deletions

View file

@ -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",

View file

@ -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)
} }

View file

@ -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()
} }

View file

@ -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> {

View file

@ -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 {
"" ""