diff --git a/src/main.rs b/src/main.rs
index 8dfd44a..bab609d 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1047,43 +1047,115 @@ fn write_attributes() -> AResult<()>{
 
 fn extract_textures(paths:Vec<std::path::PathBuf>,vpk_path:std::path::PathBuf)->AResult<()>{
 	let vpk_index=vpk::VPK::read(&vpk_path)?;
-	let mut deduplicate=std::collections::HashSet::new();
 	for path in paths{
+		let mut deduplicate=std::collections::HashSet::new();
 		let bsp=vbsp::Bsp::read(std::fs::read(path)?.as_ref())?;
 		for texture in bsp.textures(){
-			let texture_name=texture.texture_data().name();
-			let texture_file_name=format!("materials/{}.vtf",texture_name.to_lowercase());
-			if !deduplicate.insert(texture_file_name.clone()){
-				continue;
-			}
-			println!("texture_name={}",texture_file_name);
-			if let Some(stuff)=vpk_index.tree.get(texture_file_name.as_str()){
-				let image=vtf::from_bytes(&mut stuff.get()?.to_vec())?.highres_image.decode(0)?.to_rgba8();
-
-				let format=if image.width()%4!=0||image.height()%4!=0{
-					image_dds::ImageFormat::R8G8B8A8Srgb
-				}else{
-					image_dds::ImageFormat::BC7Srgb
-				};
-				//this fails if the image dimensions are not a multiple of 4
-				let dds = image_dds::dds_from_image(
-					&image,
-					format,
-					image_dds::Quality::Slow,
-					image_dds::Mipmaps::GeneratedAutomatic,
-				)?;
-
-				//write dds
-				let mut dest=std::path::PathBuf::from("textures/dds");
-				dest.push(texture_name);
-				dest.set_extension("dds");
-				std::fs::create_dir_all(dest.parent().unwrap())?;
-				let mut writer = std::io::BufWriter::new(std::fs::File::create(dest)?);
-				dds.write(&mut writer)?;
-			}else{
-				println!("nonadat");
-			}
+			deduplicate.insert(std::path::PathBuf::from(texture.name()));
 		}
+		let mut zippyt=bsp.pack.into_zip().into_inner().unwrap();
+		let tree=&vpk_index.tree;
+		std::thread::scope(move|s|{
+			for texture_name in deduplicate{
+				let mut texture_file_name=std::path::PathBuf::from("materials");
+				//lower case
+				let texture_file_name_lowercase=texture_name.to_string_lossy().to_lowercase();
+				texture_file_name.push(texture_file_name_lowercase.clone());
+				//remove stem and search for both vtf and vmt files
+				let stem=std::path::PathBuf::from(texture_file_name.file_stem().unwrap());
+				texture_file_name.pop();
+				texture_file_name.push(stem);
+				//somehow search for both files
+				let mut texture_file_name2=texture_file_name.clone();
+				texture_file_name.set_extension("vtf");
+				texture_file_name2.set_extension("vmt");
+				println!("texture_name={:?}",texture_file_name);
+				let mut found_texture=false;
+				//why can't I write a function for this without importing the ZipArchive lib
+				{
+	if let Some(mut stuff)=match (zippyt.by_name(texture_file_name.to_str().unwrap()),tree.get(texture_file_name.to_str().unwrap())){
+		(Ok(mut zip_file),None)=>{
+			let mut buf=Vec::new();
+			zip_file.read_to_end(&mut buf)?;
+			Some(buf)
+		},
+		(_,Some(vpk_entry))=>Some(vpk_entry.get()?.to_vec()),
+		_=>None,
+	}{
+		found_texture=true;
+		let texture_name=texture_name.clone();
+		s.spawn(move||{
+			let image=vtf::from_bytes(&mut stuff)?.highres_image.decode(0)?.to_rgba8();
+
+			let format=if image.width()%4!=0||image.height()%4!=0{
+				image_dds::ImageFormat::R8G8B8A8Srgb
+			}else{
+				image_dds::ImageFormat::BC7Srgb
+			};
+			//this fails if the image dimensions are not a multiple of 4
+			let dds = image_dds::dds_from_image(
+				&image,
+				format,
+				image_dds::Quality::Slow,
+				image_dds::Mipmaps::GeneratedAutomatic,
+			)?;
+
+			//write dds
+			let mut dest=std::path::PathBuf::from("textures/dds");
+			dest.push(texture_name);
+			dest.set_extension("dds");
+			std::fs::create_dir_all(dest.parent().unwrap())?;
+			let mut writer = std::io::BufWriter::new(std::fs::File::create(dest)?);
+			dds.write(&mut writer)?;
+			Ok::<(),anyhow::Error>(())
+		});
+	}
+				}
+				{
+	if let Some(mut stuff)=match (zippyt.by_name(texture_file_name2.to_str().unwrap()),tree.get(texture_file_name2.to_str().unwrap())){
+		(Ok(mut zip_file),None)=>{
+			let mut buf=Vec::new();
+			zip_file.read_to_end(&mut buf)?;
+			Some(buf)
+		},
+		(_,Some(vpk_entry))=>Some(vpk_entry.get()?.to_vec()),
+		_=>None,
+	}{
+		found_texture=true;
+		let texture_name=texture_name.clone();
+		s.spawn(move||{
+			let image=vtf::from_bytes(&mut stuff)?.highres_image.decode(0)?.to_rgba8();
+
+			let format=if image.width()%4!=0||image.height()%4!=0{
+				image_dds::ImageFormat::R8G8B8A8Srgb
+			}else{
+				image_dds::ImageFormat::BC7Srgb
+			};
+			//this fails if the image dimensions are not a multiple of 4
+			let dds = image_dds::dds_from_image(
+				&image,
+				format,
+				image_dds::Quality::Slow,
+				image_dds::Mipmaps::GeneratedAutomatic,
+			)?;
+
+			//write dds
+			let mut dest=std::path::PathBuf::from("textures/dds");
+			dest.push(texture_name);
+			dest.set_extension("dds");
+			std::fs::create_dir_all(dest.parent().unwrap())?;
+			let mut writer = std::io::BufWriter::new(std::fs::File::create(dest)?);
+			dds.write(&mut writer)?;
+			Ok::<(),anyhow::Error>(())
+		});
+	}
+				}
+				if !found_texture{
+					println!("no data");
+				}
+			}
+			Ok::<(),anyhow::Error>(())
+		})?
 	}
 	Ok(())
 }