private static void ConvertAnimation(Stream animStream, string path, bool convertAnims, FindLogic.Combo.AnimationAsset animationInfo, bool scaleAnims) { var parsedAnimation = default(teAnimation); var priority = 100; try { parsedAnimation = new teAnimation(animStream, true); priority = parsedAnimation.Header.Priority; } catch (Exception) { Logger.Error("Combo", $"Unable to parse animation {animationInfo.GetName()}"); } string animationDirectory = Path.Combine(path, "Animations", priority.ToString()); if (convertAnims && parsedAnimation != null) { SEAnim seAnim = new SEAnim(parsedAnimation, scaleAnims); string animOutput = Path.Combine(animationDirectory, animationInfo.GetNameIndex() + "." + seAnim.Extension); CreateDirectoryFromFile(animOutput); using (Stream fileStream = new FileStream(animOutput, FileMode.Create)) { seAnim.Write(fileStream); } } else { animStream.Position = 0; string rawAnimOutput = Path.Combine(animationDirectory, $"{animationInfo.GetNameIndex()}.{teResourceGUID.Type(animationInfo.m_GUID):X3}"); CreateDirectoryFromFile(rawAnimOutput); using (Stream fileStream = new FileStream(rawAnimOutput, FileMode.Create)) { animStream.CopyTo(fileStream); } } }
public static void SaveAnimationEffectReference(string path, FindLogic.Combo.ComboInfo info, ulong animation, ulong model) { FindLogic.Combo.AnimationAsset animationInfo = info.m_animations[animation]; Effect.OverwatchAnimationEffectReference reference = new Effect.OverwatchAnimationEffectReference(info, animationInfo, model); string file = Path.Combine(path, Effect.OverwatchAnimationEffect.AnimationEffectDir, animationInfo.GetNameIndex() + $".{reference.Extension}"); CreateDirectoryFromFile(file); using (Stream outputStream = File.OpenWrite(file)) { reference.Write(outputStream); } }
protected void WriteEffect(BinaryWriter writer) { writer.Write("oweffect"); writer.Write(EffectVersionMajor); writer.Write(EffectVersionMinor); EffectParser.EffectInfo effect = EffectInfo.Effect; writer.Write(teResourceGUID.Index(effect.GUID)); writer.Write(effect.EffectLength); writer.Write(effect.DMCEs.Count); writer.Write(effect.CECEs.Count); writer.Write(effect.NECEs.Count); writer.Write(effect.RPCEs.Count); writer.Write(effect.FECEs.Count); writer.Write(effect.OSCEs.Count); writer.Write(effect.SVCEs.Count); foreach (EffectParser.DMCEInfo dmceInfo in effect.DMCEs) { WriteTime(writer, dmceInfo.PlaybackInfo); writer.Write(dmceInfo.Animation); writer.Write(dmceInfo.Material); writer.Write(dmceInfo.Model); FindLogic.Combo.ModelAsset modelInfo = Info.m_models[dmceInfo.Model]; writer.Write($"Models\\{modelInfo.GetName()}\\{modelInfo.GetNameIndex()}.owmdl"); if (dmceInfo.Animation == 0) { writer.Write("null"); } else { FindLogic.Combo.AnimationAsset animationInfo = Info.m_animations[dmceInfo.Animation]; writer.Write($"Models\\{modelInfo.GetName()}\\{OverwatchAnimationEffect.AnimationEffectDir}\\{animationInfo.GetNameIndex()}\\{animationInfo.GetNameIndex()}.owanim"); } } foreach (EffectParser.CECEInfo ceceInfo in effect.CECEs) { WriteTime(writer, ceceInfo.PlaybackInfo); writer.Write((byte)ceceInfo.Action); writer.Write(ceceInfo.Animation); writer.Write(ceceInfo.Identifier); writer.Write(teResourceGUID.Index(ceceInfo.Identifier)); if (ceceInfo.Animation != 0) { FindLogic.Combo.AnimationAsset animationInfo = Info.m_animations[ceceInfo.Animation]; writer.Write($"{OverwatchAnimationEffect.AnimationEffectDir}\\{animationInfo.GetNameIndex()}\\{animationInfo.GetNameIndex()}.owanim"); } else { writer.Write("null"); } } foreach (EffectParser.NECEInfo neceInfo in effect.NECEs) { WriteTime(writer, neceInfo.PlaybackInfo); writer.Write(neceInfo.GUID); writer.Write(teResourceGUID.Index(neceInfo.Identifier)); FindLogic.Combo.EntityAsset entityInfo = Info.m_entities[neceInfo.GUID]; writer.Write($"Entities\\{entityInfo.GetName()}\\{entityInfo.GetName()}.owentity"); } foreach (EffectParser.RPCEInfo rpceInfo in effect.RPCEs) { WriteTime(writer, rpceInfo.PlaybackInfo); writer.Write(rpceInfo.Model); // todo: make the materials work writer.Write(rpceInfo.Material); FindLogic.Combo.ModelAsset modelInfo = Info.m_models[rpceInfo.Model]; //writer.Write(rpceInfo.TextureDefiniton); writer.Write($"Models\\{modelInfo.GetName()}\\{modelInfo.GetName()}.owmdl"); } foreach (EffectParser.SVCEInfo svceInfo in effect.SVCEs) { WriteTime(writer, svceInfo.PlaybackInfo); writer.Write(teResourceGUID.Index(svceInfo.VoiceStimulus)); if (VoiceStimuli.ContainsKey(svceInfo.VoiceStimulus)) { HashSet <FindLogic.Combo.VoiceLineInstanceInfo> lines = VoiceStimuli[svceInfo.VoiceStimulus]; writer.Write(lines.Count); foreach (FindLogic.Combo.VoiceLineInstanceInfo voiceLineInstance in lines) { writer.Write(voiceLineInstance.SoundFiles.Count); foreach (ulong soundFile in voiceLineInstance.SoundFiles) { FindLogic.Combo.SoundFileAsset soundFileInfo = Info.m_voiceSoundFiles[soundFile]; writer.Write($"Sounds\\{soundFileInfo.GetNameIndex()}.ogg"); } } } else { writer.Write(0); } } }
public void Write(Stream stream) { using (BinaryWriter writer = new BinaryWriter(stream)) { writer.Write(Extension); // identifier writer.Write(OverwatchAnimationEffect.AnimVersionMajor); writer.Write(OverwatchAnimationEffect.AnimVersionMinor); writer.Write(teResourceGUID.Index(Animation.m_GUID)); writer.Write(Animation.m_fps); writer.Write((int)OverwatchAnimationEffect.OWAnimType.Reference); FindLogic.Combo.ModelAsset modelInfo = Info.m_models[Model]; writer.Write($"Models\\{modelInfo.GetName()}\\{OverwatchAnimationEffect.AnimationEffectDir}\\{Animation.GetNameIndex()}\\{Animation.GetNameIndex()}.{Extension}"); // so I can change it in DataTool and not go mad } }
public override void Write(Stream stream) { using (BinaryWriter writer = new BinaryWriter(stream)) { writer.Write(Extension); writer.Write(AnimVersionMajor); writer.Write(AnimVersionMinor); writer.Write(teResourceGUID.Index(Animation.m_GUID)); writer.Write(Animation.m_fps); writer.Write((int)OWAnimType.Data); FindLogic.Combo.ModelAsset modelInfo = Info.m_models[Model]; writer.Write($"Models\\{modelInfo.GetName()}\\Animations\\{Animation.m_priority}\\{Animation.GetNameIndex()}.seanim"); writer.Write($"Models\\{modelInfo.GetName()}\\{modelInfo.GetNameIndex()}.owmdl"); // wrap oweffect WriteEffect(writer); } }
private static void SaveAnimationTask(ICLIFlags flags, string path, SaveContext context, ulong animation, ulong model) { bool convertAnims = false; bool scaleAnims = false; if (flags is ExtractFlags extractFlags) { scaleAnims = extractFlags.ScaleAnims; convertAnims = !extractFlags.RawAnimations && !extractFlags.Raw; if (extractFlags.SkipAnimations) { return; } } FindLogic.Combo.AnimationAsset animationInfo = context.m_info.m_animations[animation]; using (Stream animStream = OpenFile(animation)) { if (animStream == null) { return; } ConvertAnimation(animStream, path, convertAnims, animationInfo, scaleAnims); } if (!context.m_saveAnimationEffects) { return; } FindLogic.Combo.EffectInfoCombo animationEffect; // just create a fake effect if it doesn't exist if (animationInfo.m_effect == 0) { animationEffect = new FindLogic.Combo.EffectInfoCombo(0) { Effect = new EffectParser.EffectInfo() }; animationEffect.Effect.SetupEffect(); } else if (context.m_info.m_effects.ContainsKey(animationInfo.m_effect)) { // wot, why animationEffect = context.m_info.m_effects[animationInfo.m_effect]; } else if (context.m_info.m_animationEffects.ContainsKey(animationInfo.m_effect)) { animationEffect = context.m_info.m_animationEffects[animationInfo.m_effect]; } else { return; } string animationEffectDir = Path.Combine(path, Effect.OverwatchAnimationEffect.AnimationEffectDir, animationInfo.GetNameIndex()); Dictionary <ulong, HashSet <FindLogic.Combo.VoiceLineInstanceInfo> > svceLines = new Dictionary <ulong, HashSet <FindLogic.Combo.VoiceLineInstanceInfo> >(); if (animationEffect.m_GUID != 0) { SaveEffectExtras(flags, animationEffectDir, context, animationEffect.Effect, out svceLines); } Effect.OverwatchAnimationEffect output = new Effect.OverwatchAnimationEffect(context.m_info, animationEffect, svceLines, animationInfo, model); string animationEffectFile = Path.Combine(animationEffectDir, $"{animationInfo.GetNameIndex()}.{output.Extension}"); CreateDirectoryFromFile(animationEffectFile); using (Stream fileStream = new FileStream(animationEffectFile, FileMode.Create)) { fileStream.SetLength(0); output.Write(fileStream); } }