From ef5e25f940ef5b9a20bb926a5e2e7b1839f0c1bb Mon Sep 17 00:00:00 2001 From: Jupeyy Date: Fri, 17 Jan 2025 17:35:34 +0100 Subject: [PATCH] Use consistent naming scheme for asset parts. Add extras splitting tool. Add missing snowflake & sparkle implementation. --- Cargo.lock | 10 + Cargo.toml | 2 +- data | 2 +- game/client-containers/src/container.rs | 77 ++ game/client-containers/src/freezes.rs | 42 +- game/client-containers/src/game.rs | 149 +--- game/client-containers/src/hooks.rs | 116 +-- game/client-containers/src/ninja.rs | 149 ++-- game/client-containers/src/particles.rs | 325 ++++----- game/client-containers/src/skins.rs | 344 ++------- game/client-containers/src/weapons.rs | 683 ++++++++---------- game/client-extra/src/extra_split.rs | 81 +++ game/client-extra/src/lib.rs | 1 + game/client-render-base/src/render/toolkit.rs | 18 +- .../src/components/game_objects.rs | 6 +- game/client-render-game/src/components/hud.rs | 23 +- game/client-render-game/src/render_game.rs | 15 +- .../main_menu/settings/player/assets/game.rs | 5 - .../settings/player/assets/particles.rs | 38 +- src/extra-convert/Cargo.toml | 11 + src/extra-convert/src/main.rs | 110 +++ src/game-convert/src/main.rs | 14 +- src/part-convert/src/main.rs | 26 +- 23 files changed, 1018 insertions(+), 1229 deletions(-) create mode 100644 game/client-extra/src/extra_split.rs create mode 100644 src/extra-convert/Cargo.toml create mode 100644 src/extra-convert/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index 9123223..87b5ceb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3716,6 +3716,16 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af9673d8203fcb076b19dfd17e38b3d4ae9f44959416ea532ce72415a6020365" +[[package]] +name = "extra-convert" +version = "0.1.0" +dependencies = [ + "clap 4.5.23", + "client-extra", + "image-utils", + "tar", +] + [[package]] name = "fallible-iterator" version = "0.3.0" diff --git a/Cargo.toml b/Cargo.toml index 36ed0b3..3d85758 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -106,7 +106,7 @@ members = [ "lib/steam", "game/game-state-wasm", "lib/native-display", "src/assets-server", "game/assets-base", "src/community-server", "src/community-register-server", - "game/community", "lib/input-binds", "game/ghost", "game/client-ghost", "game/client-replay", "game/editor-wasm", "game/client-notifications", "src/editor-server", + "game/community", "lib/input-binds", "game/ghost", "game/client-ghost", "game/client-replay", "game/editor-wasm", "game/client-notifications", "src/editor-server", "src/extra-convert", ] [package] diff --git a/data b/data index 697fa7e..6944fcf 160000 --- a/data +++ b/data @@ -1 +1 @@ -Subproject commit 697fa7eb26350a2b102d2dabc5d07171accc8f6e +Subproject commit 6944fcfdeef9a0d708322047ffde45e4088cd4a0 diff --git a/game/client-containers/src/container.rs b/game/client-containers/src/container.rs index 3436ab1..48877cf 100644 --- a/game/client-containers/src/container.rs +++ b/game/client-containers/src/container.rs @@ -1485,6 +1485,45 @@ pub fn load_file_part_and_upload_ex( }) } +pub fn load_file_part_list_and_upload( + graphics_mt: &GraphicsMultiThreaded, + files: &ContainerLoadedItemDir, + default_files: &ContainerLoadedItemDir, + item_name: &str, + extra_paths: &[&str], + part_name_base: &str, +) -> anyhow::Result> { + let mut textures = Vec::new(); + let mut i = 0; + let mut allow_default = true; + loop { + match load_file_part_and_upload_ex( + graphics_mt, + files, + default_files, + item_name, + extra_paths, + &format!("{part_name_base}_{:03}", i + 1), + allow_default, + ) { + Ok(img) => { + allow_default &= img.from_default; + textures.push(img.img); + } + Err(err) => { + if i == 0 { + return Err(err); + } else { + break; + } + } + } + + i += 1; + } + Ok(textures) +} + pub struct SoundFilePartResult { pub mem: SoundBackendMemory, /// Was loaded by the default fallback mechanism @@ -1570,6 +1609,44 @@ pub fn load_sound_file_part_and_upload_ex( Ok(SoundFilePartResult { mem, from_default }) } +pub fn load_sound_file_part_list_and_upload( + sound_mt: &SoundMultiThreaded, + files: &ContainerLoadedItemDir, + default_files: &ContainerLoadedItemDir, + item_name: &str, + extra_paths: &[&str], + part_name_base: &str, +) -> anyhow::Result> { + let mut sounds = Vec::new(); + let mut i = 0; + let mut allow_default = true; + loop { + match load_sound_file_part_and_upload_ex( + sound_mt, + files, + default_files, + item_name, + extra_paths, + &format!("{part_name_base}_{:03}", i + 1), + allow_default, + ) { + Ok(sound) => { + allow_default &= sound.from_default; + sounds.push(sound.mem); + } + Err(err) => { + if i == 0 { + return Err(err); + } else { + break; + } + } + } + i += 1; + } + Ok(sounds) +} + /// returns the png data, the width and height are the 3d texture w & h, additionally the depth is returned pub fn load_file_part_as_png_and_convert_3d( runtime_thread_pool: &Arc, diff --git a/game/client-containers/src/freezes.rs b/game/client-containers/src/freezes.rs index df8d393..a8fb5e7 100644 --- a/game/client-containers/src/freezes.rs +++ b/game/client-containers/src/freezes.rs @@ -9,7 +9,9 @@ use sound::{ }; use crate::{ - container::{load_sound_file_part_and_upload_ex, ContainerLoadedItem, ContainerLoadedItemDir}, + container::{ + load_sound_file_part_list_and_upload, ContainerLoadedItem, ContainerLoadedItemDir, + }, skins::{LoadSkin, Skin}, }; @@ -49,36 +51,14 @@ impl LoadFreeze { Some("skin"), )?, - attacks: { - let mut sounds = Vec::new(); - let mut i = 0; - let mut allow_default = true; - loop { - match load_sound_file_part_and_upload_ex( - sound_mt, - &files, - default_files, - freeze_name, - &["audio"], - &format!("attack{}", i + 1), - allow_default, - ) { - Ok(sound) => { - allow_default &= sound.from_default; - sounds.push(sound.mem); - } - Err(err) => { - if i == 0 { - return Err(err); - } else { - break; - } - } - } - i += 1; - } - sounds - }, + attacks: load_sound_file_part_list_and_upload( + sound_mt, + &files, + default_files, + freeze_name, + &["audio"], + "attack", + )?, _freeze_name: freeze_name.to_string(), }) diff --git a/game/client-containers/src/game.rs b/game/client-containers/src/game.rs index 9b8885e..87583cb 100644 --- a/game/client-containers/src/game.rs +++ b/game/client-containers/src/game.rs @@ -10,8 +10,7 @@ use sound::{ }; use crate::container::{ - load_file_part_and_upload_ex, load_sound_file_part_and_upload, - load_sound_file_part_and_upload_ex, ContainerLoadedItem, ContainerLoadedItemDir, + load_sound_file_part_list_and_upload, ContainerLoadedItem, ContainerLoadedItemDir, }; use super::container::{ @@ -22,7 +21,7 @@ use super::container::{ pub struct Pickup { pub tex: TextureContainer, - pub spawn: SoundObject, + pub spawns: Vec, pub collects: Vec, } @@ -35,15 +34,13 @@ pub struct Game { pub lose_laser: TextureContainer, pub lose_ninja: TextureContainer, pub lose_shotgun: TextureContainer, - - pub stars: Vec, } #[derive(Debug)] pub struct LoadPickup { pub tex: ContainerItemLoadData, - pub spawn: SoundBackendMemory, + pub spawns: Vec, pub collects: Vec, } @@ -57,8 +54,6 @@ pub struct LoadGame { pub lose_ninja: ContainerItemLoadData, pub lose_shotgun: ContainerItemLoadData, - pub stars: Vec, - game_name: String, } @@ -82,45 +77,22 @@ impl LoadGame { )? .img, - spawn: load_sound_file_part_and_upload( + spawns: load_sound_file_part_list_and_upload( sound_mt, &files, default_files, game_name, &["audio", "heart"], "spawn", - )? - .mem, - collects: { - let mut sounds = Vec::new(); - let mut i = 0; - let mut allow_default = true; - loop { - match load_sound_file_part_and_upload_ex( - sound_mt, - &files, - default_files, - game_name, - &["audio", "heart"], - &format!("collect{}", i + 1), - allow_default, - ) { - Ok(sound) => { - allow_default &= sound.from_default; - sounds.push(sound.mem); - } - Err(err) => { - if i == 0 { - return Err(err); - } else { - break; - } - } - } - i += 1; - } - sounds - }, + )?, + collects: load_sound_file_part_list_and_upload( + sound_mt, + &files, + default_files, + game_name, + &["audio", "heart"], + "collect", + )?, }, shield: LoadPickup { tex: load_file_part_and_upload( @@ -133,45 +105,22 @@ impl LoadGame { )? .img, - spawn: load_sound_file_part_and_upload( + spawns: load_sound_file_part_list_and_upload( sound_mt, &files, default_files, game_name, &["audio", "shield"], "spawn", - )? - .mem, - collects: { - let mut sounds = Vec::new(); - let mut i = 0; - let mut allow_default = true; - loop { - match load_sound_file_part_and_upload_ex( - sound_mt, - &files, - default_files, - game_name, - &["audio", "shield"], - &format!("collect{}", i + 1), - allow_default, - ) { - Ok(sound) => { - allow_default &= sound.from_default; - sounds.push(sound.mem); - } - Err(err) => { - if i == 0 { - return Err(err); - } else { - break; - } - } - } - i += 1; - } - sounds - }, + )?, + collects: load_sound_file_part_list_and_upload( + sound_mt, + &files, + default_files, + game_name, + &["audio", "shield"], + "collect", + )?, }, lose_grenade: load_file_part_and_upload( @@ -211,38 +160,6 @@ impl LoadGame { )? .img, - stars: { - let mut textures = Vec::new(); - let mut i = 0; - let mut allow_default = true; - loop { - match load_file_part_and_upload_ex( - graphics_mt, - &files, - default_files, - game_name, - &[], - &format!("star{}", i + 1), - allow_default, - ) { - Ok(img) => { - allow_default &= img.from_default; - textures.push(img.img); - } - Err(err) => { - if i == 0 { - return Err(err); - } else { - break; - } - } - } - - i += 1; - } - textures - }, - game_name: game_name.to_string(), }) } @@ -284,7 +201,12 @@ impl ContainerLoad for LoadGame { heart: Pickup { tex: Self::load_file_into_texture(texture_handle, self.heart.tex, &self.game_name), - spawn: sound_object_handle.create(self.heart.spawn), + spawns: self + .heart + .spawns + .into_iter() + .map(|obj| sound_object_handle.create(obj)) + .collect::>(), collects: self .heart .collects @@ -295,7 +217,12 @@ impl ContainerLoad for LoadGame { shield: Pickup { tex: Self::load_file_into_texture(texture_handle, self.shield.tex, &self.game_name), - spawn: sound_object_handle.create(self.shield.spawn), + spawns: self + .shield + .spawns + .into_iter() + .map(|obj| sound_object_handle.create(obj)) + .collect::>(), collects: self .shield .collects @@ -324,12 +251,6 @@ impl ContainerLoad for LoadGame { self.lose_shotgun, &self.game_name, ), - - stars: self - .stars - .into_iter() - .map(|star| Self::load_file_into_texture(texture_handle, star, &self.game_name)) - .collect::>(), } } } diff --git a/game/client-containers/src/hooks.rs b/game/client-containers/src/hooks.rs index e235172..52ace72 100644 --- a/game/client-containers/src/hooks.rs +++ b/game/client-containers/src/hooks.rs @@ -11,7 +11,7 @@ use sound::{ }; use crate::container::{ - load_sound_file_part_and_upload_ex, ContainerLoadedItem, ContainerLoadedItemDir, + load_sound_file_part_list_and_upload, ContainerLoadedItem, ContainerLoadedItemDir, }; use super::container::{ @@ -68,96 +68,30 @@ impl LoadHook { )? .img, - hit_hookable: { - let mut sounds: Vec<_> = Vec::new(); - let mut i = 0; - let mut allow_default = true; - loop { - match load_sound_file_part_and_upload_ex( - sound_mt, - &files, - default_files, - hook_name, - &[], - &format!("hit_hookable{}", i + 1), - allow_default, - ) { - Ok(sound) => { - allow_default &= sound.from_default; - sounds.push(sound.mem); - } - Err(err) => { - if i == 0 { - return Err(err); - } else { - break; - } - } - } - i += 1; - } - sounds - }, - hit_player: { - let mut sounds: Vec<_> = Vec::new(); - let mut i = 0; - let mut allow_default = true; - loop { - match load_sound_file_part_and_upload_ex( - sound_mt, - &files, - default_files, - hook_name, - &[], - &format!("hit_player{}", i + 1), - allow_default, - ) { - Ok(sound) => { - allow_default &= sound.from_default; - sounds.push(sound.mem); - } - Err(err) => { - if i == 0 { - return Err(err); - } else { - break; - } - } - } - i += 1; - } - sounds - }, - hit_unhookable: { - let mut sounds: Vec<_> = Vec::new(); - let mut i = 0; - let mut allow_default = true; - loop { - match load_sound_file_part_and_upload_ex( - sound_mt, - &files, - default_files, - hook_name, - &[], - &format!("hit_unhookable{}", i + 1), - allow_default, - ) { - Ok(sound) => { - allow_default &= sound.from_default; - sounds.push(sound.mem); - } - Err(err) => { - if i == 0 { - return Err(err); - } else { - break; - } - } - } - i += 1; - } - sounds - }, + hit_hookable: load_sound_file_part_list_and_upload( + sound_mt, + &files, + default_files, + hook_name, + &[], + "hit_hookable", + )?, + hit_player: load_sound_file_part_list_and_upload( + sound_mt, + &files, + default_files, + hook_name, + &[], + "hit_player", + )?, + hit_unhookable: load_sound_file_part_list_and_upload( + sound_mt, + &files, + default_files, + hook_name, + &[], + "hit_unhookable", + )?, hook_name: hook_name.to_string(), }) diff --git a/game/client-containers/src/ninja.rs b/game/client-containers/src/ninja.rs index 628e931..69c51ce 100644 --- a/game/client-containers/src/ninja.rs +++ b/game/client-containers/src/ninja.rs @@ -12,8 +12,8 @@ use sound::{ use crate::{ container::{ - load_file_part_and_upload_ex, load_sound_file_part_and_upload, - load_sound_file_part_and_upload_ex, ContainerLoadedItem, ContainerLoadedItemDir, + load_file_part_list_and_upload, load_sound_file_part_list_and_upload, ContainerLoadedItem, + ContainerLoadedItemDir, }, skins::{LoadSkin, Skin}, }; @@ -30,8 +30,8 @@ pub struct Ninja { pub skin: Rc, - pub spawn: SoundObject, - pub collect: SoundObject, + pub spawn: Vec, + pub collect: Vec, pub attacks: Vec, pub hits: Vec, } @@ -44,8 +44,8 @@ pub struct LoadNinja { skin: LoadSkin, - spawn: SoundBackendMemory, - collect: SoundBackendMemory, + spawn: Vec, + collect: Vec, attacks: Vec, hits: Vec, @@ -79,37 +79,14 @@ impl LoadNinja { "weapon", )? .img, - muzzles: { - let mut textures = Vec::new(); - let mut i = 0; - let mut allow_default = true; - loop { - match load_file_part_and_upload_ex( - graphics_mt, - &files, - default_files, - ninja_name, - &[], - &format!("muzzle{i}"), - allow_default, - ) { - Ok(img) => { - allow_default &= img.from_default; - textures.push(img.img); - } - Err(err) => { - if i == 0 { - return Err(err); - } else { - break; - } - } - } - - i += 1; - } - textures - }, + muzzles: load_file_part_list_and_upload( + graphics_mt, + &files, + default_files, + ninja_name, + &[], + "muzzle", + )?, skin: LoadSkin::new( graphics_mt, @@ -120,84 +97,38 @@ impl LoadNinja { Some("skin"), )?, - spawn: load_sound_file_part_and_upload( + spawn: load_sound_file_part_list_and_upload( sound_mt, &files, default_files, ninja_name, &["audio"], "spawn", - )? - .mem, - collect: load_sound_file_part_and_upload( + )?, + collect: load_sound_file_part_list_and_upload( sound_mt, &files, default_files, ninja_name, &["audio"], "collect", - )? - .mem, - attacks: { - let mut sounds: Vec<_> = Vec::new(); - let mut i = 0; - let mut allow_default = true; - loop { - match load_sound_file_part_and_upload_ex( - sound_mt, - &files, - default_files, - ninja_name, - &["audio"], - &format!("attack{}", i + 1), - allow_default, - ) { - Ok(sound) => { - allow_default &= sound.from_default; - sounds.push(sound.mem); - } - Err(err) => { - if i == 0 { - return Err(err); - } else { - break; - } - } - } - i += 1; - } - sounds - }, - hits: { - let mut sounds: Vec<_> = Vec::new(); - let mut i = 0; - let mut allow_default = true; - loop { - match load_sound_file_part_and_upload_ex( - sound_mt, - &files, - default_files, - ninja_name, - &["audio"], - &format!("hit{}", i + 1), - allow_default, - ) { - Ok(sound) => { - allow_default &= sound.from_default; - sounds.push(sound.mem); - } - Err(err) => { - if i == 0 { - return Err(err); - } else { - break; - } - } - } - i += 1; - } - sounds - }, + )?, + attacks: load_sound_file_part_list_and_upload( + sound_mt, + &files, + default_files, + ninja_name, + &["audio"], + "attack", + )?, + hits: load_sound_file_part_list_and_upload( + sound_mt, + &files, + default_files, + ninja_name, + &["audio"], + "hit", + )?, ninja_name: ninja_name.to_string(), }) } @@ -248,8 +179,16 @@ impl ContainerLoad for LoadNinja { skin: self.skin.convert(texture_handle, sound_object_handle), - spawn: sound_object_handle.create(self.spawn), - collect: sound_object_handle.create(self.collect), + spawn: self + .spawn + .into_iter() + .map(|obj| sound_object_handle.create(obj)) + .collect::>(), + collect: self + .collect + .into_iter() + .map(|obj| sound_object_handle.create(obj)) + .collect::>(), attacks: self .attacks .into_iter() diff --git a/game/client-containers/src/particles.rs b/game/client-containers/src/particles.rs index 57e1ad0..ddc739c 100644 --- a/game/client-containers/src/particles.rs +++ b/game/client-containers/src/particles.rs @@ -10,12 +10,12 @@ use math::math::RngSlice; use rustc_hash::FxHashMap; use sound::{sound_handle::SoundObjectHandle, sound_mt::SoundMultiThreaded}; -use crate::container::{load_file_part_and_upload_ex, ContainerLoadedItem, ContainerLoadedItemDir}; - -use super::container::{ - load_file_part_and_upload, Container, ContainerItemLoadData, ContainerLoad, +use crate::container::{ + load_file_part_list_and_upload, ContainerLoadedItem, ContainerLoadedItemDir, }; +use super::container::{Container, ContainerItemLoadData, ContainerLoad}; + #[derive(Debug, Hiarc, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum ParticleType { Slice, @@ -28,67 +28,75 @@ pub enum ParticleType { Hits, Stars, Snowflake, + Sparkle, } #[derive(Debug, Clone, Hiarc)] pub struct Particle { - pub slice: TextureContainer, - pub ball: TextureContainer, + pub slice: Vec, + pub ball: Vec, pub splats: Vec, - pub smoke: TextureContainer, - pub shell: TextureContainer, + pub smoke: Vec, + pub shell: Vec, pub explosions: Vec, - pub airjump: TextureContainer, + pub airjump: Vec, pub hits: Vec, pub stars: Vec, + pub snowflakes: Vec, + pub sparkle: Vec, } impl Particle { pub fn get_by_ty(&self, ty: ParticleType, rng_val: u64) -> &TextureContainer { let rng_val = rng_val as usize; match ty { - ParticleType::Slice => &self.slice, - ParticleType::Ball => &self.ball, + ParticleType::Slice => self.slice.random_val_entry(rng_val), + ParticleType::Ball => self.ball.random_val_entry(rng_val), ParticleType::Splats => self.splats.random_val_entry(rng_val), - ParticleType::Smoke => &self.smoke, - ParticleType::Shell => &self.shell, + ParticleType::Smoke => self.smoke.random_val_entry(rng_val), + ParticleType::Shell => self.shell.random_val_entry(rng_val), ParticleType::Explosions => self.explosions.random_val_entry(rng_val), - ParticleType::Airjump => &self.airjump, + ParticleType::Airjump => self.airjump.random_val_entry(rng_val), ParticleType::Hits => self.hits.random_val_entry(rng_val), ParticleType::Stars => self.stars.random_val_entry(rng_val), - ParticleType::Snowflake => todo!(), + ParticleType::Snowflake => self.snowflakes.random_val_entry(rng_val), + ParticleType::Sparkle => self.sparkle.random_val_entry(rng_val), } } pub fn len_by_ty(&self, ty: ParticleType) -> usize { match ty { - ParticleType::Slice => 1, - ParticleType::Ball => 1, + ParticleType::Slice => self.slice.len(), + ParticleType::Ball => self.ball.len(), ParticleType::Splats => self.splats.len(), - ParticleType::Smoke => 1, - ParticleType::Shell => 1, + ParticleType::Smoke => self.smoke.len(), + ParticleType::Shell => self.shell.len(), ParticleType::Explosions => self.explosions.len(), - ParticleType::Airjump => 1, + ParticleType::Airjump => self.airjump.len(), ParticleType::Hits => self.hits.len(), ParticleType::Stars => self.stars.len(), - ParticleType::Snowflake => 1, + ParticleType::Snowflake => self.snowflakes.len(), + ParticleType::Sparkle => self.sparkle.len(), } } } #[derive(Debug, Hiarc)] pub struct LoadParticle { - slice: ContainerItemLoadData, - ball: ContainerItemLoadData, + slice: Vec, + ball: Vec, splats: Vec, - smoke: ContainerItemLoadData, - shell: ContainerItemLoadData, + smoke: Vec, + shell: Vec, explosions: Vec, - airjump: ContainerItemLoadData, + airjump: Vec, hits: Vec, stars: Vec, + snowflakes: Vec, + sparkle: Vec, + particle_name: String, } @@ -109,22 +117,22 @@ impl LoadParticle { files.insert(format!("{}.png", name).into(), file); Ok(()) }; - insert_part("slice", converted.slice)?; - insert_part("ball", converted.ball)?; - for (index, part) in converted.splat.into_iter().enumerate() { - insert_part(&format!("splat{index}"), part)?; + insert_part("slice_001", converted.slice)?; + insert_part("ball_001", converted.ball)?; + for (i, part) in converted.splat.into_iter().enumerate() { + insert_part(&format!("splat_{:03}", i + 1), part)?; } - insert_part("smoke", converted.smoke)?; - insert_part("shell", converted.shell)?; + insert_part("smoke_001", converted.smoke)?; + insert_part("shell_001", converted.shell)?; - for (index, part) in converted.explosion.into_iter().enumerate() { - insert_part(&format!("explosion{index}"), part)?; + for (i, part) in converted.explosion.into_iter().enumerate() { + insert_part(&format!("explosion_{:03}", i + 1), part)?; } - insert_part("airjump", converted.airjump)?; + insert_part("airjump_001", converted.airjump)?; - for (index, part) in converted.hit.into_iter().enumerate() { - insert_part(&format!("hit{index}"), part)?; + for (i, part) in converted.hit.into_iter().enumerate() { + insert_part(&format!("hit_{:03}", i + 1), part)?; } Ok(()) @@ -142,177 +150,94 @@ impl LoadParticle { } Ok(Self { - slice: load_file_part_and_upload( + slice: load_file_part_list_and_upload( graphics_mt, files, default_files, particle_name, &[], "slice", - )? - .img, - ball: load_file_part_and_upload( + )?, + ball: load_file_part_list_and_upload( graphics_mt, files, default_files, particle_name, &[], "ball", - )? - .img, - splats: { - let mut textures = Vec::new(); - let mut i = 0; - let mut allow_default = true; - loop { - match load_file_part_and_upload_ex( - graphics_mt, - files, - default_files, - particle_name, - &[], - &format!("splat{i}"), - allow_default, - ) { - Ok(img) => { - allow_default &= img.from_default; - textures.push(img.img); - } - Err(err) => { - if i == 0 { - return Err(err); - } else { - break; - } - } - } - - i += 1; - } - textures - }, - - smoke: load_file_part_and_upload( + )?, + splats: load_file_part_list_and_upload( + graphics_mt, + files, + default_files, + particle_name, + &[], + "splat", + )?, + smoke: load_file_part_list_and_upload( graphics_mt, files, default_files, particle_name, &[], "smoke", - )? - .img, - shell: load_file_part_and_upload( + )?, + shell: load_file_part_list_and_upload( graphics_mt, files, default_files, particle_name, &[], "shell", - )? - .img, - - explosions: { - let mut textures = Vec::new(); - let mut i = 0; - let mut allow_default = true; - loop { - match load_file_part_and_upload_ex( - graphics_mt, - files, - default_files, - particle_name, - &[], - &format!("explosion{i}"), - allow_default, - ) { - Ok(img) => { - allow_default &= img.from_default; - textures.push(img.img); - } - Err(err) => { - if i == 0 { - return Err(err); - } else { - break; - } - } - } - - i += 1; - } - textures - }, - airjump: load_file_part_and_upload( + )?, + explosions: load_file_part_list_and_upload( + graphics_mt, + files, + default_files, + particle_name, + &[], + "explosion", + )?, + airjump: load_file_part_list_and_upload( graphics_mt, files, default_files, particle_name, &[], "airjump", - )? - .img, - hits: { - let mut textures = Vec::new(); - let mut i = 0; - let mut allow_default = true; - loop { - match load_file_part_and_upload_ex( - graphics_mt, - files, - default_files, - particle_name, - &[], - &format!("hit{i}"), - allow_default, - ) { - Ok(img) => { - allow_default &= img.from_default; - textures.push(img.img); - } - Err(err) => { - if i == 0 { - return Err(err); - } else { - break; - } - } - } - - i += 1; - } - textures - }, - stars: { - let mut textures = Vec::new(); - let mut i = 0; - let mut allow_default = true; - loop { - match load_file_part_and_upload_ex( - graphics_mt, - files, - default_files, - particle_name, - &[], - &format!("star{i}"), - allow_default, - ) { - Ok(img) => { - allow_default &= img.from_default; - textures.push(img.img); - } - Err(err) => { - if i == 0 { - return Err(err); - } else { - break; - } - } - } - - i += 1; - } - textures - }, + )?, + hits: load_file_part_list_and_upload( + graphics_mt, + files, + default_files, + particle_name, + &[], + "hit", + )?, + stars: load_file_part_list_and_upload( + graphics_mt, + files, + default_files, + particle_name, + &[], + "star", + )?, + snowflakes: load_file_part_list_and_upload( + graphics_mt, + files, + default_files, + particle_name, + &[], + "snowflake", + )?, + sparkle: load_file_part_list_and_upload( + graphics_mt, + files, + default_files, + particle_name, + &[], + "sparkle", + )?, particle_name: particle_name.to_string(), }) @@ -357,8 +282,16 @@ impl ContainerLoad for LoadParticle { _sound_object_handle: &SoundObjectHandle, ) -> Particle { Particle { - slice: Self::load_file_into_texture(texture_handle, self.slice, &self.particle_name), - ball: Self::load_file_into_texture(texture_handle, self.ball, &self.particle_name), + slice: self + .slice + .into_iter() + .map(|obj| Self::load_file_into_texture(texture_handle, obj, &self.particle_name)) + .collect(), + ball: self + .ball + .into_iter() + .map(|obj| Self::load_file_into_texture(texture_handle, obj, &self.particle_name)) + .collect(), splats: self .splats .into_iter() @@ -367,8 +300,16 @@ impl ContainerLoad for LoadParticle { }) .collect(), - smoke: Self::load_file_into_texture(texture_handle, self.smoke, &self.particle_name), - shell: Self::load_file_into_texture(texture_handle, self.shell, &self.particle_name), + smoke: self + .smoke + .into_iter() + .map(|obj| Self::load_file_into_texture(texture_handle, obj, &self.particle_name)) + .collect(), + shell: self + .shell + .into_iter() + .map(|obj| Self::load_file_into_texture(texture_handle, obj, &self.particle_name)) + .collect(), explosions: self .explosions .into_iter() @@ -376,11 +317,11 @@ impl ContainerLoad for LoadParticle { Self::load_file_into_texture(texture_handle, explosion, &self.particle_name) }) .collect(), - airjump: Self::load_file_into_texture( - texture_handle, - self.airjump, - &self.particle_name, - ), + airjump: self + .airjump + .into_iter() + .map(|obj| Self::load_file_into_texture(texture_handle, obj, &self.particle_name)) + .collect(), hits: self .hits .into_iter() @@ -391,6 +332,16 @@ impl ContainerLoad for LoadParticle { .into_iter() .map(|star| Self::load_file_into_texture(texture_handle, star, &self.particle_name)) .collect(), + snowflakes: self + .snowflakes + .into_iter() + .map(|obj| Self::load_file_into_texture(texture_handle, obj, &self.particle_name)) + .collect(), + sparkle: self + .sparkle + .into_iter() + .map(|obj| Self::load_file_into_texture(texture_handle, obj, &self.particle_name)) + .collect(), } } } diff --git a/game/client-containers/src/skins.rs b/game/client-containers/src/skins.rs index 3c352f5..4546e99 100644 --- a/game/client-containers/src/skins.rs +++ b/game/client-containers/src/skins.rs @@ -22,7 +22,7 @@ use sound::{ }; use crate::container::{ - load_sound_file_part_and_upload_ex, ContainerLoadedItem, ContainerLoadedItemDir, + load_sound_file_part_list_and_upload, ContainerLoadedItem, ContainerLoadedItemDir, }; use super::container::{load_file_part_as_png, Container, ContainerItemLoadData, ContainerLoad}; @@ -932,276 +932,78 @@ impl LoadSkin { grey_scaled_textures: grey_scaled_textures_data.load_into_texture(graphics_mt), sound: LoadSkinSounds { - ground_jump: { - let mut sounds = Vec::new(); - let mut i = 0; - let mut allow_default = true; - loop { - match load_sound_file_part_and_upload_ex( - sound_mt, - files, - default_files, - skin_name, - &[skin_extra_path.as_slice(), &["audio"]].concat(), - &format!("ground_jump{}", i + 1), - allow_default, - ) { - Ok(sound) => { - allow_default &= sound.from_default; - sounds.push(sound.mem); - } - Err(err) => { - if i == 0 { - return Err(err); - } else { - break; - } - } - } - i += 1; - } - sounds - }, - air_jump: { - let mut sounds = Vec::new(); - let mut i = 0; - let mut allow_default = true; - loop { - match load_sound_file_part_and_upload_ex( - sound_mt, - files, - default_files, - skin_name, - &[skin_extra_path.as_slice(), &["audio"]].concat(), - &format!("air_jump{}", i + 1), - allow_default, - ) { - Ok(sound) => { - allow_default &= sound.from_default; - sounds.push(sound.mem); - } - Err(err) => { - if i == 0 { - return Err(err); - } else { - break; - } - } - } - i += 1; - } - sounds - }, - spawn: { - let mut sounds = Vec::new(); - let mut i = 0; - let mut allow_default = true; - loop { - match load_sound_file_part_and_upload_ex( - sound_mt, - files, - default_files, - skin_name, - &[skin_extra_path.as_slice(), &["audio"]].concat(), - &format!("spawn{}", i + 1), - allow_default, - ) { - Ok(sound) => { - allow_default &= sound.from_default; - sounds.push(sound.mem); - } - Err(err) => { - if i == 0 { - return Err(err); - } else { - break; - } - } - } - i += 1; - } - sounds - }, - death: { - let mut sounds = Vec::new(); - let mut i = 0; - let mut allow_default = true; - loop { - match load_sound_file_part_and_upload_ex( - sound_mt, - files, - default_files, - skin_name, - &[skin_extra_path.as_slice(), &["audio"]].concat(), - &format!("death{}", i + 1), - allow_default, - ) { - Ok(sound) => { - allow_default &= sound.from_default; - sounds.push(sound.mem); - } - Err(err) => { - if i == 0 { - return Err(err); - } else { - break; - } - } - } - i += 1; - } - sounds - }, - pain_short: { - let mut sounds = Vec::new(); - let mut i = 0; - let mut allow_default = true; - loop { - match load_sound_file_part_and_upload_ex( - sound_mt, - files, - default_files, - skin_name, - &[skin_extra_path.as_slice(), &["audio"]].concat(), - &format!("pain_short{}", i + 1), - allow_default, - ) { - Ok(sound) => { - allow_default &= sound.from_default; - sounds.push(sound.mem); - } - Err(err) => { - if i == 0 { - return Err(err); - } else { - break; - } - } - } - i += 1; - } - sounds - }, - pain_long: { - let mut sounds = Vec::new(); - let mut i = 0; - let mut allow_default = true; - loop { - match load_sound_file_part_and_upload_ex( - sound_mt, - files, - default_files, - skin_name, - &[skin_extra_path.as_slice(), &["audio"]].concat(), - &format!("pain_long{}", i + 1), - allow_default, - ) { - Ok(sound) => { - allow_default &= sound.from_default; - sounds.push(sound.mem); - } - Err(err) => { - if i == 0 { - return Err(err); - } else { - break; - } - } - } - i += 1; - } - sounds - }, - hit_strong: { - let mut sounds = Vec::new(); - let mut i = 0; - let mut allow_default = true; - loop { - match load_sound_file_part_and_upload_ex( - sound_mt, - files, - default_files, - skin_name, - &[skin_extra_path.as_slice(), &["audio"]].concat(), - &format!("hit_strong{}", i + 1), - allow_default, - ) { - Ok(sound) => { - allow_default &= sound.from_default; - sounds.push(sound.mem); - } - Err(err) => { - if i == 0 { - return Err(err); - } else { - break; - } - } - } - i += 1; - } - sounds - }, - hit_weak: { - let mut sounds = Vec::new(); - let mut i = 0; - let mut allow_default = true; - loop { - match load_sound_file_part_and_upload_ex( - sound_mt, - files, - default_files, - skin_name, - &[skin_extra_path.as_slice(), &["audio"]].concat(), - &format!("hit_weak{}", i + 1), - allow_default, - ) { - Ok(sound) => { - allow_default &= sound.from_default; - sounds.push(sound.mem); - } - Err(err) => { - if i == 0 { - return Err(err); - } else { - break; - } - } - } - i += 1; - } - sounds - }, - skid: { - let mut sounds = Vec::new(); - let mut i = 0; - let mut allow_default = true; - loop { - match load_sound_file_part_and_upload_ex( - sound_mt, - files, - default_files, - skin_name, - &[skin_extra_path.as_slice(), &["audio"]].concat(), - &format!("skid{}", i + 1), - allow_default, - ) { - Ok(sound) => { - allow_default &= sound.from_default; - sounds.push(sound.mem); - } - Err(err) => { - if i == 0 { - return Err(err); - } else { - break; - } - } - } - i += 1; - } - sounds - }, + ground_jump: load_sound_file_part_list_and_upload( + sound_mt, + files, + default_files, + skin_name, + &[skin_extra_path.as_slice(), &["audio"]].concat(), + "ground_jump", + )?, + air_jump: load_sound_file_part_list_and_upload( + sound_mt, + files, + default_files, + skin_name, + &[skin_extra_path.as_slice(), &["audio"]].concat(), + "air_jump", + )?, + spawn: load_sound_file_part_list_and_upload( + sound_mt, + files, + default_files, + skin_name, + &[skin_extra_path.as_slice(), &["audio"]].concat(), + "spawn", + )?, + death: load_sound_file_part_list_and_upload( + sound_mt, + files, + default_files, + skin_name, + &[skin_extra_path.as_slice(), &["audio"]].concat(), + "death", + )?, + pain_short: load_sound_file_part_list_and_upload( + sound_mt, + files, + default_files, + skin_name, + &[skin_extra_path.as_slice(), &["audio"]].concat(), + "pain_short", + )?, + pain_long: load_sound_file_part_list_and_upload( + sound_mt, + files, + default_files, + skin_name, + &[skin_extra_path.as_slice(), &["audio"]].concat(), + "pain_long", + )?, + hit_strong: load_sound_file_part_list_and_upload( + sound_mt, + files, + default_files, + skin_name, + &[skin_extra_path.as_slice(), &["audio"]].concat(), + "hit_strong", + )?, + hit_weak: load_sound_file_part_list_and_upload( + sound_mt, + files, + default_files, + skin_name, + &[skin_extra_path.as_slice(), &["audio"]].concat(), + "hit_weak", + )?, + skid: load_sound_file_part_list_and_upload( + sound_mt, + files, + default_files, + skin_name, + &[skin_extra_path.as_slice(), &["audio"]].concat(), + "skid", + )?, }, skin_name: skin_name.to_string(), diff --git a/game/client-containers/src/weapons.rs b/game/client-containers/src/weapons.rs index 1f7cff7..10ca832 100644 --- a/game/client-containers/src/weapons.rs +++ b/game/client-containers/src/weapons.rs @@ -12,48 +12,71 @@ use sound::{ }; use crate::container::{ - load_file_part_and_upload_ex, load_sound_file_part_and_upload, - load_sound_file_part_and_upload_ex, ContainerLoadedItem, ContainerLoadedItemDir, + load_file_part_list_and_upload, load_sound_file_part_list_and_upload, ContainerLoadedItem, + ContainerLoadedItemDir, }; use super::container::{ load_file_part_and_upload, Container, ContainerItemLoadData, ContainerLoad, }; +#[derive(Debug, Hiarc, Clone)] +pub struct WeaponProjectile { + pub projectile: TextureContainer, +} + +#[derive(Debug, Hiarc, Clone)] +pub struct WeaponMuzzles { + pub muzzles: Vec, +} + #[derive(Debug, Hiarc, Clone)] pub struct Weapon { pub tex: TextureContainer, pub cursor: TextureContainer, - pub projectiles: Vec, - pub muzzles: Vec, pub fire: Vec, pub switch: Vec, pub noammo: Vec, } +#[derive(Debug, Hiarc, Clone)] +pub struct Gun { + pub weapon: Weapon, + + pub projectile: WeaponProjectile, + pub muzzles: WeaponMuzzles, +} + #[derive(Debug, Hiarc, Clone)] pub struct Grenade { pub weapon: Weapon, - pub spawn: SoundObject, - pub collect: SoundObject, + pub spawn: Vec, + pub collect: Vec, pub explosions: Vec, + + pub projectile: WeaponProjectile, } #[derive(Debug, Hiarc, Clone)] pub struct Laser { pub weapon: Weapon, - pub spawn: SoundObject, - pub collect: SoundObject, + pub spawn: Vec, + pub collect: Vec, pub bounces: Vec, pub heads: Vec, + + pub projectile: WeaponProjectile, } #[derive(Debug, Hiarc, Clone)] pub struct Shotgun { pub weapon: Weapon, - pub spawn: SoundObject, - pub collect: SoundObject, + pub spawn: Vec, + pub collect: Vec, + + pub projectile: WeaponProjectile, + pub muzzles: WeaponMuzzles, } #[derive(Debug, Hiarc, Clone)] @@ -65,7 +88,7 @@ pub struct Hammer { #[derive(Debug, Hiarc, Clone)] pub struct Weapons { pub hammer: Hammer, - pub gun: Weapon, + pub gun: Gun, pub shotgun: Shotgun, pub grenade: Grenade, pub laser: Laser, @@ -75,7 +98,7 @@ impl Weapons { pub fn by_type(&self, weapon: WeaponType) -> &Weapon { match weapon { WeaponType::Hammer => &self.hammer.weapon, - WeaponType::Gun => &self.gun, + WeaponType::Gun => &self.gun.weapon, WeaponType::Shotgun => &self.shotgun.weapon, WeaponType::Grenade => &self.grenade.weapon, WeaponType::Laser => &self.laser.weapon, @@ -83,12 +106,81 @@ impl Weapons { } } +#[derive(Debug, Hiarc)] +pub struct LoadProjectile { + projectile: ContainerItemLoadData, +} + +impl LoadProjectile { + pub fn new( + graphics_mt: &GraphicsMultiThreaded, + files: &ContainerLoadedItemDir, + default_files: &ContainerLoadedItemDir, + weapon_name: &str, + weapon_part: &str, + ) -> anyhow::Result { + Ok(Self { + projectile: load_file_part_and_upload( + graphics_mt, + files, + default_files, + weapon_name, + &[weapon_part], + "projectile", + )? + .img, + }) + } + + fn load(self, texture_handle: &GraphicsTextureHandle, name: &str) -> WeaponProjectile { + WeaponProjectile { + projectile: texture_handle + .load_texture_rgba_u8(self.projectile.data, name) + .unwrap(), + } + } +} + +#[derive(Debug, Hiarc)] +pub struct LoadMuzzles { + muzzles: Vec, +} + +impl LoadMuzzles { + pub fn new( + graphics_mt: &GraphicsMultiThreaded, + files: &ContainerLoadedItemDir, + default_files: &ContainerLoadedItemDir, + weapon_name: &str, + weapon_part: &str, + ) -> anyhow::Result { + Ok(Self { + muzzles: load_file_part_list_and_upload( + graphics_mt, + files, + default_files, + weapon_name, + &[weapon_part], + "muzzle", + )?, + }) + } + + fn load(self, texture_handle: &GraphicsTextureHandle, name: &str) -> WeaponMuzzles { + WeaponMuzzles { + muzzles: self + .muzzles + .into_iter() + .map(|v| texture_handle.load_texture_rgba_u8(v.data, name).unwrap()) + .collect(), + } + } +} + #[derive(Debug, Hiarc)] pub struct LoadWeapon { tex: ContainerItemLoadData, cursor_tex: ContainerItemLoadData, - projectiles: Vec, - muzzles: Vec, fire: Vec, switch: Vec, @@ -103,8 +195,6 @@ impl LoadWeapon { default_files: &ContainerLoadedItemDir, weapon_name: &str, weapon_part: &str, - has_projectiles: bool, - has_muzzle: bool, ) -> anyhow::Result { Ok(Self { // weapon @@ -128,163 +218,30 @@ impl LoadWeapon { )? .img, - projectiles: { - let mut textures = Vec::new(); - let mut i = 0; - let mut allow_default = true; - if has_projectiles { - loop { - match load_file_part_and_upload_ex( - graphics_mt, - files, - default_files, - weapon_name, - &[weapon_part], - &format!("projectile{i}"), - allow_default, - ) { - Ok(img) => { - allow_default &= img.from_default; - textures.push(img.img); - } - Err(err) => { - if i == 0 { - return Err(err); - } else { - break; - } - } - } - - i += 1; - } - } - textures - }, - muzzles: { - let mut textures = Vec::new(); - let mut i = 0; - let mut allow_default = true; - if has_muzzle { - loop { - match load_file_part_and_upload_ex( - graphics_mt, - files, - default_files, - weapon_name, - &[weapon_part], - &format!("muzzle{i}"), - allow_default, - ) { - Ok(img) => { - allow_default &= img.from_default; - textures.push(img.img); - } - Err(err) => { - if i == 0 { - return Err(err); - } else { - break; - } - } - } - - i += 1; - } - } - textures - }, - - fire: { - let mut sounds = Vec::new(); - let mut i = 0; - let mut allow_default = true; - loop { - match load_sound_file_part_and_upload_ex( - sound_mt, - files, - default_files, - weapon_name, - &[weapon_part], - &format!("fire{}", i + 1), - allow_default, - ) { - Ok(sound) => { - allow_default &= sound.from_default; - sounds.push(sound.mem); - } - Err(err) => { - if i == 0 { - return Err(err); - } else { - break; - } - } - } - i += 1; - } - sounds - }, - switch: { - let mut sounds = Vec::new(); - let mut i = 0; - let mut allow_default = true; - loop { - match load_sound_file_part_and_upload_ex( - sound_mt, - files, - default_files, - weapon_name, - &[weapon_part], - &format!("switch{}", i + 1), - allow_default, - ) { - Ok(sound) => { - allow_default &= sound.from_default; - sounds.push(sound.mem); - } - Err(err) => { - if i == 0 { - return Err(err); - } else { - break; - } - } - } - i += 1; - } - sounds - }, - noammo: { - let mut sounds = Vec::new(); - let mut i = 0; - let mut allow_default = true; - loop { - match load_sound_file_part_and_upload_ex( - sound_mt, - files, - default_files, - weapon_name, - &[weapon_part], - &format!("noammo{}", i + 1), - allow_default, - ) { - Ok(sound) => { - allow_default &= sound.from_default; - sounds.push(sound.mem); - } - Err(err) => { - if i == 0 { - return Err(err); - } else { - break; - } - } - } - i += 1; - } - sounds - }, + fire: load_sound_file_part_list_and_upload( + sound_mt, + files, + default_files, + weapon_name, + &[weapon_part], + "fire", + )?, + switch: load_sound_file_part_list_and_upload( + sound_mt, + files, + default_files, + weapon_name, + &[weapon_part], + "switch", + )?, + noammo: load_sound_file_part_list_and_upload( + sound_mt, + files, + default_files, + weapon_name, + &[weapon_part], + "noammo", + )?, }) } @@ -305,16 +262,6 @@ impl LoadWeapon { Weapon { tex: Self::load_file_into_texture(texture_handle, file.tex, name), cursor: Self::load_file_into_texture(texture_handle, file.cursor_tex, name), - projectiles: file - .projectiles - .into_iter() - .map(|file| Self::load_file_into_texture(texture_handle, file, name)) - .collect(), - muzzles: file - .muzzles - .into_iter() - .map(|file| Self::load_file_into_texture(texture_handle, file, name)) - .collect(), fire: file .fire @@ -335,13 +282,54 @@ impl LoadWeapon { } } +#[derive(Debug, Hiarc)] +pub struct LoadGun { + weapon: LoadWeapon, + + projectile: LoadProjectile, + muzzles: LoadMuzzles, +} + +impl LoadGun { + pub fn new( + graphics_mt: &GraphicsMultiThreaded, + sound_mt: &SoundMultiThreaded, + files: &ContainerLoadedItemDir, + default_files: &ContainerLoadedItemDir, + weapon_name: &str, + weapon_part: &str, + ) -> anyhow::Result { + Ok(Self { + weapon: LoadWeapon::new( + graphics_mt, + sound_mt, + files, + default_files, + weapon_name, + weapon_part, + )?, + + projectile: LoadProjectile::new( + graphics_mt, + files, + default_files, + weapon_name, + weapon_part, + )?, + muzzles: LoadMuzzles::new(graphics_mt, files, default_files, weapon_name, weapon_part)?, + }) + } +} + #[derive(Debug, Hiarc)] pub struct LoadGrenade { weapon: LoadWeapon, - spawn: SoundBackendMemory, - collect: SoundBackendMemory, + spawn: Vec, + collect: Vec, explosions: Vec, + + projectile: LoadProjectile, } impl LoadGrenade { @@ -352,8 +340,6 @@ impl LoadGrenade { default_files: &ContainerLoadedItemDir, weapon_name: &str, weapon_part: &str, - has_projectile: bool, - has_muzzle: bool, ) -> anyhow::Result { Ok(Self { weapon: LoadWeapon::new( @@ -363,60 +349,42 @@ impl LoadGrenade { default_files, weapon_name, weapon_part, - has_projectile, - has_muzzle, )?, - explosions: { - let mut sounds = Vec::new(); - let mut i = 0; - let mut allow_default = true; - loop { - match load_sound_file_part_and_upload_ex( - sound_mt, - files, - default_files, - weapon_name, - &[weapon_part], - &format!("explosion{}", i + 1), - allow_default, - ) { - Ok(sound) => { - allow_default &= sound.from_default; - sounds.push(sound.mem); - } - Err(err) => { - if i == 0 { - return Err(err); - } else { - break; - } - } - } - i += 1; - } - sounds - }, + explosions: load_sound_file_part_list_and_upload( + sound_mt, + files, + default_files, + weapon_name, + &[weapon_part], + "explosion", + )?, - spawn: load_sound_file_part_and_upload( + spawn: load_sound_file_part_list_and_upload( sound_mt, files, default_files, weapon_name, &[weapon_part], "spawn", - )? - .mem, + )?, - collect: load_sound_file_part_and_upload( + collect: load_sound_file_part_list_and_upload( sound_mt, files, default_files, weapon_name, &[weapon_part], "collect", - )? - .mem, + )?, + + projectile: LoadProjectile::new( + graphics_mt, + files, + default_files, + weapon_name, + weapon_part, + )?, }) } } @@ -425,10 +393,12 @@ impl LoadGrenade { pub struct LoadLaser { weapon: LoadWeapon, - spawn: SoundBackendMemory, - collect: SoundBackendMemory, + spawn: Vec, + collect: Vec, bounces: Vec, heads: Vec, + + projectile: LoadProjectile, } impl LoadLaser { @@ -439,8 +409,6 @@ impl LoadLaser { default_files: &ContainerLoadedItemDir, weapon_name: &str, weapon_part: &str, - has_projectile: bool, - has_muzzle: bool, ) -> anyhow::Result { Ok(Self { weapon: LoadWeapon::new( @@ -450,92 +418,51 @@ impl LoadLaser { default_files, weapon_name, weapon_part, - has_projectile, - has_muzzle, )?, - bounces: { - let mut sounds = Vec::new(); - let mut i = 0; - let mut allow_default = true; - loop { - match load_sound_file_part_and_upload_ex( - sound_mt, - files, - default_files, - weapon_name, - &[weapon_part], - &format!("bounce{}", i + 1), - allow_default, - ) { - Ok(sound) => { - allow_default &= sound.from_default; - sounds.push(sound.mem); - } - Err(err) => { - if i == 0 { - return Err(err); - } else { - break; - } - } - } - i += 1; - } - sounds - }, + bounces: load_sound_file_part_list_and_upload( + sound_mt, + files, + default_files, + weapon_name, + &[weapon_part], + "bounce", + )?, - spawn: load_sound_file_part_and_upload( + spawn: load_sound_file_part_list_and_upload( sound_mt, files, default_files, weapon_name, &[weapon_part], "spawn", - )? - .mem, + )?, - collect: load_sound_file_part_and_upload( + collect: load_sound_file_part_list_and_upload( sound_mt, files, default_files, weapon_name, &[weapon_part], "collect", - )? - .mem, - - heads: { - let mut textures: Vec = Default::default(); - let mut i = 0; - let mut allow_default = true; - loop { - match load_file_part_and_upload_ex( - graphics_mt, - files, - default_files, - weapon_name, - &[weapon_part], - &format!("splat{}", i + 1), - allow_default, - ) { - Ok(img) => { - allow_default &= img.from_default; - textures.push(img.img); - } - Err(err) => { - if i == 0 { - return Err(err); - } else { - break; - } - } - } - - i += 1; - } - textures - }, + )?, + + heads: load_file_part_list_and_upload( + graphics_mt, + files, + default_files, + weapon_name, + &[weapon_part], + "bounce", + )?, + + projectile: LoadProjectile::new( + graphics_mt, + files, + default_files, + weapon_name, + weapon_part, + )?, }) } } @@ -544,8 +471,11 @@ impl LoadLaser { pub struct LoadShotgun { weapon: LoadWeapon, - spawn: SoundBackendMemory, - collect: SoundBackendMemory, + projectile: LoadProjectile, + muzzles: LoadMuzzles, + + spawn: Vec, + collect: Vec, } impl LoadShotgun { @@ -556,8 +486,6 @@ impl LoadShotgun { default_files: &ContainerLoadedItemDir, weapon_name: &str, weapon_part: &str, - has_projectiles: bool, - has_muzzle: bool, ) -> anyhow::Result { Ok(Self { weapon: LoadWeapon::new( @@ -567,29 +495,34 @@ impl LoadShotgun { default_files, weapon_name, weapon_part, - has_projectiles, - has_muzzle, )?, - spawn: load_sound_file_part_and_upload( + spawn: load_sound_file_part_list_and_upload( sound_mt, files, default_files, weapon_name, &[weapon_part], "spawn", - )? - .mem, + )?, - collect: load_sound_file_part_and_upload( + collect: load_sound_file_part_list_and_upload( sound_mt, files, default_files, weapon_name, &[weapon_part], "collect", - )? - .mem, + )?, + + projectile: LoadProjectile::new( + graphics_mt, + files, + default_files, + weapon_name, + weapon_part, + )?, + muzzles: LoadMuzzles::new(graphics_mt, files, default_files, weapon_name, weapon_part)?, }) } } @@ -609,8 +542,6 @@ impl LoadHammer { default_files: &ContainerLoadedItemDir, weapon_name: &str, weapon_part: &str, - has_projectile: bool, - has_muzzle: bool, ) -> anyhow::Result { Ok(Self { weapon: LoadWeapon::new( @@ -620,40 +551,16 @@ impl LoadHammer { default_files, weapon_name, weapon_part, - has_projectile, - has_muzzle, )?, - hits: { - let mut sounds = Vec::new(); - let mut i = 0; - let mut allow_default = true; - loop { - match load_sound_file_part_and_upload_ex( - sound_mt, - files, - default_files, - weapon_name, - &[weapon_part], - &format!("hit{}", i + 1), - allow_default, - ) { - Ok(sound) => { - allow_default &= sound.from_default; - sounds.push(sound.mem); - } - Err(err) => { - if i == 0 { - return Err(err); - } else { - break; - } - } - } - i += 1; - } - sounds - }, + hits: load_sound_file_part_list_and_upload( + sound_mt, + files, + default_files, + weapon_name, + &[weapon_part], + "hit", + )?, }) } } @@ -661,7 +568,7 @@ impl LoadHammer { #[derive(Debug, Hiarc)] pub struct LoadWeapons { hammer: LoadHammer, - gun: LoadWeapon, + gun: LoadGun, shotgun: LoadShotgun, grenade: LoadGrenade, laser: LoadLaser, @@ -686,19 +593,15 @@ impl LoadWeapons { default_files, weapon_name, "hammer", - false, - false, )?, // gun - gun: LoadWeapon::new( + gun: LoadGun::new( graphics_mt, sound_mt, &files, default_files, weapon_name, "gun", - true, - true, )?, // shotgun shotgun: LoadShotgun::new( @@ -708,8 +611,6 @@ impl LoadWeapons { default_files, weapon_name, "shotgun", - true, - true, )?, // grenade grenade: LoadGrenade::new( @@ -719,8 +620,6 @@ impl LoadWeapons { default_files, weapon_name, "grenade", - true, - false, )?, // laser laser: LoadLaser::new( @@ -730,8 +629,6 @@ impl LoadWeapons { default_files, weapon_name, "laser", - true, - false, )?, weapon_name: weapon_name.to_string(), @@ -758,12 +655,16 @@ impl LoadWeapons { .map(|hammer| sound_object_handle.create(hammer)) .collect::>(), }, - gun: LoadWeapon::load_files_into_objects( - texture_handle, - sound_object_handle, - self.gun, - &self.weapon_name, - ), + gun: Gun { + weapon: LoadWeapon::load_files_into_objects( + texture_handle, + sound_object_handle, + self.gun.weapon, + &self.weapon_name, + ), + projectile: self.gun.projectile.load(texture_handle, &self.weapon_name), + muzzles: self.gun.muzzles.load(texture_handle, &self.weapon_name), + }, shotgun: Shotgun { weapon: LoadWeapon::load_files_into_objects( texture_handle, @@ -771,8 +672,24 @@ impl LoadWeapons { self.shotgun.weapon, &self.weapon_name, ), - spawn: sound_object_handle.create(self.shotgun.spawn), - collect: sound_object_handle.create(self.shotgun.collect), + spawn: self + .shotgun + .spawn + .into_iter() + .map(|s| sound_object_handle.create(s)) + .collect(), + collect: self + .shotgun + .collect + .into_iter() + .map(|s| sound_object_handle.create(s)) + .collect(), + + projectile: self + .shotgun + .projectile + .load(texture_handle, &self.weapon_name), + muzzles: self.shotgun.muzzles.load(texture_handle, &self.weapon_name), }, grenade: Grenade { weapon: LoadWeapon::load_files_into_objects( @@ -781,14 +698,28 @@ impl LoadWeapons { self.grenade.weapon, &self.weapon_name, ), - spawn: sound_object_handle.create(self.grenade.spawn), - collect: sound_object_handle.create(self.grenade.collect), + spawn: self + .grenade + .spawn + .into_iter() + .map(|s| sound_object_handle.create(s)) + .collect(), + collect: self + .grenade + .collect + .into_iter() + .map(|s| sound_object_handle.create(s)) + .collect(), explosions: self .grenade .explosions .into_iter() .map(|bounce| sound_object_handle.create(bounce)) .collect::>(), + projectile: self + .grenade + .projectile + .load(texture_handle, &self.weapon_name), }, laser: Laser { weapon: LoadWeapon::load_files_into_objects( @@ -797,8 +728,18 @@ impl LoadWeapons { self.laser.weapon, &self.weapon_name, ), - spawn: sound_object_handle.create(self.laser.spawn), - collect: sound_object_handle.create(self.laser.collect), + spawn: self + .laser + .spawn + .into_iter() + .map(|s| sound_object_handle.create(s)) + .collect(), + collect: self + .laser + .collect + .into_iter() + .map(|s| sound_object_handle.create(s)) + .collect(), bounces: self .laser .bounces @@ -811,6 +752,10 @@ impl LoadWeapons { .into_iter() .map(|head| LoadWeapon::load_file_into_texture(texture_handle, head, "head")) .collect::>(), + projectile: self + .laser + .projectile + .load(texture_handle, &self.weapon_name), }, } } diff --git a/game/client-extra/src/extra_split.rs b/game/client-extra/src/extra_split.rs new file mode 100644 index 0000000..af4e427 --- /dev/null +++ b/game/client-extra/src/extra_split.rs @@ -0,0 +1,81 @@ +use anyhow::anyhow; + +#[derive(Debug, Clone)] +pub struct Extras06Part { + pub data: Vec, + pub width: u32, + pub height: u32, +} + +impl Extras06Part { + fn new(data: Vec, width: usize, height: usize) -> Self { + Self { + data, + width: width as u32, + height: height as u32, + } + } +} + +#[derive(Debug)] +pub struct Extras06ConvertResult { + pub snowflake: Extras06Part, + pub sparkle: Extras06Part, +} + +fn single_img( + file: &[u8], + x: usize, + y: usize, + sub_width: usize, + sub_height: usize, + pitch: usize, +) -> Extras06Part { + let mut res: Vec = Default::default(); + + let in_line = file.split_at(y * pitch).1.split_at(sub_height * pitch).0; + in_line.chunks(pitch).for_each(|chunk| { + res.extend(chunk.split_at(x * 4).1.split_at(sub_width * 4).0); + }); + + Extras06Part::new(res, sub_width, sub_height) +} + +/// Splits the extras.png into its individual components. +/// +/// The width has to be divisible by 16 +/// and the height by 16. +pub fn split_06_extras( + file: &[u8], + width: u32, + height: u32, +) -> anyhow::Result { + if width % 16 != 0 { + Err(anyhow!("width is not divisible by 16")) + } else if height % 16 != 0 { + Err(anyhow!("height is not divisible by 16")) + } else { + let full_width = width as usize * 4; // * 4 for RGBA + let segment_width = width as usize / 16; + let segment_height = height as usize / 16; + + let snowflake = single_img( + file, + 0 * segment_width, + 0 * segment_height, + 2 * segment_width, + 2 * segment_height, + full_width, + ); + let sparkle = single_img( + file, + 2 * segment_width, + 0 * segment_height, + 2 * segment_width, + 2 * segment_height, + full_width, + ); + + Ok(Extras06ConvertResult { snowflake, sparkle }) + } +} diff --git a/game/client-extra/src/lib.rs b/game/client-extra/src/lib.rs index 645de5f..8b71db6 100644 --- a/game/client-extra/src/lib.rs +++ b/game/client-extra/src/lib.rs @@ -2,6 +2,7 @@ #![allow(clippy::identity_op)] pub mod ddrace_hud_split; pub mod emoticon_split; +pub mod extra_split; pub mod game_split; pub mod particles_split; pub mod skin_split; diff --git a/game/client-render-base/src/render/toolkit.rs b/game/client-render-base/src/render/toolkit.rs index 9ef7e9f..29d4c8c 100644 --- a/game/client-render-base/src/render/toolkit.rs +++ b/game/client-render-base/src/render/toolkit.rs @@ -364,13 +364,7 @@ impl ToolkitRender { quad_scope: DrawScope<4>, ) { // normal weapons - let texture = match weapon_type { - WeaponType::Hammer => &weapons.hammer.weapon.tex, - WeaponType::Gun => &weapons.gun.tex, - WeaponType::Shotgun => &weapons.shotgun.weapon.tex, - WeaponType::Grenade => &weapons.grenade.weapon.tex, - WeaponType::Laser => &weapons.laser.weapon.tex, - }; + let texture = &weapons.by_type(*weapon_type).tex; let quad_offset = if cursor_dir.x >= 0.0 { self.weapon_quad_offsets[*weapon_type as usize].0 @@ -493,12 +487,12 @@ impl ToolkitRender { // muzzle if weapon is firing if current_weapon == WeaponType::Gun || current_weapon == WeaponType::Shotgun { // check if we're firing stuff - let (weapon, spec) = if current_weapon == WeaponType::Gun { - (&weapons.gun, WeaponGunSpec::get()) + let (muzzles, spec) = if current_weapon == WeaponType::Gun { + (&weapons.gun.muzzles.muzzles, WeaponGunSpec::get()) } else { - (&weapons.shotgun.weapon, WeaponShotgunSpec::get()) + (&weapons.shotgun.muzzles.muzzles, WeaponShotgunSpec::get()) }; - if !weapon.muzzles.is_empty() { + if !muzzles.is_empty() { let mut alpha_muzzle = 0.0; let muzzle_duration = 8.0 / 5.0; // TODO: move this into the weapon spec let attack_time = attack_time @@ -521,7 +515,7 @@ impl ToolkitRender { let muzzle_pos = weapon_pos + dir * spec.muzzle_offset_x + muzzle_dir_y * pos_offset_y; - let texture = weapon.muzzles.random_entry(&mut self.rng); + let texture = muzzles.random_entry(&mut self.rng); self.quad_container.render_quad_container_as_sprite( quad_offset, diff --git a/game/client-render-game/src/components/game_objects.rs b/game/client-render-game/src/components/game_objects.rs index 3bcdb2b..59d3737 100644 --- a/game/client-render-game/src/components/game_objects.rs +++ b/game/client-render-game/src/components/game_objects.rs @@ -230,9 +230,9 @@ impl GameObjectsRender { } let texture = match ty { - WeaponWithProjectile::Gun => &weapon.gun.projectiles[0], - WeaponWithProjectile::Shotgun => &weapon.shotgun.weapon.projectiles[0], - WeaponWithProjectile::Grenade => &weapon.grenade.weapon.projectiles[0], + WeaponWithProjectile::Gun => &weapon.gun.projectile.projectile, + WeaponWithProjectile::Shotgun => &weapon.shotgun.projectile.projectile, + WeaponWithProjectile::Grenade => &weapon.grenade.projectile.projectile, }; quad_scope.set_colors_from_single(1.0, 1.0, 1.0, phased_alpha); self.items_quad_container.render_quad_container_as_sprite( diff --git a/game/client-render-game/src/components/hud.rs b/game/client-render-game/src/components/hud.rs index 48826cf..db42bc8 100644 --- a/game/client-render-game/src/components/hud.rs +++ b/game/client-render-game/src/components/hud.rs @@ -32,7 +32,7 @@ use graphics::{ streaming::quad_scope_begin, }; use graphics_types::rendering::State; -use math::math::{vector::vec2, Rng, RngSlice, PI}; +use math::math::{vector::vec2, PI}; use ui_base::ui::UiCreator; use vanilla::weapons::definitions::weapon_def::{get_weapon_sprite_scale, get_weapon_visual_scale}; @@ -93,8 +93,6 @@ pub struct RenderHud { ddrace_offsets: RenderOffsetsDdrace, canvas_handle: GraphicsCanvasHandle, - - rng: Rng, } impl RenderHud { @@ -359,8 +357,6 @@ impl RenderHud { canvas_handle: graphics.canvas_handle.clone(), - rng: Rng::new(0), - ui: HudRender::new(graphics, creator), } } @@ -429,10 +425,21 @@ impl RenderHud { ); // render ammo - let weapon = weapons.by_type(cur_weapon); - if !weapon.projectiles.is_empty() && info.ammo_of_weapon.is_some() { + let projectile = match cur_weapon { + WeaponType::Hammer => None, + WeaponType::Gun => Some(&weapons.gun.projectile), + WeaponType::Shotgun => Some(&weapons.shotgun.projectile), + WeaponType::Grenade => Some(&weapons.grenade.projectile), + WeaponType::Laser => Some(&weapons.laser.projectile), + }; + if let Some(projectile) = info + .ammo_of_weapon + .is_some() + .then_some(projectile) + .flatten() + { let cur_ammo_of_weapon = info.ammo_of_weapon.unwrap().min(10) as usize; - let texture = weapon.projectiles.random_entry(&mut self.rng); + let texture = &projectile.projectile; self.quad_container.render_quad_container( self.vanilla_offsets.weapon_ammo_offsets[cur_weapon as usize], &QuadContainerRenderCount::Count(cur_ammo_of_weapon), diff --git a/game/client-render-game/src/render_game.rs b/game/client-render-game/src/render_game.rs index 5d20740..67b9821 100644 --- a/game/client-render-game/src/render_game.rs +++ b/game/client-render-game/src/render_game.rs @@ -1329,6 +1329,7 @@ impl RenderGame { .weapon_container .get_or_default_opt(info.map(|i| &i.weapon)) .gun + .weapon .fire .random_entry(&mut self.rng) .play( @@ -1568,6 +1569,7 @@ impl RenderGame { .ninja_container .get_or_default_opt(info.map(|i| &i.ninja)) .spawn + .random_entry(&mut self.rng) .play( SoundPlayProps::new_with_pos_opt(pos) .with_with_spatial(settings.spatial_sound) @@ -1581,6 +1583,7 @@ impl RenderGame { .ninja_container .get_or_default_opt(info.map(|i| &i.ninja)) .collect + .random_entry(&mut self.rng) .play( SoundPlayProps::new_with_pos_opt(pos) .with_with_spatial(settings.spatial_sound) @@ -1687,6 +1690,7 @@ impl RenderGame { .get_or_default_opt(info.map(|i| &i.weapon)) .grenade .spawn + .random_entry(&mut self.rng) .play( SoundPlayProps::new_with_pos_opt(pos) .with_with_spatial(settings.spatial_sound) @@ -1701,6 +1705,7 @@ impl RenderGame { .get_or_default_opt(info.map(|i| &i.weapon)) .grenade .collect + .random_entry(&mut self.rng) .play( SoundPlayProps::new_with_pos_opt(pos) .with_with_spatial(settings.spatial_sound) @@ -1757,6 +1762,7 @@ impl RenderGame { .get_or_default_opt(info.map(|i| &i.weapon)) .laser .spawn + .random_entry(&mut self.rng) .play( SoundPlayProps::new_with_pos_opt(pos) .with_with_spatial(settings.spatial_sound) @@ -1771,6 +1777,7 @@ impl RenderGame { .get_or_default_opt(info.map(|i| &i.weapon)) .laser .collect + .random_entry(&mut self.rng) .play( SoundPlayProps::new_with_pos_opt(pos) .with_with_spatial(settings.spatial_sound) @@ -1813,6 +1820,7 @@ impl RenderGame { .get_or_default_opt(info.map(|i| &i.weapon)) .shotgun .spawn + .random_entry(&mut self.rng) .play( SoundPlayProps::new_with_pos_opt(pos) .with_with_spatial(settings.spatial_sound) @@ -1827,6 +1835,7 @@ impl RenderGame { .get_or_default_opt(info.map(|i| &i.weapon)) .shotgun .collect + .random_entry(&mut self.rng) .play( SoundPlayProps::new_with_pos_opt(pos) .with_with_spatial(settings.spatial_sound) @@ -1938,7 +1947,8 @@ impl RenderGame { .game_container .get_or_default_opt(info.map(|i| &i.game)) .heart - .spawn + .spawns + .random_entry(&mut self.rng) .play( SoundPlayProps::new_with_pos_opt(pos) .with_with_spatial(settings.spatial_sound) @@ -1969,7 +1979,8 @@ impl RenderGame { .game_container .get_or_default_opt(info.map(|i| &i.game)) .shield - .spawn + .spawns + .random_entry(&mut self.rng) .play( SoundPlayProps::new_with_pos_opt(pos) .with_with_spatial(settings.spatial_sound) diff --git a/game/client-ui/src/main_menu/settings/player/assets/game.rs b/game/client-ui/src/main_menu/settings/player/assets/game.rs index abd4995..b0cba20 100644 --- a/game/client-ui/src/main_menu/settings/player/assets/game.rs +++ b/game/client-ui/src/main_menu/settings/player/assets/game.rs @@ -75,11 +75,6 @@ pub fn game_list( render_texture(&game.heart.tex, index); index += 1; render_texture(&game.shield.tex, index); - index += 1; - for tex in &game.stars { - render_texture(tex, index); - index += 1; - } }, |_, name| { next_name = Some(name.to_string()); diff --git a/game/client-ui/src/main_menu/settings/player/assets/particles.rs b/game/client-ui/src/main_menu/settings/player/assets/particles.rs index 92c953c..d66e710 100644 --- a/game/client-ui/src/main_menu/settings/player/assets/particles.rs +++ b/game/client-ui/src/main_menu/settings/player/assets/particles.rs @@ -65,29 +65,39 @@ pub fn particles_list( }; let mut index = 0; - render_texture(&particles.airjump, index); - index += 1; - render_texture(&particles.slice, index); - index += 1; - render_texture(&particles.ball, index); - index += 1; - for tex in &particles.splats { + for tex in particles.airjump.iter().take(2) { render_texture(tex, index); index += 1; } - render_texture(&particles.smoke, index); - index += 1; - render_texture(&particles.shell, index); - index += 1; - for tex in &particles.explosions { + for tex in particles.slice.iter().take(2) { render_texture(tex, index); index += 1; } - for tex in &particles.hits { + for tex in particles.ball.iter().take(2) { render_texture(tex, index); index += 1; } - for tex in &particles.stars { + for tex in particles.splats.iter().take(2) { + render_texture(tex, index); + index += 1; + } + for tex in particles.smoke.iter().take(2) { + render_texture(tex, index); + index += 1; + } + for tex in particles.shell.iter().take(2) { + render_texture(tex, index); + index += 1; + } + for tex in particles.explosions.iter().take(2) { + render_texture(tex, index); + index += 1; + } + for tex in particles.hits.iter().take(2) { + render_texture(tex, index); + index += 1; + } + for tex in particles.stars.iter().take(2) { render_texture(tex, index); index += 1; } diff --git a/src/extra-convert/Cargo.toml b/src/extra-convert/Cargo.toml new file mode 100644 index 0000000..0e542cb --- /dev/null +++ b/src/extra-convert/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "extra-convert" +version = "0.1.0" +edition = "2021" + +[dependencies] +client-extra = { path = "../../game/client-extra" } +image-utils = { path = "../../lib/image-utils" } + +clap = { version = "4.5.23", features = ["derive"] } +tar = "0.4.43" diff --git a/src/extra-convert/src/main.rs b/src/extra-convert/src/main.rs new file mode 100644 index 0000000..bcdbc01 --- /dev/null +++ b/src/extra-convert/src/main.rs @@ -0,0 +1,110 @@ +use std::{ + collections::HashMap, + path::{Path, PathBuf}, +}; + +use clap::Parser; +use client_extra::extra_split::Extras06Part; +use tar::Header; + +#[derive(Parser, Debug)] +#[command(author, version, about, long_about = None)] +struct Args { + /// file name of the extras + file: String, + /// output path (directory) + output: PathBuf, + /// Put the resulting assets into a tar archieve. + #[arg(short, long, default_value_t = false, action = clap::ArgAction::Set)] + tar: bool, +} + +struct TarFile { + file: tar::Builder>, +} + +enum WriteMode<'a> { + Tar(&'a mut HashMap), + Disk, +} + +fn new_tar() -> TarFile { + let mut builder = tar::Builder::new(Vec::new()); + builder.mode(tar::HeaderMode::Deterministic); + TarFile { file: builder } +} + +fn write_part(write_mode: &mut WriteMode<'_>, part: Extras06Part, output: &Path, name: &str) { + let png = image_utils::png::save_png_image(&part.data, part.width, part.height).unwrap(); + match write_mode { + WriteMode::Tar(files) => { + let tar = files + .entry(output.to_string_lossy().to_string()) + .or_insert_with(new_tar); + + let mut header = Header::new_gnu(); + header.set_cksum(); + header.set_size(png.len() as u64); + header.set_mode(0o644); + header.set_uid(1000); + header.set_gid(1000); + tar.file + .append_data( + &mut header, + format!("{name}.png"), + std::io::Cursor::new(&png), + ) + .unwrap(); + } + WriteMode::Disk => { + std::fs::write(output.join(format!("{name}.png")), png).unwrap(); + } + } +} + +fn main() { + let args = Args::parse(); + + let file = std::fs::read(args.file).unwrap(); + let mut mem: Vec = Default::default(); + let img: image_utils::png::PngResult<'_> = + image_utils::png::load_png_image_as_rgba(&file, |width, height, bytes_per_pixel| { + mem.resize(width * height * bytes_per_pixel, Default::default()); + &mut mem + }) + .unwrap(); + let converted = + client_extra::extra_split::split_06_extras(img.data, img.width, img.height).unwrap(); + + let mut tar_files: HashMap = Default::default(); + let mut write_mode = if args.tar { + WriteMode::Tar(&mut tar_files) + } else { + WriteMode::Disk + }; + + std::fs::create_dir_all(args.output.clone()).unwrap(); + + write_part( + &mut write_mode, + converted.snowflake, + &args.output, + "snowflake_001", + ); + write_part( + &mut write_mode, + converted.sparkle, + &args.output, + "sparkle_001", + ); + + for (name, file) in tar_files { + let tar_file = file.file.into_inner().unwrap(); + std::fs::write(format!("{name}.tar"), tar_file).unwrap_or_else(|err| { + panic!( + "failed to write tar file {name} in {:?}: {err}", + args.output + ) + }); + } +} diff --git a/src/game-convert/src/main.rs b/src/game-convert/src/main.rs index 5d1da54..ffa0eea 100644 --- a/src/game-convert/src/main.rs +++ b/src/game-convert/src/main.rs @@ -201,28 +201,28 @@ fn main() { converted.projectile_gun, &args.output, "weapons/default", - "gun/projectile0", + "gun/projectile", ); write_part( &mut write_mode, converted.projectile_shotgun, &args.output, "weapons/default", - "shotgun/projectile0", + "shotgun/projectile", ); write_part( &mut write_mode, converted.projectile_grenade, &args.output, "weapons/default", - "grenade/projectile0", + "grenade/projectile", ); write_part( &mut write_mode, converted.projectile_laser, &args.output, "weapons/default", - "laser/projectile0", + "laser/projectile", ); converted @@ -235,7 +235,7 @@ fn main() { muzzle, &args.output, "weapons/default", - &format!("gun/muzzle{index}"), + &format!("gun/muzzle_{:03}", index + 1), ) }); converted @@ -248,7 +248,7 @@ fn main() { muzzle, &args.output, "weapons/default", - &format!("shotgun/muzzle{index}"), + &format!("shotgun/muzzle_{:03}", index + 1), ) }); converted @@ -261,7 +261,7 @@ fn main() { muzzle, &args.output, "ninjas/default", - &format!("muzzle{index}"), + &format!("muzzle_{:03}", index + 1), ) }); if let Some(ninja_bar_full_left) = converted.ninja_bar_full_left { diff --git a/src/part-convert/src/main.rs b/src/part-convert/src/main.rs index ba4cdd8..fd86545 100644 --- a/src/part-convert/src/main.rs +++ b/src/part-convert/src/main.rs @@ -85,8 +85,8 @@ fn main() { std::fs::create_dir_all(args.output.clone()).unwrap(); - write_part(&mut write_mode, converted.slice, &args.output, "slice"); - write_part(&mut write_mode, converted.ball, &args.output, "ball"); + write_part(&mut write_mode, converted.slice, &args.output, "slice_001"); + write_part(&mut write_mode, converted.ball, &args.output, "ball_001"); converted .splat @@ -97,12 +97,12 @@ fn main() { &mut write_mode, splat, &args.output, - &format!("splat{index}"), + &format!("splat_{:03}", index + 1), ) }); - write_part(&mut write_mode, converted.smoke, &args.output, "smoke"); - write_part(&mut write_mode, converted.shell, &args.output, "shell"); + write_part(&mut write_mode, converted.smoke, &args.output, "smoke_001"); + write_part(&mut write_mode, converted.shell, &args.output, "shell_001"); converted .explosion @@ -113,18 +113,28 @@ fn main() { &mut write_mode, explosion, &args.output, - &format!("explosion{index}"), + &format!("explosion_{:03}", index + 1), ) }); - write_part(&mut write_mode, converted.airjump, &args.output, "airjump"); + write_part( + &mut write_mode, + converted.airjump, + &args.output, + "airjump_001", + ); converted .hit .into_iter() .enumerate() .for_each(|(index, hit)| { - write_part(&mut write_mode, hit, &args.output, &format!("hit{index}")) + write_part( + &mut write_mode, + hit, + &args.output, + &format!("hit_{:03}", index + 1), + ) }); for (name, file) in tar_files {