public OverwatchAnimationEffect(FindLogic.Combo.ComboInfo info, FindLogic.Combo.EffectInfoCombo animationEffect, Dictionary <ulong, HashSet <FindLogic.Combo.VoiceLineInstanceInfo> > voiceStimuli, FindLogic.Combo.AnimationInfoNew animation, ulong model) : base(info, animationEffect, voiceStimuli) { Animation = animation; Model = model; }
private static void SaveOWAnimFile(string animationEffectFile, FindLogic.Combo.EffectInfoCombo animationEffect, FindLogic.Combo.AnimationInfoNew animationInfo, FindLogic.Combo.ComboInfo info, Effect.OWAnimWriter owAnimWriter, ulong model, Dictionary <ulong, HashSet <FindLogic.Combo.VoiceLineInstanceInfo> > svceLines) { CreateDirectoryFromFile(animationEffectFile); using (Stream fileStream = new FileStream(animationEffectFile, FileMode.Create)) { fileStream.SetLength(0); owAnimWriter.Write(fileStream, info, animationInfo, animationEffect, model, svceLines); } }
public static void SaveAnimationEffectReference(ICLIFlags flags, string path, FindLogic.Combo.ComboInfo info, ulong animation, ulong model) { FindLogic.Combo.AnimationInfoNew animationInfo = info.Animations[animation]; Effect.OWAnimWriter animWriter = new Effect.OWAnimWriter(); string file = Path.Combine(path, Model.AnimationEffectDir, animationInfo.GetNameIndex() + animWriter.Format); CreateDirectoryFromFile(file); using (Stream outputStream = File.OpenWrite(file)) { animWriter.WriteReference(outputStream, info, animationInfo, model); } }
public static void SaveAnimationEffectReference(string path, FindLogic.Combo.ComboInfo info, ulong animation, ulong model) { FindLogic.Combo.AnimationInfoNew animationInfo = info.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); } }
public void Write(Stream output, FindLogic.Combo.ComboInfo info, FindLogic.Combo.AnimationInfoNew animation, FindLogic.Combo.EffectInfoCombo animationEffect, ulong model, Dictionary <ulong, HashSet <FindLogic.Combo.VoiceLineInstanceInfo> > svceLines) { using (BinaryWriter writer = new BinaryWriter(output)) { writer.Write(new string(Identifier)); writer.Write(VersionMajor); writer.Write(VersionMinor); writer.Write(GUID.Index(animation.GUID)); writer.Write(animation.FPS); writer.Write((int)OWAnimType.Data); FindLogic.Combo.ModelInfoNew modelInfo = info.Models[model]; writer.Write($"Models\\{modelInfo.GetName()}\\Animations\\{animation.Priority}\\{animation.GetNameIndex()}.seanim"); writer.Write($"Models\\{modelInfo.GetName()}\\{modelInfo.GetNameIndex()}.owmdl"); // wrap oweffect OWEffectWriter effectWriter = new OWEffectWriter(); effectWriter.Write(writer, animationEffect, info, svceLines); } }
private static void ConvertAnimation(Stream animStream, string path, bool convertAnims, FindLogic.Combo.AnimationInfoNew animationInfo) { teAnimation parsedAnimation = new teAnimation(animStream, true); string animationDirectory = Path.Combine(path, "Animations", parsedAnimation.Header.Priority.ToString()); if (convertAnims) { SEAnim seAnim = new SEAnim(parsedAnimation); string animOutput = Path.Combine(animationDirectory, animationInfo.GetNameIndex() + "." + seAnim.Extension); CreateDirectoryFromFile(animOutput); using (Stream fileStream = new FileStream(animOutput, FileMode.Create)) { seAnim.Write(fileStream); } } else { string rawAnimOutput = Path.Combine(animationDirectory, $"{animationInfo.GetNameIndex()}.{teResourceGUID.Type(animationInfo.GUID):X3}"); CreateDirectoryFromFile(rawAnimOutput); using (Stream fileStream = new FileStream(rawAnimOutput, FileMode.Create)) { animStream.CopyTo(fileStream); } } }
public static void SaveAnimation(ICLIFlags flags, string path, FindLogic.Combo.ComboInfo info, ulong animation, ulong model) { bool convertAnims = false; if (flags is ExtractFlags extractFlags) { convertAnims = extractFlags.ConvertAnimations && !extractFlags.Raw; if (extractFlags.SkipAnimations) { return; } } FindLogic.Combo.AnimationInfoNew animationInfo = info.Animations[animation]; using (Stream animStream = OpenFile(animation)) { if (animStream == null) { return; } ConvertAnimation(animStream, path, convertAnims, animationInfo); } if (!info.SaveConfig.SaveAnimationEffects) { return; } FindLogic.Combo.EffectInfoCombo animationEffect; // just create a fake effect if it doesn't exist if (animationInfo.Effect == 0) { animationEffect = new FindLogic.Combo.EffectInfoCombo(0) { Effect = new EffectParser.EffectInfo() }; animationEffect.Effect.SetupEffect(); } else if (info.Effects.ContainsKey(animationInfo.Effect)) { // wot, why animationEffect = info.Effects[animationInfo.Effect]; } else { animationEffect = info.AnimationEffects[animationInfo.Effect]; } 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.GUID != 0) { SaveEffectExtras(flags, animationEffectDir, info, animationEffect.Effect, out svceLines); } Effect.OverwatchAnimationEffect output = new Effect.OverwatchAnimationEffect(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); } }
public static void SaveAnimation(ICLIFlags flags, string path, FindLogic.Combo.ComboInfo info, ulong animation, ulong model) { bool convertAnims = false; if (flags is ExtractFlags extractFlags) { convertAnims = extractFlags.ConvertAnimations && !extractFlags.Raw; if (extractFlags.SkipAnimations) { return; } } SEAnimWriter animWriter = new SEAnimWriter(); FindLogic.Combo.AnimationInfoNew animationInfo = info.Animations[animation]; using (Stream animStream = OpenFile(animation)) { if (animStream == null) { return; } MemoryStream animMemStream = new MemoryStream(); animStream.CopyTo(animMemStream); if (info.SaveRuntimeData.Threads) { info.SaveRuntimeData.Tasks.Add(Task.Run(() => { ConvertAnimation(animMemStream, path, convertAnims, animWriter, animationInfo); })); } else { ConvertAnimation(animMemStream, path, convertAnims, animWriter, animationInfo); } } if (!info.SaveConfig.SaveAnimationEffects) { return; } FindLogic.Combo.EffectInfoCombo animationEffect; // just create a fake effect if it doesn't exist if (animationInfo.Effect == 0) { animationEffect = new FindLogic.Combo.EffectInfoCombo(0) { Effect = new EffectParser.EffectInfo() }; animationEffect.Effect.SetupEffect(); } else if (info.Effects.ContainsKey(animationInfo.Effect)) { // wot, why animationEffect = info.Effects[animationInfo.Effect]; } else { animationEffect = info.AnimationEffects[animationInfo.Effect]; } Effect.OWAnimWriter owAnimWriter = new Effect.OWAnimWriter(); string animationEffectDir = Path.Combine(path, Model.AnimationEffectDir, animationInfo.GetNameIndex()); string animationEffectFile = Path.Combine(animationEffectDir, $"{animationInfo.GetNameIndex()}{owAnimWriter.Format}"); Dictionary <ulong, HashSet <FindLogic.Combo.VoiceLineInstanceInfo> > svceLines = new Dictionary <ulong, HashSet <FindLogic.Combo.VoiceLineInstanceInfo> >(); if (animationEffect.GUID != 0) { SaveEffectExtras(flags, animationEffectDir, info, animationEffect.Effect, out svceLines); } if (info.SaveRuntimeData.Threads) { info.SaveRuntimeData.Tasks.Add(Task.Run(() => { SaveOWAnimFile(animationEffectFile, animationEffect, animationInfo, info, owAnimWriter, model, svceLines); })); } else { SaveOWAnimFile(animationEffectFile, animationEffect, animationInfo, info, owAnimWriter, model, svceLines); } }
private static void ConvertAnimation(Stream animStream, string path, bool convertAnims, SEAnimWriter animWriter, FindLogic.Combo.AnimationInfoNew animationInfo) { animStream.Position = 0; Animation parsedAnimation = new Animation(animStream); string animationDirectory = Path.Combine(path, "Animations", parsedAnimation.Header.priority.ToString()); if (convertAnims) { string animOutput = Path.Combine(animationDirectory, animationInfo.GetNameIndex() + animWriter.Format); CreateDirectoryFromFile(animOutput); using (Stream fileStream = new FileStream(animOutput, FileMode.Create)) { animWriter.Write(parsedAnimation, fileStream, new object[] { }); } } else { string rawAnimOutput = Path.Combine(animationDirectory, $"{animationInfo.GetNameIndex()}.{GUID.Type(animationInfo.GUID):X3}"); CreateDirectoryFromFile(rawAnimOutput); using (Stream fileStream = new FileStream(rawAnimOutput, FileMode.Create)) { animStream.CopyTo(fileStream); } } animStream.Dispose(); }
// combo public void Write(BinaryWriter writer, FindLogic.Combo.EffectInfoCombo effectInfo, FindLogic.Combo.ComboInfo info, Dictionary <ulong, HashSet <FindLogic.Combo.VoiceLineInstanceInfo> > svceLines) { writer.Write(new string(Identifier)); writer.Write(VersionMajor); writer.Write(VersionMinor); EffectParser.EffectInfo effect = effectInfo.Effect; writer.Write(GUID.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.ModelInfoNew modelInfo = info.Models[dmceInfo.Model]; writer.Write($"Models\\{modelInfo.GetName()}\\{modelInfo.GetNameIndex()}.owmdl"); if (dmceInfo.Animation == 0) { writer.Write("null"); } else { FindLogic.Combo.AnimationInfoNew animationInfo = info.Animations[dmceInfo.Animation]; writer.Write($"Models\\{modelInfo.GetName()}\\{Model.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.EntityVariable); writer.Write(GUID.Index(ceceInfo.EntityVariable)); if (ceceInfo.Animation != 0) { FindLogic.Combo.AnimationInfoNew animationInfo = info.Animations[ceceInfo.Animation]; writer.Write($"{Model.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(GUID.Index(neceInfo.Variable)); FindLogic.Combo.EntityInfoNew entityInfo = info.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.ModelInfoNew modelInfo = info.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(GUID.Index(svceInfo.VoiceStimulus)); if (svceLines.ContainsKey(svceInfo.VoiceStimulus)) { HashSet <FindLogic.Combo.VoiceLineInstanceInfo> lines = svceLines[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.SoundFileInfo soundFileInfo = info.VoiceSoundFiles[soundFile]; writer.Write($"Sounds\\{soundFileInfo.GetNameIndex()}.ogg"); } } } else { writer.Write(0); } } // foreach (EffectParser.FECEInfo feceInfo in effect.FECEs) { // WriteTime(writer, feceInfo.PlaybackInfo); // writer.Write(feceInfo.GUID); // } // // foreach (EffectParser.OSCEInfo osceInfo in effect.OSCEs) { // // this needs preprocessing, get the sounds // WriteTime(writer, osceInfo.PlaybackInfo); // writer.Write(osceInfo.Sound); // } }
// plan and stuff: // dmce submodels // how are weapons attached? TICK // stretch goal: // how do camera public void WriteReference(Stream output, FindLogic.Combo.ComboInfo info, FindLogic.Combo.AnimationInfoNew animation, ulong model) { using (BinaryWriter writer = new BinaryWriter(output)) { writer.Write(new string(Identifier)); writer.Write(VersionMajor); writer.Write(VersionMinor); writer.Write(GUID.Index(animation.GUID)); writer.Write(animation.FPS); writer.Write((int)OWAnimType.Reference); FindLogic.Combo.ModelInfoNew modelInfo = info.Models[model]; writer.Write($"Models\\{modelInfo.GetName()}\\{Model.AnimationEffectDir}\\{animation.GetNameIndex()}\\{animation.GetNameIndex()}{Format}"); // so I can change it in DataTool and not go mad } }
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.ModelInfoNew modelInfo = Info.Models[dmceInfo.Model]; writer.Write($"Models\\{modelInfo.GetName()}\\{modelInfo.GetNameIndex()}.owmdl"); if (dmceInfo.Animation == 0) { writer.Write("null"); } else { FindLogic.Combo.AnimationInfoNew animationInfo = Info.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.AnimationInfoNew animationInfo = Info.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.EntityInfoNew entityInfo = Info.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.ModelInfoNew modelInfo = Info.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.SoundFileInfo soundFileInfo = Info.VoiceSoundFiles[soundFile]; writer.Write($"Sounds\\{soundFileInfo.GetNameIndex()}.ogg"); } } } else { writer.Write(0); } } }
public OverwatchAnimationEffectReference(FindLogic.Combo.ComboInfo info, FindLogic.Combo.AnimationInfoNew animation, ulong model) { Info = info; Animation = animation; Model = model; }