public static void Save(ICLIFlags flags, string directory, DataModels.Unlock unlock, VoiceSet voiceSet) { if (voiceSet == null) { return; } if (!(unlock.STU is STUUnlock_VoiceLine vl)) { return; } HashSet <ulong> voiceLines = new HashSet <ulong>(); using (Stream vlStream = IO.OpenFile(vl.m_F57B051E)) { teChunkedData chunkedData = new teChunkedData(vlStream); foreach (teEffectComponentVoiceStimulus voiceStimulus in chunkedData.GetChunks <teEffectComponentVoiceStimulus>()) { if (voiceSet.Stimuli.TryGetValue(voiceStimulus.Header.VoiceStimulus, out var stimuliLines)) { foreach (var voiceLine in stimuliLines) { voiceLines.Add(voiceLine); } } } } SaveVoiceLines(flags, voiceLines, voiceSet, directory); }
private void SaveEffect(string dir, ulong guid) { using (Stream stream = OpenFile(guid)) { teChunkedData chunkedData = new teChunkedData(stream); ulong lastModel = 0; foreach (IChunk chunk in chunkedData.Chunks) { if (chunk is teEffectChunkShaderSetup shaderSetup) { //if (teResourceGUID.Index(lastModel) != 0x296B) continue; // the circle ExtractDebugShaders.SaveMaterial(dir, shaderSetup.Header.Material, GetFileName(guid)); } if (chunk is teEffectComponentParticle particle) { lastModel = particle.Header.Model; } else { lastModel = 0; } } foreach (teEffectComponentEntityControl entityControl in chunkedData.GetChunks <teEffectComponentEntityControl>()) { if (entityControl.Header.Animation == 0) { continue; } SaveAnimation(dir, entityControl.Header.Animation); } foreach (teEffectComponentModel model in chunkedData.GetChunks <teEffectComponentModel>()) { if (model.Header.Animation == 0) { continue; } SaveAnimation(dir, model.Header.Animation); } } }
public static void SaveModel(ICLIFlags flags, string path, SaveContext info, ulong modelGUID) { bool convertModels = true; bool doRefpose = false; bool doStu = false; byte lod = 1; if (flags is ExtractFlags extractFlags) { convertModels = !extractFlags.RawModels && !extractFlags.Raw; doRefpose = extractFlags.ExtractRefpose; doStu = extractFlags.ExtractModelStu; lod = extractFlags.LOD; if (extractFlags.SkipModels) { return; } } FindLogic.Combo.ModelAsset modelInfo = info.m_info.m_models[modelGUID]; string modelDirectory = Path.Combine(path, "Models", modelInfo.GetName()); if (convertModels) { string modelPath = Path.Combine(modelDirectory, $"{modelInfo.GetNameIndex()}.owmdl"); using (Stream modelStream = OpenFile(modelInfo.m_GUID)) { if (modelStream == null) { return; } CreateDirectoryFromFile(modelPath); teChunkedData chunkedData = new teChunkedData(modelStream); OverwatchModel model = new OverwatchModel(chunkedData, modelInfo.m_GUID, (sbyte)lod); if (modelInfo.m_modelLooks.Count > 0) { FindLogic.Combo.ModelLookAsset modelLookInfo = info.m_info.m_modelLooks[modelInfo.m_modelLooks.First()]; model.ModelLookFileName = Path.Combine("ModelLooks", modelLookInfo.GetNameIndex() + ".owmat"); } using (Stream fileStream = File.OpenWrite(modelPath)) { fileStream.SetLength(0); model.Write(fileStream); } if (doRefpose) { string refposePath = Path.Combine(modelDirectory, modelInfo.GetNameIndex() + ".smd"); using (Stream fileStream = File.OpenWrite(refposePath)) { fileStream.SetLength(0); var refpose = new RefPoseSkeleton(chunkedData); refpose.Write(fileStream); } } if (doStu) { var stu = chunkedData.GetChunks <teModelChunk_STU>().Select(x => x.StructuredData).ToArray(); string stuPath = Path.Combine(modelDirectory, modelInfo.GetNameIndex() + ".json"); JSONTool.OutputJSONAlt(stu, new ListFlags { Output = stuPath }, false); } } } else { using (Stream modelStream = OpenFile(modelInfo.m_GUID)) { WriteFile(modelStream, Path.Combine(modelDirectory, modelInfo.GetNameIndex() + ".00C")); } } foreach (ulong modelModelLook in modelInfo.m_modelLooks) { SaveModelLook(flags, modelDirectory, info, modelModelLook); } foreach (ulong looseMaterial in modelInfo.m_looseMaterials) { SaveMaterial(flags, modelDirectory, info, looseMaterial); } foreach (ulong modelAnimation in modelInfo.n_animations) { SaveAnimation(flags, modelDirectory, info, modelAnimation, modelGUID); } }