/// <summary> /// Open an existing tag /// </summary> /// <param name="name">name of the tag</param> /// <param name="tag_group">group tag of the tag</param> /// <param name="flags">special flags to use when opening</param> /// <returns> /// The tag_index handle associated with the <see cref="TagManager"/> used to load the tag, or <see cref="Blam.DatumIndex.Null"/> if this operations fails /// </returns> /// <remarks> /// Will return existing handles if tag is already open. /// If <paramref name="tag_group"/> is setup to be ignored, we return <see cref="kSkipped"/>. /// </remarks> public Blam.DatumIndex Open(string name, TagInterface.TagGroup tag_group, uint flags) { // HACK: Halo1 PC uses gbx's variant of the model tag if (Engine == BlamVersion.Halo1_CE && tag_group == Blam.Halo1.TagGroups.mode) { tag_group = Blam.Halo1.TagGroups.mod2; } if (Ignore(tag_group)) return kSkipped; // Does this tag even exist on disk? string path = string.Format("{0}.{1}", Path.Combine(directory, name), tag_group.Name); if (!Exists(path)) return kMissing; // Is this tag already loaded? if so, reuse handle Blam.DatumIndex di = IsLoaded(name, tag_group); if (di != Blam.DatumIndex.Null) { Array.IncrementReference(di); return di; } // If the tag had errors, don't try loading it again. // Note that valid tags can exist in the error database since they act as root tags for problem // tags, but since we call [IsLoaded] above this it will catch any valid cases if (ErrorDatabaseContains(name, tag_group)) return Blam.DatumIndex.Null; #region Initialize tag manager TagManager tm = new TagManager(this); tm.ReferenceName = refManager.Add(tm, tag_group, name); tm.Flags.Add(flags); tm.Manage(tag_group); tm.TagIndex = di = Array.Add(tm); // in order to read the tag, the tag index must be setup first (due how TagManager.Path is setup) #endregion #region Stream tag manager tm.OpenForRead(); try { tm.Read(); } catch (TagInterface.Exceptions.InvalidVersion /*ex_version*/) { //indexTrace.WriteLine("Tag Index: Failed to open tag from disk (invalid\\unhandled version): {0}{1}{2}", path, Program.NewLine, ex_version); di = kVersionInvalid; } catch (Exception ex) { indexTrace.WriteLine("Tag Index: Failed to open tag from disk: {0}{1}{2}", path, Program.NewLine, ex); di = Blam.DatumIndex.Null; } finally { tm.Close(); } if(di != tm.TagIndex) { Array.Remove(tm.TagIndex); ErrorDatabaseAddLocalHack(name, tag_group); return di; } #endregion ErrorDatabaseUpdate(tm); base.OnEventOpen(new TagIndexEventArgs(this, tm)); return tm.TagIndex; }