Created
January 29, 2020 01:49
-
-
Save PichotM/2b3dd445ba640a8867dfae84450fba48 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using CodeWalker.GameFiles; | |
using System.IO; | |
using SharpDX; | |
using System.Collections.Generic; | |
using NodReader; | |
using CodeWalker; | |
namespace YNDMover | |
{ | |
public partial class MainYND | |
{ | |
private string basePath = "NODE_FOLDER"; | |
private string targetPath = "NODE_DESTINATION"; | |
private List<YndFile> AllYnds = new List<YndFile>(); | |
private static Dictionary<int, List<Node>> NodeList = new Dictionary<int, List<Node>>(); | |
private static Dictionary<int, NodeLink[]> LinkList = new Dictionary<int, NodeLink[]>(); | |
private static List<NodeData> NodeDataList = new List<NodeData>(); | |
private static List<YndFile> LegacyYndFileList = new List<YndFile>(); | |
private static Dictionary<int, YndFile> YndFileList = new Dictionary<int, YndFile>(); | |
private static Dictionary<int, YndFile> YndFileList2 = new Dictionary<int, YndFile>(); | |
private static List<NewLink> NewLinkList = new List<NewLink>(); | |
private static string logContent = ""; | |
private void WriteLine(string text) | |
{ | |
logContent += text + "\n"; | |
} | |
private void DoNodeStuff(YndNode uselessNode, YndNode centerNode, YndNode outerNode, YndLink link) | |
{ | |
NewLink newLink = new NewLink(); | |
foreach (NodeData nodeData in NodeDataList) | |
{ | |
if (nodeData.newNode.AreaID == uselessNode.AreaID && nodeData.newNode.NodeID == uselessNode.NodeID) | |
{ | |
NodeList[nodeData.newNode.AreaID].Remove(nodeData.Node); | |
} | |
else if (nodeData.newNode == centerNode) | |
{ | |
newLink.centerNode = nodeData.Node; | |
} | |
else if (nodeData.newNode == outerNode) | |
{ | |
newLink.outerNode = nodeData.Node; | |
} | |
} | |
newLink.link = link; | |
NewLinkList.Add(newLink); | |
} | |
private static void Main() | |
{ | |
MainYND mainYND = new MainYND(); | |
mainYND.Launch(); | |
} | |
private void BuildNodes(Dictionary<int, YndFile> yndList) | |
{ | |
NodeDataList.Clear(); | |
foreach (KeyValuePair<int, List<Node>> entry in NodeList) | |
{ | |
YndFile ynd; | |
if (!yndList.ContainsKey(entry.Key)) | |
{ | |
ynd = new YndFile(); | |
ynd.AreaID = (ushort)entry.Key; | |
ynd.NodeDictionary = new NodeDictionary(); | |
yndList[entry.Key] = ynd; | |
} | |
else | |
{ | |
ynd = yndList[entry.Key]; | |
} | |
foreach (Node node in entry.Value) | |
{ | |
YndNode newNode = ynd.AddNode(); | |
newNode.AreaID = (ushort)ynd.AreaID; | |
newNode.SetPosition(new Vector3(node.PositionX / 4.0f, node.PositionY / 4.0f, node.PositionZ / 32.0f)); | |
var flag = node.LinkCountFlags.Value & 7; | |
var flags5 = (uint)(flag); | |
if (BitUtil.IsBitSet(node.Flags2, 6)) // Freeway | |
{ | |
flags5 = BitUtil.UpdateBit(flags5, 0, BitUtil.IsBitSet(flags5, 0)); | |
flags5 = BitUtil.UpdateBit(flags5, 1, true); | |
flags5 = BitUtil.UpdateBit(flags5, 2, true); | |
} | |
if (BitUtil.IsBitSet(node.Flags2, 2) && !BitUtil.IsBitSet(flags5, 0)) // Junction | |
{ | |
flags5 = BitUtil.UpdateBit(flags5, 0, true); | |
flags5 = BitUtil.UpdateBit(flags5, 1, BitUtil.IsBitSet(flags5, 1)); | |
flags5 = BitUtil.UpdateBit(flags5, 2, true); | |
} | |
newNode.Flags0 = node.Flags0; | |
newNode.Flags1 = node.Flags1; | |
newNode.Flags2 = node.Flags2; | |
newNode.Flags3 = node.Flags3; | |
newNode.Flags4 = node.Flags4; | |
newNode.LinkCountUnk = (int)flags5; | |
//Console.WriteLine(newNode.LinkCountUnk); | |
bool IsPedNode = newNode.Flags4 > 100; | |
if (IsPedNode) | |
{ | |
ynd.NodeDictionary.NodesCountPed++; | |
} | |
else | |
{ | |
ynd.NodeDictionary.NodesCountVehicle++; | |
} | |
NodeData nodeData = new NodeData(); | |
nodeData.Node = node; | |
nodeData.newNode = newNode; | |
nodeData.AreaID = newNode.AreaID; | |
NodeDataList.Add(nodeData); | |
} | |
} | |
} | |
private void BuildNodesLinks(Dictionary<int, YndFile> yndList) | |
{ | |
foreach (KeyValuePair<int, YndFile> entry in yndList) | |
{ | |
YndFile ynd = entry.Value; | |
foreach (YndNode yndNode in ynd.Nodes) | |
{ | |
NodeData nodeData = new NodeData(); | |
foreach (NodeData iindoe in NodeDataList) | |
{ | |
if (iindoe.newNode == yndNode) | |
{ | |
nodeData = iindoe; | |
break; | |
} | |
} | |
int links = nodeData.Node.LinkCountFlags.Value >> 3; | |
if (links != 0) | |
{ | |
for (var i = 0; i < links; i++) | |
{ | |
int linkArrayIndex = nodeData.Node.LinkID + i; | |
NodeLink targetLink = LinkList[nodeData.Node.AreaID][linkArrayIndex]; | |
foreach (NodeData node2 in NodeDataList) | |
{ | |
if (node2.Node.NodeID == targetLink.NodeID && node2.AreaID == targetLink.AreaID) | |
{ | |
YndLink newLink = yndNode.AddLink(node2.newNode); | |
newLink.Flags0 = targetLink.Flags0; | |
newLink.Flags1 = targetLink.Flags1; | |
newLink.Flags2 = targetLink.Flags2; | |
newLink.UpdateLength(); | |
} | |
} | |
} | |
} | |
} | |
} | |
if (NewLinkList != null && NewLinkList.Count != 0) | |
{ | |
foreach(NewLink newLink in NewLinkList) | |
{ | |
YndNode centerNode = null; | |
YndNode outerNode = null; | |
foreach(NodeData node in NodeDataList) | |
{ | |
if (node.Node.AreaID == newLink.centerNode.AreaID && node.Node.NodeID == newLink.centerNode.NodeID) | |
{ | |
centerNode = node.newNode; | |
} | |
else if (node.Node.AreaID == newLink.outerNode.AreaID && node.Node.NodeID == newLink.outerNode.NodeID) | |
{ | |
outerNode = node.newNode; | |
} | |
if (outerNode != null && centerNode != null) { break; } | |
} | |
if (outerNode != null && centerNode != null) | |
{ | |
YndLink n1 = outerNode.AddLink(centerNode); | |
n1.Flags0 = newLink.link.Flags0; | |
n1.Flags1 = newLink.link.Flags1; | |
n1.Flags2 = newLink.link.Flags2; | |
YndLink n2 = centerNode.AddLink(outerNode); | |
n2.Flags0 = newLink.link.Flags0; | |
n2.Flags1 = newLink.link.Flags1; | |
n2.Flags2 = newLink.link.Flags2; | |
n2.UpdateLength(); | |
n1.UpdateLength(); | |
} | |
else | |
{ | |
WriteLine("ERROR."); | |
} | |
} | |
} | |
} | |
void Launch() | |
{ | |
if (basePath == null || !Directory.Exists(basePath)) | |
{ | |
WriteLine("Wrong path"); | |
Console.ReadKey(true); | |
return; | |
} | |
string[] yndFiles = Directory.GetFiles(basePath.Replace("\\", "//"), "*.ynd"); | |
if (yndFiles == null || yndFiles.Length == 0) | |
{ | |
WriteLine("0 ynd file in this folder."); | |
Console.ReadKey(true); | |
return; | |
} | |
foreach (string filePath in yndFiles) | |
{ | |
string fileName = Path.GetFileNameWithoutExtension(filePath); | |
if (true || fileName == "nodes528") | |
{ | |
YndFile ynd = new YndFile(); | |
byte[] data = File.ReadAllBytes(filePath); | |
ynd.Load(data); | |
string pathDir = Path.GetDirectoryName(filePath); | |
string areaidstr = fileName.ToLowerInvariant().Replace("nodes", ""); | |
int areaid = 0; | |
int.TryParse(areaidstr, out areaid); | |
ynd.AreaID = areaid; | |
LegacyYndFileList.Add(ynd); | |
Console.WriteLine(ynd.AreaID.ToString()); | |
WriteLine("----------------" + ynd.AreaID.ToString() + "--------------"); | |
if (ynd.NodeDictionary.Links != null) | |
WriteLine("Links " + ynd.NodeDictionary.Links.Length + " | " + (ynd.Links != null ? ynd.Links.Length.ToString() : "0")); | |
if (ynd.NodeDictionary.LinksCount != null) | |
WriteLine("LinksCount " + ynd.NodeDictionary.LinksCount); | |
if (ynd.NodeDictionary.Nodes != null) | |
WriteLine("Nodes " + ynd.NodeDictionary.Nodes.Length + " | " + ynd.Nodes.Length); | |
if (ynd.NodeDictionary.NodesCount != null) | |
WriteLine("NodesCount " + ynd.NodeDictionary.NodesCount); | |
if (ynd.NodeDictionary.NodesCountPed != null) | |
WriteLine("NodesCountPed " + ynd.NodeDictionary.NodesCountPed); | |
if (ynd.NodeDictionary.NodesCountVehicle != null) | |
WriteLine("NodesCountVehicle " + ynd.NodeDictionary.NodesCountVehicle); | |
if (ynd.NodeDictionary.NodesPointer != null) | |
WriteLine("NodesPointer " + ynd.NodeDictionary.NodesPointer); | |
WriteLine("------------------------------"); | |
} | |
} | |
foreach(YndFile ynd in LegacyYndFileList) | |
{ | |
NodeList[ynd.AreaID] = new List<Node>(); | |
foreach (Node node in ynd.NodeDictionary.Nodes) | |
{ | |
//if (node.AreaID == ynd.AreaID) | |
NodeList[ynd.AreaID].Add(node); | |
} | |
if (NodeList[ynd.AreaID] != null) | |
{ | |
WriteLine("Total nodes " + NodeList[ynd.AreaID].Count + " in " + ynd.AreaID); | |
if (ynd.Junctions != null) | |
WriteLine("Total junctions " + ynd.Junctions.Length); | |
} | |
LinkList[ynd.AreaID] = ynd.NodeDictionary.Links; | |
} | |
BuildNodes(YndFileList); | |
BuildNodesLinks(YndFileList); | |
int removedNodes = 0; | |
foreach (KeyValuePair<int, YndFile> entry in YndFileList) | |
{ | |
YndFile ynd = entry.Value; | |
foreach (YndNode node in ynd.Nodes) | |
{ | |
if (node.Flags1 == 120 && node.LinkCount > 0) | |
{ | |
foreach (YndLink nodeLink in node.Links) | |
{ | |
if (nodeLink.Node1.LinkCountUnk != 7 && nodeLink.Node1.LinkCountUnk != 5 && !BitUtil.IsBitSet(nodeLink.Node1.Flags2, 2)) | |
{ | |
foreach (YndLink nodeLink1 in nodeLink.Node1.Links) | |
{ | |
if ((nodeLink1.Node1.LinkCountUnk == 7 || nodeLink1.Node1.LinkCountUnk == 5) && !BitUtil.IsBitSet(nodeLink1.Node1.Flags2, 2)) | |
{ | |
DoNodeStuff(nodeLink1.Node2, nodeLink1.Node1, node, nodeLink1); | |
removedNodes++; | |
} | |
} | |
} | |
if (nodeLink.Node2.LinkCountUnk != 7 && nodeLink.Node2.LinkCountUnk != 5 && !BitUtil.IsBitSet(nodeLink.Node2.Flags2, 2)) | |
{ | |
foreach (YndLink nodeLink2 in nodeLink.Node2.Links) | |
{ | |
if ((nodeLink2.Node2.LinkCountUnk == 7 || nodeLink2.Node2.LinkCountUnk == 5) && !BitUtil.IsBitSet(nodeLink2.Node1.Flags2, 2)) | |
{ | |
DoNodeStuff(nodeLink2.Node1, nodeLink2.Node2, node, nodeLink2); | |
removedNodes++; | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
WriteLine("Removed nodes : " + removedNodes); | |
BuildNodes(YndFileList2); | |
BuildNodesLinks(YndFileList2); | |
WriteLine(YndFileList2.Count.ToString()); | |
foreach (KeyValuePair<int, YndFile> entry in YndFileList2) | |
{ | |
YndFile ynd = entry.Value; | |
byte[] newData = ynd.Save(); | |
if (ynd.NodeDictionary.Links != null) | |
WriteLine("Links " + ynd.NodeDictionary.Links.Length + " | " + (ynd.Links != null ? ynd.Links.Length.ToString() : "0")); | |
if (ynd.NodeDictionary.LinksCount != null) | |
WriteLine("LinksCount " + ynd.NodeDictionary.LinksCount); | |
if (ynd.NodeDictionary.Nodes != null) | |
WriteLine("Nodes " + ynd.NodeDictionary.Nodes.Length + " | " + ynd.Nodes.Length); | |
if (ynd.NodeDictionary.NodesCount != null) | |
WriteLine("NodesCount " + ynd.NodeDictionary.NodesCount); | |
if (ynd.NodeDictionary.NodesCountPed != null) | |
WriteLine("NodesCountPed " + ynd.NodeDictionary.NodesCountPed); | |
if (ynd.NodeDictionary.NodesCountVehicle != null) | |
WriteLine("NodesCountVehicle " + ynd.NodeDictionary.NodesCountVehicle); | |
if (ynd.NodeDictionary.NodesPointer != null) | |
WriteLine("NodesPointer " + ynd.NodeDictionary.NodesPointer); | |
WriteLine("------------------------------"); | |
WriteLine("Successfully written " + ynd.AreaID + " node."); | |
Console.WriteLine("Successfully written " + ynd.AreaID + " node."); | |
File.WriteAllBytes(targetPath + "//nodes" + ynd.AreaID.ToString() + ".ynd", newData); | |
} | |
Console.Write("\nPress any key to exit..."); | |
File.WriteAllText("log.txt", logContent); | |
Console.ReadKey(true); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment