SimShift.MapTool.Ets2Mapper.BuildNavigationCache C# (CSharp) Method

BuildNavigationCache() private method

private BuildNavigationCache ( ) : void
return void
        private void BuildNavigationCache()
        {
            // The idea of navigation cache is that we calculate distances between nodes
            // The nodes we identify as prefabs (cross points etc.)
            // Distance between them are the roads
            // This way we don't have to walk through each road segment (which can be hundreds or thousands) each time we want to know the node-node length
            // This is a reduction of approximately 6x
            Dictionary<ulong, Dictionary<ulong, float>> cache = new Dictionary<ulong, Dictionary<ulong, float>>();

            foreach (var prefab in Items.Values.Where(x => x.HideUI == false && x.Type == Ets2ItemType.Prefab))
            {
                foreach (var node in prefab.NodesList.Values)
                {
                    var endNode = default(Ets2Item);

                    var fw = node.ForwardItem != null && node.ForwardItem.Type == Ets2ItemType.Road;
                    var road = node.ForwardItem != null && node.ForwardItem.Type == Ets2ItemType.Prefab
                    ? node.BackwardItem
                    : node.ForwardItem;
                    var totalLength = 0.0f;
                    var weight = 0.0f;
                    List<Ets2Item> roadList = new List<Ets2Item>();
                    while (road != null)
                    {
                        if (road.StartNode == null || road.EndNode == null)
                            break;
                        var length =
                            (float)Math.Sqrt(Math.Pow(road.StartNode.X - road.EndNode.X, 2) +
                                      Math.Pow(road.StartNode.Z - road.EndNode.Z, 2));
                        var spd = 1;
                        if (road.RoadLook != null)
                        {
                            if (road.RoadLook.IsExpress) spd = 25;
                            if (road.RoadLook.IsLocal) spd = 45;
                            if (road.RoadLook.IsHighway) spd = 70;
                        }

                        totalLength += length;
                        weight += length / spd;
                        roadList.Add(road);

                        if (fw)
                        {
                            road = road.EndNode == null?null: road.EndNode.ForwardItem;
                            if (road != null && road.Type == Ets2ItemType.Prefab)
                            {
                                endNode = road;
                                break;
                            }
                        }
                        else
                        {
                            road = road.StartNode == null ? null : road.StartNode.BackwardItem;
                            if (road != null && road.Type == Ets2ItemType.Prefab)
                            {
                                endNode = road;
                                break;
                            }
                        }
                    }

                    if (prefab.ItemUID == 0x002935DED8C0345C)
                    {
                        Console.WriteLine(node.NodeUID.ToString("X16") + " following to " + endNode.ItemUID.ToString("X16"));
                    }

                    // If there is no end-node found, it is a dead-end road.
                    if (endNode != null && prefab != endNode)
                    {
                        if (prefab.Navigation.ContainsKey(endNode) == false)
                        {
                            prefab.Navigation.Add(endNode,
                                new Tuple<float, float, IEnumerable<Ets2Item>>(weight, totalLength, roadList));
                        }
                        if (endNode.Navigation.ContainsKey(prefab) == false)
                        {
                            var reversedRoadList = new List<Ets2Item>(roadList);
                            reversedRoadList.Reverse();
                            endNode.Navigation.Add(prefab,
                                new Tuple<float, float, IEnumerable<Ets2Item>>(weight, totalLength, reversedRoadList));
                        }
                    }
                }
            }
        }