diff --git a/AboutForm.Designer.cs b/AboutForm.Designer.cs index a9b9938..689e67c 100644 --- a/AboutForm.Designer.cs +++ b/AboutForm.Designer.cs @@ -37,7 +37,7 @@ // OkButton // this.OkButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.OkButton.Location = new System.Drawing.Point(305, 136); + this.OkButton.Location = new System.Drawing.Point(305, 147); this.OkButton.Name = "OkButton"; this.OkButton.Size = new System.Drawing.Size(75, 23); this.OkButton.TabIndex = 0; @@ -52,7 +52,7 @@ | System.Windows.Forms.AnchorStyles.Right))); this.label1.Location = new System.Drawing.Point(12, 35); this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(368, 127); + this.label1.Size = new System.Drawing.Size(368, 138); this.label1.TabIndex = 1; this.label1.Text = resources.GetString("label1.Text"); this.label1.TextAlign = System.Drawing.ContentAlignment.TopCenter; @@ -73,7 +73,7 @@ // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(392, 171); + this.ClientSize = new System.Drawing.Size(392, 182); this.Controls.Add(this.label2); this.Controls.Add(this.OkButton); this.Controls.Add(this.label1); diff --git a/AboutForm.resx b/AboutForm.resx index 5360d58..38771a4 100644 --- a/AboutForm.resx +++ b/AboutForm.resx @@ -124,8 +124,8 @@ Special thanks to: -- Neodymium -- tgascoigne -- CamxxCore -- -- Tadden -- Gramz -- Kai -- Vertigo -- HL -- Pouaichh -- --- The .White team -- CP -- Kilian -- --- Dilapidated -- dav90 -- Neos7 -- +-- Dilapidated -- dav90 -- Neos7 -- Jevi -- sollaholla -- +-- The .White team -- CP -- Kilian -- diff --git a/CodeWalker.csproj b/CodeWalker.csproj index 434cf41..3c63cf1 100644 --- a/CodeWalker.csproj +++ b/CodeWalker.csproj @@ -332,6 +332,7 @@ MainForm.cs + diff --git a/Project/MenyooXml.cs b/Project/MenyooXml.cs new file mode 100644 index 0000000..217593e --- /dev/null +++ b/Project/MenyooXml.cs @@ -0,0 +1,200 @@ +using SharpDX; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml; + +namespace CodeWalker.Project +{ + public class MenyooXml + { + public string Name { get; set; } + public string FileName { get; set; } + public string FilePath { get; set; } + + + + + public List Placements { get; set; } = new List(); + + + public void Init(string xmlstr) + { + XmlDocument doc = new XmlDocument(); + doc.LoadXml(xmlstr); + + XmlElement root = doc.DocumentElement; + + + //see: + //https://github.com/sollaholla/me2ymap/blob/master/YMapExporter/SpoonerPlacements.cs + //https://github.com/Guad/MapEditor/blob/master/MenyooCompatibility.cs + + + + //example: + // + // + //false + //0 + //false + // + // + // + // + // + //true + // + // -180.65478 + // 100.87645 + // 100.05556 + // + + + + + + + + var placements = root.SelectNodes("Placement"); + + foreach (XmlNode node in placements) + { + MenyooXmlPlacement pl = new MenyooXmlPlacement(); + pl.Init(node); + + Placements.Add(pl); + } + + } + + + + + } + + + + + public class MenyooXmlPlacement + { + + public uint ModelHash { get; set; } + public int Type { get; set; } + public bool Dynamic { get; set; } + public bool FrozenPos { get; set; } + public string HashName { get; set; } + public int InitialHandle { get; set; } + public List ObjectProperties { get; set; } + public int OpacityLevel { get; set; } + public float LodDistance { get; set; } + public bool IsVisible { get; set; } + public int MaxHealth { get; set; } + public int Health { get; set; } + public bool HasGravity { get; set; } + public bool IsOnFire { get; set; } + public bool IsInvincible { get; set; } + public bool IsBulletProof { get; set; } + public bool IsCollisionProof { get; set; } + public bool IsExplosionProof { get; set; } + public bool IsFireProof { get; set; } + public bool IsMeleeProof { get; set; } + public bool IsOnlyDamagedByPlayer { get; set; } + public Vector3 Position { get; set; } + public Vector3 RotationYawPitchRoll { get; set; } + public bool Attachment_isAttached { get; set; } + + public Vector4 Rotation + { + get + { + var pry = RotationYawPitchRoll * -(float)(Math.PI / 180.0); + return Quaternion.RotationYawPitchRoll(pry.Z, pry.Y, pry.X).ToVector4(); + } + } + + + + public void Init(XmlNode node) + { + + XmlElement enode = node as XmlElement; + + var hashstr = Xml.GetChildInnerText(node, "ModelHash").ToLowerInvariant(); + if (hashstr.StartsWith("0x")) hashstr = hashstr.Substring(2); + ModelHash = Convert.ToUInt32(hashstr, 16); + + Type = Xml.GetChildIntInnerText(node, "Type"); + Dynamic = Xml.GetChildBoolInnerText(node, "Dynamic"); + FrozenPos = Xml.GetChildBoolInnerText(node, "FrozenPos"); + HashName = Xml.GetChildInnerText(node, "HashName"); + InitialHandle = Xml.GetChildIntInnerText(node, "InitialHandle"); + + if (enode != null) + { + var objprops = Xml.GetChild(enode, "ObjectProperties"); + ObjectProperties = new List(); + if (objprops != null) + { + foreach (XmlNode objpropn in objprops.ChildNodes) + { + MenyooXmlObjectProperty pr = new MenyooXmlObjectProperty(); + pr.Name = objpropn.Name; + pr.Value = objpropn.InnerText; + ObjectProperties.Add(pr); + } + } + + var posrot = Xml.GetChild(enode, "PositionRotation"); + var px = Xml.GetChildFloatInnerText(posrot, "X"); + var py = Xml.GetChildFloatInnerText(posrot, "Y"); + var pz = Xml.GetChildFloatInnerText(posrot, "Z"); + var rp = Xml.GetChildFloatInnerText(posrot, "Pitch"); + var rr = Xml.GetChildFloatInnerText(posrot, "Roll"); + var ry = Xml.GetChildFloatInnerText(posrot, "Yaw"); + Position = new Vector3(px, py, pz); + RotationYawPitchRoll = new Vector3(ry, rp, rr); + } + + OpacityLevel = Xml.GetChildIntInnerText(node, "OpacityLevel"); + LodDistance = Xml.GetChildFloatInnerText(node, "LodDistance"); + IsVisible = Xml.GetChildBoolInnerText(node, "IsVisible"); + MaxHealth = Xml.GetChildIntInnerText(node, "MaxHealth"); + Health = Xml.GetChildIntInnerText(node, "Health"); + HasGravity = Xml.GetChildBoolInnerText(node, "HasGravity"); + IsOnFire = Xml.GetChildBoolInnerText(node, "IsOnFire"); + IsInvincible = Xml.GetChildBoolInnerText(node, "IsInvincible"); + IsBulletProof = Xml.GetChildBoolInnerText(node, "IsBulletProof"); + IsCollisionProof = Xml.GetChildBoolInnerText(node, "IsCollisionProof"); + IsExplosionProof = Xml.GetChildBoolInnerText(node, "IsExplosionProof"); + IsFireProof = Xml.GetChildBoolInnerText(node, "IsFireProof"); + IsMeleeProof = Xml.GetChildBoolInnerText(node, "IsMeleeProof"); + IsOnlyDamagedByPlayer = Xml.GetChildBoolInnerText(node, "IsOnlyDamagedByPlayer"); + Attachment_isAttached = Xml.GetChildBoolAttribute(node, "Attachment", "isAttached"); + + + } + + + + public override string ToString() + { + return Type.ToString() + ": " + HashName + ": " + Position.ToString(); + } + + } + + public class MenyooXmlObjectProperty + { + public string Name { get; set; } + public string Value { get; set; } + public override string ToString() + { + return Name + ": " + Value; + } + } + + +} diff --git a/ProjectForm.Designer.cs b/ProjectForm.Designer.cs index 5a91a36..ea08b27 100644 --- a/ProjectForm.Designer.cs +++ b/ProjectForm.Designer.cs @@ -668,6 +668,8 @@ this.OptionsHideGTAVMapMenu = new System.Windows.Forms.ToolStripMenuItem(); this.SaveFileDialog = new System.Windows.Forms.SaveFileDialog(); this.OpenFileDialog = new System.Windows.Forms.OpenFileDialog(); + this.ToolsMenu = new System.Windows.Forms.ToolStripMenuItem(); + this.ToolsImportMenyooXmlMenu = new System.Windows.Forms.ToolStripMenuItem(); ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); this.splitContainer1.Panel1.SuspendLayout(); this.splitContainer1.Panel2.SuspendLayout(); @@ -1025,6 +1027,7 @@ this.ProjectManifestTextBox.CommentPrefix = null; this.ProjectManifestTextBox.Cursor = System.Windows.Forms.Cursors.IBeam; this.ProjectManifestTextBox.DisabledColor = System.Drawing.Color.FromArgb(((int)(((byte)(100)))), ((int)(((byte)(180)))), ((int)(((byte)(180)))), ((int)(((byte)(180))))); + this.ProjectManifestTextBox.Font = new System.Drawing.Font("Courier New", 9.75F); this.ProjectManifestTextBox.IsReplaceMode = false; this.ProjectManifestTextBox.Language = FastColoredTextBoxNS.Language.XML; this.ProjectManifestTextBox.LeftBracket = '<'; @@ -7511,6 +7514,7 @@ this.YnvMenu, this.TrainsMenu, this.ScenarioMenu, + this.ToolsMenu, this.OptionsMenu}); this.TopMenuStrip.Location = new System.Drawing.Point(0, 0); this.TopMenuStrip.Name = "TopMenuStrip"; @@ -8037,6 +8041,21 @@ // this.OpenFileDialog.Filter = "CodeWalker Projects|*.cwproj"; // + // ToolsMenu + // + this.ToolsMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.ToolsImportMenyooXmlMenu}); + this.ToolsMenu.Name = "ToolsMenu"; + this.ToolsMenu.Size = new System.Drawing.Size(47, 20); + this.ToolsMenu.Text = "Tools"; + // + // ToolsImportMenyooXmlMenu + // + this.ToolsImportMenyooXmlMenu.Name = "ToolsImportMenyooXmlMenu"; + this.ToolsImportMenyooXmlMenu.Size = new System.Drawing.Size(193, 22); + this.ToolsImportMenyooXmlMenu.Text = "Import Menyoo XML..."; + this.ToolsImportMenyooXmlMenu.Click += new System.EventHandler(this.ToolsImportMenyooXmlMenu_Click); + // // ProjectForm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -8883,5 +8902,7 @@ private System.Windows.Forms.Label label162; private System.Windows.Forms.CheckedListBox CarFlagsCheckedListBox; private System.Windows.Forms.CheckedListBox EntityFlagsCheckedListBox; + private System.Windows.Forms.ToolStripMenuItem ToolsMenu; + private System.Windows.Forms.ToolStripMenuItem ToolsImportMenyooXmlMenu; } } \ No newline at end of file diff --git a/ProjectForm.cs b/ProjectForm.cs index fda28e7..17f580a 100644 --- a/ProjectForm.cs +++ b/ProjectForm.cs @@ -1703,23 +1703,26 @@ namespace CodeWalker CEntityDef cent = new CEntityDef(); - cent.archetypeName = new MetaHash(JenkHash.GenHash("prop_alien_egg_01")); - cent.rotation = new Vector4(0, 0, 0, 1); - cent.scaleXY = 1.0f; - cent.scaleZ = 1.0f; - cent.flags = 1572872; - cent.parentIndex = -1; - cent.lodDist = 200.0f; - cent.lodLevel = Unk_1264241711.LODTYPES_DEPTH_ORPHANHD; - cent.priorityLevel = Unk_648413703.PRI_REQUIRED; - cent.ambientOcclusionMultiplier = 255; - cent.artificialAmbientOcclusion = 255; if (copy != null) { cent = copy.CEntityDef; //TODO: copy entity extensions! } + else + { + cent.archetypeName = new MetaHash(JenkHash.GenHash("prop_alien_egg_01")); + cent.rotation = new Vector4(0, 0, 0, 1); + cent.scaleXY = 1.0f; + cent.scaleZ = 1.0f; + cent.flags = 1572872; + cent.parentIndex = -1; + cent.lodDist = 200.0f; + cent.lodLevel = Unk_1264241711.LODTYPES_DEPTH_ORPHANHD; + cent.priorityLevel = Unk_648413703.PRI_REQUIRED; + cent.ambientOcclusionMultiplier = 255; + cent.artificialAmbientOcclusion = 255; + } cent.position = pos; @@ -1946,15 +1949,18 @@ namespace CodeWalker CCarGen ccg = new CCarGen(); - ccg.flags = 3680; - ccg.orientX = 5.0f; - ccg.perpendicularLength = 2.6f; - //TODO: set default values for cargen if (copy != null) { ccg = copy.CCarGen; } + else + { + ccg.flags = 3680; + ccg.orientX = 5.0f; + ccg.perpendicularLength = 2.6f; + //TODO: set default values for cargen + } if (!copyPosition || (copy == null)) { @@ -5501,6 +5507,181 @@ namespace CodeWalker + + + + + + + + + + + + + + + + + + private void ImportMenyooXml() + { + if (CurrentProjectFile == null) + { + NewProject(); + } + + var xmlpath = ShowOpenDialog("XML Files|*.xml", string.Empty); + + if (string.IsNullOrEmpty(xmlpath)) return; + + + var xmlstr = string.Empty; + try + { + xmlstr = File.ReadAllText(xmlpath); + } + catch (Exception ex) + { + MessageBox.Show("Error loading file!\n" + ex.ToString()); + } + + if (string.IsNullOrEmpty(xmlstr)) return; + + var finf = new FileInfo(xmlpath); + + MenyooXml menyooXml = new MenyooXml(); + menyooXml.FilePath = xmlpath; + menyooXml.FileName = finf.Name; + menyooXml.Name = Path.GetFileNameWithoutExtension(finf.Name); + menyooXml.Init(xmlstr); + + + + string fname = menyooXml.Name + ".ymap"; + lock (ymapsyncroot) + { + YmapFile ymap = CurrentProjectFile.AddYmapFile(fname); + if (ymap != null) + { + ymap.Loaded = true; + ymap.HasChanged = true; //new ymap, flag as not saved + ymap._CMapData.contentFlags = 65; //stream flags value + } + CurrentYmapFile = ymap; + } + + CurrentProjectFile.HasChanged = true; + + + int pedcount = 0; + int carcount = 0; + int entcount = 0; + int unkcount = 0; + + foreach (var placement in menyooXml.Placements) + { + if (placement.Type == 1) + { + pedcount++; + } + else if (placement.Type == 2) + { + CCarGen ccg = new CCarGen(); + var rotq = Quaternion.Invert(new Quaternion(placement.Rotation)); + Vector3 cdir = rotq.Multiply(new Vector3(0, 5, 0)); + ccg.flags = 3680; + ccg.orientX = cdir.X; + ccg.orientY = cdir.Y; + ccg.perpendicularLength = 2.6f; + ccg.position = placement.Position; + ccg.carModel = placement.ModelHash; + + YmapCarGen cg = new YmapCarGen(CurrentYmapFile, ccg); + + if (WorldForm != null) + { + lock (WorldForm.RenderSyncRoot) //don't try to do this while rendering... + { + CurrentYmapFile.AddCarGen(cg); + } + } + else + { + CurrentYmapFile.AddCarGen(cg); + } + + carcount++; + } + else if (placement.Type == 3) //standard entity + { + CEntityDef cent = new CEntityDef(); + cent.archetypeName = placement.ModelHash; + cent.position = placement.Position; + cent.rotation = placement.Rotation; + cent.scaleXY = 1.0f; + cent.scaleZ = 1.0f; + cent.flags = placement.Dynamic ? 32u : 0; //1572872; //? + cent.parentIndex = -1; + cent.lodDist = placement.LodDistance; + cent.lodLevel = Unk_1264241711.LODTYPES_DEPTH_ORPHANHD; + cent.priorityLevel = Unk_648413703.PRI_REQUIRED; + cent.ambientOcclusionMultiplier = 255; + cent.artificialAmbientOcclusion = 255; + + YmapEntityDef ent = new YmapEntityDef(CurrentYmapFile, 0, ref cent); + + ent.SetArchetype(GameFileCache.GetArchetype(cent.archetypeName)); + + if (WorldForm != null) + { + lock (WorldForm.RenderSyncRoot) //don't try to do this while rendering... + { + CurrentYmapFile.AddEntity(ent); + } + } + else + { + CurrentYmapFile.AddEntity(ent); + } + + entcount++; + } + else + { + unkcount++; + } + } + + + LoadProjectTree(); + + + + CalcYmapFlags(); + + CalcYmapExtents(); + + + MessageBox.Show(entcount.ToString() + " entities imported. \n" + carcount.ToString() + " car generators imported. \n" + pedcount.ToString() + " peds ignored. \n" + unkcount.ToString() + " others ignored."); + + } + + + + + + + + + + + + + + + + public void GetVisibleYmaps(Camera camera, Dictionary ymaps) { if (hidegtavmap) @@ -6701,6 +6882,11 @@ namespace CodeWalker RemoveScenarioFromProject(); } + private void ToolsImportMenyooXmlMenu_Click(object sender, EventArgs e) + { + ImportMenyooXml(); + } + private void OptionsHideGTAVMapMenu_Click(object sender, EventArgs e) { ProjectHideMapCheckBox.Checked = !hidegtavmap; diff --git a/Utils/Xml.cs b/Utils/Xml.cs index 77a74ab..0a4293b 100644 --- a/Utils/Xml.cs +++ b/Utils/Xml.cs @@ -46,6 +46,30 @@ namespace CodeWalker if (node == null) return null; return node.SelectSingleNode(name)?.InnerText; } + public static bool GetChildBoolInnerText(XmlNode node, string name) + { + if (node == null) return false; + string val = node.SelectSingleNode(name)?.InnerText; + bool b; + bool.TryParse(val, out b); + return b; + } + public static int GetChildIntInnerText(XmlNode node, string name) + { + if (node == null) return 0; + string val = node.SelectSingleNode(name)?.InnerText; + int i; + int.TryParse(val, out i); + return i; + } + public static float GetChildFloatInnerText(XmlNode node, string name) + { + if (node == null) return 0; + string val = node.SelectSingleNode(name)?.InnerText; + float f; + FloatUtil.TryParse(val, out f); + return f; + } public static bool GetChildBoolAttribute(XmlNode node, string name, string attribute) { diff --git a/World/Scenarios.cs b/World/Scenarios.cs index 7cf5305..4b8cfe2 100644 --- a/World/Scenarios.cs +++ b/World/Scenarios.cs @@ -986,15 +986,33 @@ namespace CodeWalker.World List newids = new List(); foreach (var cell in cells) { + bool flag = false; if (cell != null) { newpoints.AddRange(cell); + foreach (var point in cell) + { + if ((point.Flags & Unk_700327466.ExtendedRange) > 0) + { + flag = true; + } + } } - newids.Add((ushort)newpoints.Count); + + ushort cid = (ushort)newpoints.Count; + if (flag) + { + cid += 32768; //any cells with extended range points have this bit set. + } + + newids.Add(cid); } Region.Unk_3844724227 = newids.ToArray(); + + + rage__spdGrid2D grid = new rage__spdGrid2D(); grid.Unk_X_2690909759 = cellsize; grid.Unk_Y_3691675019 = cellsize;