2018-03-03 21:03:08 +08:00
|
|
|
|
using CodeWalker.GameFiles;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.ComponentModel;
|
|
|
|
|
using System.Data;
|
|
|
|
|
using System.Drawing;
|
2019-01-13 06:03:27 +08:00
|
|
|
|
using System.IO;
|
2018-03-03 21:03:08 +08:00
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using System.Windows.Forms;
|
2019-01-13 06:03:27 +08:00
|
|
|
|
using System.Xml;
|
2018-03-03 21:03:08 +08:00
|
|
|
|
using WeifenLuo.WinFormsUI.Docking;
|
|
|
|
|
|
|
|
|
|
namespace CodeWalker.Project.Panels
|
|
|
|
|
{
|
|
|
|
|
public partial class EditProjectManifestPanel : ProjectPanel
|
|
|
|
|
{
|
2018-03-03 21:09:31 +08:00
|
|
|
|
public ProjectForm ProjectForm { get; set; }
|
2018-03-03 21:03:08 +08:00
|
|
|
|
public ProjectFile CurrentProjectFile { get; set; }
|
|
|
|
|
|
2018-03-03 21:09:31 +08:00
|
|
|
|
public EditProjectManifestPanel(ProjectForm projectForm)
|
2018-03-03 21:03:08 +08:00
|
|
|
|
{
|
|
|
|
|
ProjectForm = projectForm;
|
|
|
|
|
InitializeComponent();
|
|
|
|
|
Tag = "_manifest.ymf";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void SetTheme(ThemeBase theme)
|
|
|
|
|
{
|
|
|
|
|
base.SetTheme(theme);
|
|
|
|
|
|
|
|
|
|
var txtback = SystemColors.Window;
|
|
|
|
|
var indback = Color.WhiteSmoke;
|
|
|
|
|
|
|
|
|
|
if (theme is VS2015DarkTheme)
|
|
|
|
|
{
|
|
|
|
|
txtback = theme.ColorPalette.MainWindowActive.Background;
|
|
|
|
|
indback = theme.ColorPalette.MainWindowActive.Background;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ProjectManifestTextBox.BackColor = txtback;
|
|
|
|
|
ProjectManifestTextBox.IndentBackColor = indback;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void SetProject(ProjectFile project)
|
|
|
|
|
{
|
|
|
|
|
//TODO: include _manifest.ymf in project and load/save
|
|
|
|
|
|
|
|
|
|
CurrentProjectFile = project;
|
|
|
|
|
|
|
|
|
|
GenerateProjectManifest();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void GenerateProjectManifest()
|
|
|
|
|
{
|
2018-03-10 01:58:44 +08:00
|
|
|
|
var sb = new StringBuilder();
|
|
|
|
|
var mapdeps = new Dictionary<string, YtypFile>();
|
|
|
|
|
var typdeps = new Dictionary<string, Dictionary<string, YtypFile>>();
|
2019-01-13 06:46:52 +08:00
|
|
|
|
var interiors = new List<string>();
|
2018-03-03 21:03:08 +08:00
|
|
|
|
|
|
|
|
|
sb.AppendLine("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");
|
|
|
|
|
sb.AppendLine("<CPackFileMetaData>");
|
|
|
|
|
sb.AppendLine(" <MapDataGroups/>");
|
|
|
|
|
sb.AppendLine(" <HDTxdBindingArray/>");
|
|
|
|
|
sb.AppendLine(" <imapDependencies/>");
|
|
|
|
|
|
|
|
|
|
|
2018-03-10 01:58:44 +08:00
|
|
|
|
var getYtypName = new Func<YtypFile, string>((ytyp) =>
|
|
|
|
|
{
|
|
|
|
|
var ytypname = ytyp?.RpfFileEntry?.NameLower;
|
|
|
|
|
if (ytyp != null)
|
|
|
|
|
{
|
|
|
|
|
if (string.IsNullOrEmpty(ytypname))
|
|
|
|
|
{
|
|
|
|
|
ytypname = ytyp.RpfFileEntry?.Name?.ToLowerInvariant();
|
|
|
|
|
if (ytypname == null) ytypname = "";
|
|
|
|
|
}
|
|
|
|
|
if (ytypname.EndsWith(".ytyp"))
|
|
|
|
|
{
|
|
|
|
|
ytypname = ytypname.Substring(0, ytypname.Length - 5);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return ytypname;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
2019-01-13 06:03:27 +08:00
|
|
|
|
if (CurrentProjectFile != null)
|
2018-03-03 21:03:08 +08:00
|
|
|
|
{
|
2019-01-13 06:03:27 +08:00
|
|
|
|
if (CurrentProjectFile.YmapFiles.Count > 0)
|
2018-03-03 21:03:08 +08:00
|
|
|
|
{
|
2019-01-13 06:03:27 +08:00
|
|
|
|
sb.AppendLine(" <imapDependencies_2>");
|
|
|
|
|
foreach (var ymap in CurrentProjectFile.YmapFiles)
|
2018-03-03 21:03:08 +08:00
|
|
|
|
{
|
2019-01-13 06:03:27 +08:00
|
|
|
|
var ymapname = ymap.RpfFileEntry?.NameLower;
|
|
|
|
|
if (string.IsNullOrEmpty(ymapname))
|
|
|
|
|
{
|
|
|
|
|
ymapname = ymap.Name.ToLowerInvariant();
|
|
|
|
|
}
|
|
|
|
|
if (ymapname.EndsWith(".ymap"))
|
|
|
|
|
{
|
|
|
|
|
ymapname = ymapname.Substring(0, ymapname.Length - 5);
|
|
|
|
|
}
|
2018-03-03 21:03:08 +08:00
|
|
|
|
|
2019-01-13 06:03:27 +08:00
|
|
|
|
mapdeps.Clear();
|
2019-01-13 06:46:52 +08:00
|
|
|
|
bool ismilo = false;
|
2019-01-13 06:03:27 +08:00
|
|
|
|
if (ymap.AllEntities != null)
|
2018-03-03 21:03:08 +08:00
|
|
|
|
{
|
2019-01-13 06:03:27 +08:00
|
|
|
|
foreach (var ent in ymap.AllEntities)
|
2018-03-03 21:03:08 +08:00
|
|
|
|
{
|
2019-01-13 06:03:27 +08:00
|
|
|
|
var ytyp = ent.Archetype?.Ytyp;
|
|
|
|
|
var ytypname = getYtypName(ytyp);
|
|
|
|
|
if (ytyp != null)
|
|
|
|
|
{
|
|
|
|
|
mapdeps[ytypname] = ytyp;
|
|
|
|
|
}
|
2018-03-10 01:58:44 +08:00
|
|
|
|
|
2019-01-13 06:03:27 +08:00
|
|
|
|
if (ent.IsMlo)
|
2018-03-03 21:03:08 +08:00
|
|
|
|
{
|
2019-01-13 06:46:52 +08:00
|
|
|
|
ismilo = true;
|
2019-01-13 06:03:27 +08:00
|
|
|
|
if (ent.MloInstance?.Entities != null)
|
2018-03-10 01:58:44 +08:00
|
|
|
|
{
|
2019-01-13 06:03:27 +08:00
|
|
|
|
Dictionary<string, YtypFile> typdepdict;
|
|
|
|
|
if (!typdeps.TryGetValue(ytypname, out typdepdict))
|
2018-03-10 01:58:44 +08:00
|
|
|
|
{
|
2019-01-13 06:03:27 +08:00
|
|
|
|
typdepdict = new Dictionary<string, YtypFile>();
|
|
|
|
|
typdeps[ytypname] = typdepdict;
|
|
|
|
|
}
|
|
|
|
|
foreach (var ient in ent.MloInstance.Entities)
|
|
|
|
|
{
|
|
|
|
|
var iytyp = ient.Archetype?.Ytyp;
|
|
|
|
|
var iytypname = getYtypName(iytyp);
|
|
|
|
|
if ((iytyp != null) && (iytypname != ytypname))
|
|
|
|
|
{
|
|
|
|
|
typdepdict[iytypname] = iytyp;
|
|
|
|
|
}
|
2018-03-10 01:58:44 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2018-03-03 21:03:08 +08:00
|
|
|
|
}
|
2018-03-10 01:58:44 +08:00
|
|
|
|
|
2019-01-13 06:03:27 +08:00
|
|
|
|
}
|
2018-03-03 21:03:08 +08:00
|
|
|
|
}
|
2019-01-13 06:03:27 +08:00
|
|
|
|
if (ymap.GrassInstanceBatches != null)
|
2018-06-08 00:42:41 +08:00
|
|
|
|
{
|
2019-01-13 06:03:27 +08:00
|
|
|
|
foreach (var batch in ymap.GrassInstanceBatches)
|
2018-06-08 00:42:41 +08:00
|
|
|
|
{
|
2019-01-13 06:03:27 +08:00
|
|
|
|
var ytyp = batch.Archetype?.Ytyp;
|
|
|
|
|
var ytypname = getYtypName(ytyp);
|
|
|
|
|
if (ytyp != null)
|
|
|
|
|
{
|
|
|
|
|
mapdeps[ytypname] = ytyp;
|
|
|
|
|
}
|
2018-06-08 00:42:41 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2019-01-13 06:03:27 +08:00
|
|
|
|
|
|
|
|
|
sb.AppendLine(" <Item>");
|
|
|
|
|
sb.AppendLine(" <imapName>" + ymapname + "</imapName>");
|
2019-01-13 06:46:52 +08:00
|
|
|
|
if (ismilo)
|
|
|
|
|
{
|
|
|
|
|
sb.AppendLine(" <manifestFlags>INTERIOR_DATA</manifestFlags>");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
sb.AppendLine(" <manifestFlags/>");
|
|
|
|
|
}
|
2019-01-13 06:03:27 +08:00
|
|
|
|
sb.AppendLine(" <itypDepArray>");
|
|
|
|
|
foreach (var kvp in mapdeps)
|
|
|
|
|
{
|
|
|
|
|
sb.AppendLine(" <Item>" + kvp.Key + "</Item>");
|
|
|
|
|
}
|
|
|
|
|
sb.AppendLine(" </itypDepArray>");
|
|
|
|
|
sb.AppendLine(" </Item>");
|
2018-06-08 00:42:41 +08:00
|
|
|
|
}
|
2019-01-13 06:03:27 +08:00
|
|
|
|
sb.AppendLine(" </imapDependencies_2>");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
sb.AppendLine(" <imapDependencies_2/>");
|
|
|
|
|
}
|
2018-03-03 21:03:08 +08:00
|
|
|
|
|
2019-01-13 06:03:27 +08:00
|
|
|
|
if ((CurrentProjectFile.YtypFiles.Count > 0) && (ProjectForm?.GameFileCache != null))
|
|
|
|
|
{
|
|
|
|
|
foreach (var ytyp in CurrentProjectFile.YtypFiles)
|
2018-03-03 21:03:08 +08:00
|
|
|
|
{
|
2019-01-13 06:03:27 +08:00
|
|
|
|
var ytypname = getYtypName(ytyp);
|
|
|
|
|
foreach (var archm in ytyp.AllArchetypes)
|
|
|
|
|
{
|
|
|
|
|
var mloa = archm as MloArchetype;
|
|
|
|
|
if (mloa != null)
|
|
|
|
|
{
|
2019-01-13 06:46:52 +08:00
|
|
|
|
interiors.Add(mloa.Name);
|
2019-01-13 06:03:27 +08:00
|
|
|
|
Dictionary<string, YtypFile> typdepdict;
|
|
|
|
|
if (!typdeps.TryGetValue(ytypname, out typdepdict))
|
|
|
|
|
{
|
|
|
|
|
typdepdict = new Dictionary<string, YtypFile>();
|
|
|
|
|
typdeps[ytypname] = typdepdict;
|
|
|
|
|
}
|
|
|
|
|
if (mloa.entities != null)
|
|
|
|
|
{
|
|
|
|
|
foreach (var ent in mloa.entities)
|
|
|
|
|
{
|
|
|
|
|
var archname = ent._Data.archetypeName;
|
|
|
|
|
var arch = ProjectForm.GameFileCache.GetArchetype(archname);
|
|
|
|
|
var iytyp = arch?.Ytyp;
|
|
|
|
|
var iytypname = getYtypName(iytyp);
|
|
|
|
|
if ((iytyp != null) && (iytypname != ytypname))
|
|
|
|
|
{
|
|
|
|
|
typdepdict[iytypname] = iytyp;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (mloa.entitySets != null)
|
|
|
|
|
{
|
|
|
|
|
foreach (var entset in mloa.entitySets)
|
|
|
|
|
{
|
|
|
|
|
if (entset.Entities != null)
|
|
|
|
|
{
|
|
|
|
|
foreach (var ent in entset.Entities)
|
|
|
|
|
{
|
|
|
|
|
var archname = ent._Data.archetypeName;
|
|
|
|
|
var arch = ProjectForm.GameFileCache.GetArchetype(archname);
|
|
|
|
|
var iytyp = arch?.Ytyp;
|
|
|
|
|
var iytypname = getYtypName(iytyp);
|
|
|
|
|
if ((iytyp != null) && (iytypname != ytypname))
|
|
|
|
|
{
|
|
|
|
|
typdepdict[iytypname] = iytyp;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-03-03 21:03:08 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2019-01-13 06:03:27 +08:00
|
|
|
|
|
2018-03-03 21:03:08 +08:00
|
|
|
|
}
|
|
|
|
|
|
2018-03-10 01:58:44 +08:00
|
|
|
|
if (typdeps.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
sb.AppendLine(" <itypDependencies_2>");
|
|
|
|
|
foreach (var kvp1 in typdeps)
|
|
|
|
|
{
|
|
|
|
|
sb.AppendLine(" <Item>");
|
|
|
|
|
sb.AppendLine(" <itypName>" + kvp1.Key + "</itypName>");
|
|
|
|
|
sb.AppendLine(" <manifestFlags>INTERIOR_DATA</manifestFlags>");
|
|
|
|
|
sb.AppendLine(" <itypDepArray>");
|
|
|
|
|
foreach (var kvp2 in kvp1.Value)
|
|
|
|
|
{
|
|
|
|
|
sb.AppendLine(" <Item>" + kvp2.Key + "</Item>");
|
|
|
|
|
}
|
|
|
|
|
sb.AppendLine(" </itypDepArray>");
|
|
|
|
|
sb.AppendLine(" </Item>");
|
|
|
|
|
}
|
|
|
|
|
sb.AppendLine(" </itypDependencies_2>");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
sb.AppendLine(" <itypDependencies_2/>");
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-13 06:46:52 +08:00
|
|
|
|
if (interiors.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
sb.AppendLine(" <Interiors itemType=\"CInteriorBoundsFiles\">");
|
|
|
|
|
foreach (var interior in interiors)
|
|
|
|
|
{
|
|
|
|
|
sb.AppendLine(" <Item>");
|
|
|
|
|
sb.AppendLine(" <Name>" + interior + "</Name>");
|
|
|
|
|
sb.AppendLine(" <Bounds>");
|
|
|
|
|
sb.AppendLine(" <Item>" + interior + "</Item>");
|
|
|
|
|
sb.AppendLine(" </Bounds>");
|
|
|
|
|
sb.AppendLine(" </Item>");
|
|
|
|
|
}
|
|
|
|
|
sb.AppendLine(" </Interiors>");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
sb.AppendLine(" <Interiors/>");
|
|
|
|
|
}
|
2018-03-03 21:03:08 +08:00
|
|
|
|
sb.AppendLine("</CPackFileMetaData>");
|
|
|
|
|
|
|
|
|
|
ProjectManifestTextBox.Text = sb.ToString();
|
|
|
|
|
Text = "_manifest.ymf*";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ProjectManifestGenerateButton_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
CurrentProjectFile = ProjectForm.CurrentProjectFile;
|
|
|
|
|
GenerateProjectManifest();
|
|
|
|
|
}
|
2019-01-13 06:03:27 +08:00
|
|
|
|
|
|
|
|
|
private void SaveManifestButton_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
if (SaveFileDialog.ShowDialog() != DialogResult.OK) return;
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var filename = SaveFileDialog.FileName;
|
|
|
|
|
var xml = ProjectManifestTextBox.Text;
|
|
|
|
|
var xmldoc = new XmlDocument();
|
|
|
|
|
xmldoc.LoadXml(xml);
|
|
|
|
|
var pso = XmlPso.GetPso(xmldoc);
|
|
|
|
|
var bytes = pso.Save();
|
|
|
|
|
File.WriteAllBytes(filename, bytes);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
MessageBox.Show("Error saving _manifest.ymf file:\n" + ex.ToString());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
2018-03-03 21:03:08 +08:00
|
|
|
|
}
|
|
|
|
|
}
|