/// <summary> /// Serializes a tag reference. /// </summary> /// <param name="context">The serialization context to use.</param> /// <param name="block">The block to write to.</param> /// <param name="referencedTag">The referenced tag.</param> /// <param name="valueInfo">Information about the value. Can be <c>null</c>.</param> private void SerializeTagReference(ISerializationContext context, IDataBlock block, CachedTag referencedTag, TagFieldAttribute valueInfo) { if (referencedTag != null && referencedTag.Group == TagGroup.None) { referencedTag = null; } if (referencedTag != null && valueInfo != null && valueInfo.ValidTags != null) { foreach (string tag in valueInfo.ValidTags) { if (!referencedTag.IsInGroup(tag)) { throw new Exception($"Invalid group for tag reference: {referencedTag.Group.Tag}"); } } } block.AddTagReference(referencedTag, valueInfo == null ? false : valueInfo.Flags.HasFlag(Short)); if (valueInfo == null || !valueInfo.Flags.HasFlag(Short)) { block.Writer.Write((referencedTag != null) ? referencedTag.Group.Tag.Value : -1); block.Writer.Write(0); block.Writer.Write(0); } block.Writer.Write((referencedTag != null) ? referencedTag.Index : -1); }
public void LoadTagEditor(CachedTag tag) { if (tag == null || (CurrentTag != null && CurrentTag.Index == tag.Index)) { return; } LoadingTag = true; object definition = null; if (CurrentTags.ContainsKey(tag.Index)) { definition = CurrentTags[tag.Index]; } tagTreeView.Enabled = false; tagEditorPanel.Controls.Clear(); var tagName = tag.Name ?? $"0x{tag.Index:X4}"; var groupName = Cache.StringTable.GetString(tag.Group.Name); statusLabel.Text = $"Loading {tagName}.{ groupName}..."; progressBar.Style = ProgressBarStyle.Marquee; progressBar.MarqueeAnimationSpeed = 30; if (definition == null) { using (var stream = Cache.OpenCacheRead()) definition = Cache.Deserialize(stream, tag); } if (tagName.Contains("\\")) { var index = tagName.LastIndexOf('\\') + 1; tagName = tagName.Substring(index, tagName.Length - index); } statusLabel.Text = $"Generating {groupName} interface..."; Application.DoEvents(); var point = new Point(); if (tag.IsInGroup("matg") || tag.IsInGroup("mulg") || tag.IsInGroup("scnr") || tag.IsInGroup("sbsp")) { var control = new StructMultiControl(this, Cache, tag, definition) { Dock = DockStyle.Fill }; control.GetFieldValue(null, definition, definition); tagEditorPanel.Controls.Add(control); } // todo: fixup/clean model rendering code // todo: finish bitm editing (save/import dds, add size scaling to image) else if (tag.IsInGroup("bitm") || tag.IsInGroup("obje")) { var splitContainer = new SplitContainer { Dock = DockStyle.Fill, Orientation = Orientation.Horizontal }; splitContainer.FixedPanel = FixedPanel.Panel1; tagEditorPanel.Controls.Add(splitContainer); splitContainer.BringToFront(); /*if (tag.IsInGroup("bitm")) * splitContainer.SplitterDistance = 384;//Math.Min((short)512, Math.Max((short)16, ((TagTool.Tags.Definitions.Bitmap)definition).Images[0].Height)); * else if (tag.IsInGroup("obje")) * splitContainer.SplitterDistance = 384;*/ if (tag.IsInGroup("bitm")) { var bitmDefinition = (TagTool.Tags.Definitions.Bitmap)definition; if (Cache.ResourceCache.GetBitmapTextureInteropResource(bitmDefinition.Resources[0]) != null) { splitContainer.SplitterDistance = 384; var bitmapControl = new BitmapControl(Cache, bitmDefinition) { Dock = DockStyle.Fill }; splitContainer.Panel1.Controls.Add(bitmapControl); bitmapControl.BringToFront(); } } /*else if (tag.IsInGroup("obje")) * { * var modelControl = new ObjectControl(Cache, (GameObject)definition) * { * Dock = DockStyle.Fill * }; * * splitContainer.Panel1.Controls.Add(modelControl); * modelControl.BringToFront(); * }*/ var control = tag.IsInGroup("obje") ? (Control) new StructMultiControl(this, Cache, tag, definition) { Dock = DockStyle.Fill } : new StructControl(this, Cache, definition.GetType(), null); ((IFieldControl)control).GetFieldValue(null, definition, definition); control.Location = point; splitContainer.Panel2.Controls.Add(control); splitContainer.Panel2.AutoScroll = true; } else { if (tag.IsInGroup("snd!")) { var soundControl = new SoundControl(Cache, tag, (Sound)definition) { Dock = DockStyle.Top }; tagEditorPanel.Controls.Add(soundControl); soundControl.BringToFront(); point.Y = soundControl.Bottom; } var control = new StructControl(this, Cache, definition.GetType(), null); control.GetFieldValue(null, definition, definition); control.Location = point; tagEditorPanel.Controls.Add(control); } statusLabel.Text = ""; progressBar.Style = ProgressBarStyle.Continuous; progressBar.MarqueeAnimationSpeed = 0; tagTreeView.Enabled = true; CurrentTag = tag; if (!CurrentTags.ContainsKey(tag.Index)) { CurrentTags[tag.Index] = definition; var item = new TagInstanceItem { Cache = Cache, Tag = tag }; currentTagsComboBox.Items.Add(item); currentTagsComboBox.SelectedItem = item; } else { for (var i = 0; i < currentTagsComboBox.Items.Count; i++) { var item = (TagInstanceItem)currentTagsComboBox.Items[i]; if (item.Tag.Index == tag.Index) { currentTagsComboBox.SelectedIndex = i; break; } } } LoadingTag = false; }
private string GetTagTreeNodeImageKey(CachedTag tag) { if (tag.IsInGroup("cfgt") || tag.IsInGroup("matg") || tag.IsInGroup("mulg") || tag.IsInGroup("aigl") || tag.IsInGroup("smdt") || tag.IsInGroup("inpg") || tag.IsInGroup("rasg") || tag.IsInGroup("wezr") || tag.IsInGroup("wgtz") || tag.IsInGroup("wigl")) { return("file_settings"); } if (tag.IsInGroup("jmad")) { return("file_animation"); } else if (tag.IsInGroup("bitm")) { return("file_bitmap"); } else if (tag.IsInGroup("snd!") || tag.IsInGroup("lsnd")) { return("file_sound"); } else { return("file"); } }
public override object Execute(List <string> args) { //Arguments needed: filepath, <new>|<tagIndex> if (args.Count < 2) { return(false); } if (Environment.Is64BitProcess) // JsonMoppNet uses Havok 6.5.0, which is x86 only { Console.WriteLine("TagTool must be compiled in 32bit mode to use this command."); return(true); } CachedTag tag = null; bool b_duplicate; // optional argument: forces overwriting of tags that are not type: phmo bool b_force = (args.Count >= 3 && args[2].ToLower().Equals("force")); if (args[1].ToLower().Equals("new")) { b_duplicate = true; } else { if (!Cache.TryGetCachedTag(args[1], out tag)) { return(false); } b_duplicate = false; } if (!b_force && !b_duplicate && !tag.IsInGroup("phmo")) { Console.WriteLine("Tag to override was not of class- 'phmo'. Use third argument- 'force' to inject."); return(false); } var filename = args[0]; var modelbuilder = new PhysicsModelBuilder(); if (!modelbuilder.ParseFromFile(filename)) { return(false); } //modelbuilder must also make a node for the physics model var phmo = modelbuilder.Build(); if (phmo == null) { return(false); } using (var stream = Cache.OpenCacheReadWrite()) { if (b_duplicate) { //duplicate an existing tag, trashcan phmo tag = null; // Cache.TagCache.DuplicateTag(stream, Cache.TagCache.GetTagByIndex(0x4436)); if (tag == null) { Console.WriteLine("Failed tag duplication."); return(false); } } Cache.Serialize(stream, tag, phmo); } Console.Write("Successfully imported phmo to: "); TagPrinter.PrintTagShort(tag); return(true); }