示例#1
0
        public Tuple <bool, float> AddPrefabPath(TsPrefabItem prefab, TsNode startNode, TsNode endNode)
        {
            //Optional - some prefabs, like gas stastions will be completely selected instead of selecting a sigle road
            //if (prefab.Prefab.PrefabNodes.Count <= 2) {
            //    RoutePrefabs.Add(prefab);
            //    return true;
            //}
            var returnValue = new Tuple <bool, float>(false, 0);
            var s           = prefab.GetNearestNode(this, startNode, 0);
            var e           = prefab.GetNearestNode(this, endNode, 1);

            if (s.id == -1 || e.id == -1)
            {
                return(returnValue);
            }
            var key = new Tuple <TsPrefabNode, TsPrefabNode>(s, e);

            if (prefab.Prefab.NavigationRoutes.ContainsKey(key))
            {
                PrefabNav[prefab] = prefab.Prefab.NavigationRoutes[key].Item1;
                returnValue       = new Tuple <bool, float>(true, prefab.Prefab.NavigationRoutes[key].Item2);
            }
            return(returnValue);
        }
示例#2
0
        public void Parse()
        {
            Version = BitConverter.ToInt32(Stream, 0x0);

            if (Version < 825)
            {
                Log.Msg($"{FilePath} version ({Version}) is too low, min. is 825");
                return;
            }

            var itemCount = BitConverter.ToUInt32(Stream, 0x10);

            if (itemCount == 0)
            {
                _empty = true;
            }
            if (_empty)
            {
                return;
            }

            var lastOffset = 0x14;

            for (var i = 0; i < itemCount; i++)
            {
                var type = (TsItemType)MemoryHelper.ReadUInt32(Stream, lastOffset);
                if (Version <= 825)
                {
                    type++;                 // after version 825 all types were pushed up 1
                }
                switch (type)
                {
                case TsItemType.Road:
                {
                    var item = new TsRoadItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    if (item.Valid)
                    {
                        Mapper.Roads.Add(item);
                    }
                    break;
                }

                case TsItemType.Prefab:
                {
                    var item = new TsPrefabItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    if (item.Valid)
                    {
                        Mapper.Prefabs.Add(item);
                    }
                    break;
                }

                case TsItemType.Company:
                {
                    var item = new TsCompanyItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    if (item.Valid)
                    {
                        Mapper.Companies.Add(item);
                    }
                    break;
                }

                case TsItemType.Service:
                {
                    var item = new TsServiceItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    break;
                }

                case TsItemType.CutPlane:
                {
                    var item = new TsCutPlaneItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    break;
                }

                case TsItemType.City:
                {
                    var item = new TsCityItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    if (item.Valid)
                    {
                        Mapper.Cities.Add(item);
                    }
                    break;
                }

                case TsItemType.MapOverlay:
                {
                    var item = new TsMapOverlayItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    if (item.Valid)
                    {
                        Mapper.MapOverlays.Add(item);
                    }
                    break;
                }

                case TsItemType.Ferry:
                {
                    var item = new TsFerryItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    if (item.Valid)
                    {
                        Mapper.FerryConnections.Add(item);
                    }
                    break;
                }

                case TsItemType.Garage:
                {
                    var item = new TsGarageItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    break;
                }

                case TsItemType.Trigger:
                {
                    var item = new TsTriggerItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    if (item.Valid)
                    {
                        Mapper.Triggers.Add(item);
                    }
                    break;
                }

                case TsItemType.FuelPump:
                {
                    var item = new TsFuelPumpItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    break;
                }

                case TsItemType.RoadSideItem:
                {
                    var item = new TsRoadSideItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    break;
                }

                case TsItemType.BusStop:
                {
                    var item = new TsBusStopItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    break;
                }

                case TsItemType.TrafficRule:
                {
                    var item = new TsTrafficRuleItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    break;
                }

                case TsItemType.TrajectoryItem:
                {
                    var item = new TsTrajectoryItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    break;
                }

                case TsItemType.MapArea:
                {
                    var item = new TsMapAreaItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    if (item.Valid)
                    {
                        Mapper.MapAreas.Add(item);
                    }
                    break;
                }

                default:
                {
                    Log.Msg($"Unknown Type: {type} in {Path.GetFileName(FilePath)} @ {lastOffset}");
                    break;
                }
                }
            }

            var nodeCount = MemoryHelper.ReadInt32(Stream, lastOffset);

            for (var i = 0; i < nodeCount; i++)
            {
                TsNode node = new TsNode(this, lastOffset += 0x04);
                Mapper.UpdateEdgeCoords(node);
                if (!Mapper.Nodes.ContainsKey(node.Uid))
                {
                    Mapper.Nodes.Add(node.Uid, node);
                }
                lastOffset += 0x34;
            }
        }
示例#3
0
        /// <summary>
        /// Loads navigation inside TsItem objects
        /// </summary>
        private void LoadNavigation()
        {
            foreach (var prefab in Prefabs)
            {
                foreach (var nodeStr in prefab.Nodes)
                {
                    var           node     = GetNodeByUid(nodeStr);
                    TsItem        road     = null;
                    TsNode        precnode = node;
                    TsItem        precitem = prefab;
                    TsNode        nextnode;
                    TsItem        nextitem;
                    List <TsItem> roads       = new List <TsItem>();
                    var           totalLength = 0.0f;
                    if (node.ForwardItem != null && node.ForwardItem.Type == TsItemType.Road)
                    {
                        road = node.ForwardItem;
                    }
                    else if (node.BackwardItem != null && node.BackwardItem.Type == TsItemType.Road)
                    {
                        road = node.BackwardItem;
                    }
                    if (road != null)
                    {
                        int direction = 0;
                        if (road.EndNodeUid == node.Uid)
                        {
                            direction = 1;
                        }
                        while (road != null && road.Type != TsItemType.Prefab && !road.Hidden)
                        {
                            var        length  = (float)Math.Sqrt(Math.Pow(GetNodeByUid(road.StartNodeUid).X - GetNodeByUid(road.EndNodeUid).X, 2) + Math.Pow(GetNodeByUid(road.StartNodeUid).Z - GetNodeByUid(road.EndNodeUid).Z, 2));
                            TsRoadItem roadObj = (TsRoadItem)road;
                            totalLength += length / roadObj.RoadLook.GetWidth();

                            /*if (roadObj.RoadLook.IsHighway) totalLength += (length / 2) / roadObj.RoadLook.GetWidth();
                             * else if (roadObj.RoadLook.IsLocal) totalLength += (length / 1.75f) / roadObj.RoadLook.GetWidth();
                             * else if (roadObj.RoadLook.IsExpress) totalLength += (length / 1.25f) / roadObj.RoadLook.GetWidth();
                             * else length += length * 2;*/
                            roads.Add(road);
                            if (GetNodeByUid(road.StartNodeUid) == precnode)
                            {
                                nextnode = GetNodeByUid(road.EndNodeUid);
                                precnode = GetNodeByUid(road.EndNodeUid);
                            }
                            else
                            {
                                nextnode = GetNodeByUid(road.StartNodeUid);
                                precnode = GetNodeByUid(road.StartNodeUid);
                            }
                            if (nextnode.BackwardItem == road || nextnode.BackwardItem == precitem)
                            {
                                nextitem = nextnode.ForwardItem;
                                precitem = nextnode.ForwardItem;
                            }
                            else
                            {
                                nextitem = nextnode.BackwardItem;
                                precitem = nextnode.BackwardItem;
                            }
                            road = nextitem;
                        }
                        if (road != null && !road.Hidden)
                        {
                            TsPrefabItem prevPrefab = (TsPrefabItem)prefab;
                            TsPrefabItem nextPrefab = (TsPrefabItem)road;
                            TsRoadLook   look       = ((TsRoadItem)roads.LastOrDefault()).RoadLook;
                            if (prevPrefab.Hidden || nextPrefab.Hidden)
                            {
                                continue;
                            }
                            if (prevPrefab.Navigation.ContainsKey(nextPrefab) == false && (look.IsBidirectional() || direction == 0))
                            {
                                prevPrefab.Navigation.Add(nextPrefab, new Tuple <float, List <TsItem> >(totalLength, roads));
                            }
                            if (nextPrefab.Navigation.ContainsKey(prevPrefab) == false && (look.IsBidirectional() || direction == 1))
                            {
                                var reverse = new List <TsItem>(roads);
                                reverse.Reverse();
                                nextPrefab.Navigation.Add(prevPrefab, new Tuple <float, List <TsItem> >(totalLength, reverse));
                            }
                        }
                    }
                    else if (node.ForwardItem != null && node.BackwardItem != null)
                    {
                        TsPrefabItem forwardPrefab  = (TsPrefabItem)node.ForwardItem;
                        TsPrefabItem backwardPrefab = (TsPrefabItem)node.BackwardItem;
                        if (forwardPrefab.Hidden || backwardPrefab.Hidden)
                        {
                            continue;
                        }
                        if (forwardPrefab.Navigation.ContainsKey(backwardPrefab) == false)
                        {
                            forwardPrefab.Navigation.Add(backwardPrefab, new Tuple <float, List <TsItem> >(0, null));
                        }
                        if (backwardPrefab.Navigation.ContainsKey(forwardPrefab) == false)
                        {
                            backwardPrefab.Navigation.Add(forwardPrefab, new Tuple <float, List <TsItem> >(0, null));
                        }
                    }
                }
            }

            Dictionary <ulong, TsPrefabItem> ferryToPrefab = new Dictionary <ulong, TsPrefabItem>();

            foreach (var port in FerryConnections)
            {
                float        min          = float.MaxValue;
                TsPrefabItem closerPrefab = null;
                foreach (var prefab in Prefabs)
                {
                    float distance = (float)Math.Sqrt(Math.Pow(port.X - prefab.X, 2) + Math.Pow(port.Z - prefab.Z, 2));
                    if (distance < min && prefab.Navigation.Count > 1 && !prefab.Hidden)
                    {
                        min          = distance;
                        closerPrefab = prefab;
                    }
                }
                ferryToPrefab[port.FerryPortId] = closerPrefab;
            }
            foreach (var port in FerryConnections)
            {
                foreach (var connection in LookupFerryConnection(port.FerryPortId))
                {
                    var ports = new List <TsItem>();
                    ports.Add(FerryPortbyId[connection.StartPortToken]);
                    ports.Add(FerryPortbyId[connection.EndPortToken]);
                    ferryToPrefab[connection.StartPortToken].Navigation.Add(ferryToPrefab[connection.EndPortToken], new Tuple <float, List <TsItem> >(connection.Distance, ports));
                    ports.Reverse();
                    ferryToPrefab[connection.EndPortToken].Navigation.Add(ferryToPrefab[connection.StartPortToken], new Tuple <float, List <TsItem> >(connection.Distance, ports));
                }
            }
        }
示例#4
0
        /// <summary>
        /// Calculate path between two prefabs with Dijkstra's shortest path algorithm (Needs improvement with A* Algorithm)
        /// </summary>
        private void CalculatePath(TsPrefabItem Start, TsPrefabItem End)
        {
            Dictionary <TsPrefabItem, Tuple <float, TsPrefabItem> > nodesToWalk = new Dictionary <TsPrefabItem, Tuple <float, TsPrefabItem> >();
            Dictionary <TsPrefabItem, Tuple <float, TsPrefabItem> > walkedNodes = new Dictionary <TsPrefabItem, Tuple <float, TsPrefabItem> >();

            foreach (var node in Prefabs)
            {
                nodesToWalk.Add(node, new Tuple <float, TsPrefabItem>(float.MaxValue, null));
            }

            if (!nodesToWalk.ContainsKey((TsPrefabItem)Start))
            {
                return;
            }
            if (!nodesToWalk.ContainsKey((TsPrefabItem)End))
            {
                return;
            }

            nodesToWalk[Start] = new Tuple <float, TsPrefabItem>(0, null);

            while (nodesToWalk.Count != 0)
            {
                float        distanceWalked = float.MaxValue;
                TsPrefabItem toWalk         = null;
                foreach (var node in nodesToWalk)
                {
                    var dTmp = node.Value.Item1;
                    if (distanceWalked > dTmp)
                    {
                        distanceWalked = dTmp;
                        toWalk         = node.Key;
                    }
                }
                if (toWalk == null)
                {
                    break;
                }

                walkedNodes[toWalk] = nodesToWalk[toWalk];
                nodesToWalk.Remove(toWalk);

                if (toWalk.Uid == End.Uid)
                {
                    break;
                }

                var currentWeight = walkedNodes[toWalk].Item1;

                foreach (var jump in toWalk.Navigation)
                {
                    var          newWeight = jump.Value.Item1 + currentWeight;
                    TsPrefabItem newNode   = jump.Key;

                    if (walkedNodes[toWalk].Item2 != null)
                    {
                        TsPrefabItem  precPrefab   = walkedNodes[toWalk].Item2;
                        TsPrefabItem  middlePrefab = toWalk;
                        List <TsItem> precRoad     = null;
                        while (precRoad == null && precPrefab != null)
                        {
                            precRoad     = precPrefab.Navigation[middlePrefab].Item2;
                            middlePrefab = precPrefab;
                            precPrefab   = walkedNodes[precPrefab].Item2;
                        }
                        var nextRoad = toWalk.Navigation[newNode].Item2;
                        if (precRoad != null && nextRoad != null && (precRoad.Count != 0 && nextRoad.Count != 0) &&
                            precRoad.LastOrDefault() is TsRoadItem && nextRoad[0] is TsRoadItem)
                        {
                            var result = SetInternalRoutePrefab((TsRoadItem)precRoad.LastOrDefault(), (TsRoadItem)nextRoad[0]);
                            if (!result.Item1)
                            {
                                continue;
                            }
                            else
                            {
                                newWeight += result.Item2;
                            }
                        }
                    }

                    if (!walkedNodes.ContainsKey(newNode) && nodesToWalk[newNode].Item1 > newWeight)
                    {
                        nodesToWalk[newNode] = new Tuple <float, TsPrefabItem>(newWeight, toWalk);
                    }
                }
            }

            TsPrefabItem route = End;

            while (route != null)
            {
                TsPrefabItem gotoNew;
                if (walkedNodes.ContainsKey(route))
                {
                    gotoNew = walkedNodes[route].Item2;
                }
                else
                {
                    gotoNew = nodesToWalk[route].Item2;
                }
                if (gotoNew == null)
                {
                    break;
                }
                if (gotoNew.Navigation.ContainsKey(route) && gotoNew.Navigation[route].Item2 != null)
                {
                    if (gotoNew.Navigation[route].Item2.Count == 2 && gotoNew.Navigation[route].Item2[0] is TsFerryItem && gotoNew.Navigation[route].Item2[1] is TsFerryItem)
                    {
                        var startPort = (TsFerryItem)gotoNew.Navigation[route].Item2[0];
                        var endPort   = (TsFerryItem)gotoNew.Navigation[route].Item2[1];
                        if (!RouteFerryPorts.ContainsKey(startPort))
                        {
                            RouteFerryPorts.Add(startPort, endPort);
                        }
                    }
                    else
                    {
                        for (int i = gotoNew.Navigation[route].Item2.Count - 1; i >= 0; i--)
                        {
                            RouteRoads.Add((TsRoadItem)gotoNew.Navigation[route].Item2[i]);
                        }
                    }
                }

                route = gotoNew;
            }

            RouteRoads.Reverse();
        }
示例#5
0
        public void Parse()
        {
            Version = BitConverter.ToInt32(Stream, 0x0); // 853 = 1.31+
            var itemCount = BitConverter.ToUInt32(Stream, 0x10);

            if (itemCount == 0)
            {
                _empty = true;
            }
            if (_empty)
            {
                return;
            }

            var lastOffset = 0x14;

            for (var i = 0; i < itemCount; i++)
            {
                var type = (TsItemType)BitConverter.ToUInt32(Stream, lastOffset);

                switch (type)
                {
                case TsItemType.Road:
                {
                    var item = new TsRoadItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    if (item.Valid)
                    {
                        Mapper.Roads.Add(item);
                    }
                    break;
                }

                case TsItemType.Prefab:
                {
                    var item = new TsPrefabItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    if (item.Valid)
                    {
                        Mapper.Prefabs.Add(item);
                    }
                    break;
                }

                case TsItemType.Company:
                {
                    var item = new TsCompanyItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    if (item.Valid)
                    {
                        Mapper.Companies.Add(item);
                    }
                    break;
                }

                case TsItemType.Service:
                {
                    var item = new TsServiceItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    break;
                }

                case TsItemType.CutPlane:
                {
                    var item = new TsCutPlaneItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    break;
                }

                case TsItemType.City:
                {
                    var item = new TsCityItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    if (item.Valid)
                    {
                        Mapper.Cities.Add(item);
                    }
                    break;
                }

                case TsItemType.MapOverlay:
                {
                    var item = new TsMapOverlayItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    if (item.Valid)
                    {
                        Mapper.MapOverlays.Add(item);
                    }
                    break;
                }

                case TsItemType.Ferry:
                {
                    var item = new TsFerryItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    if (item.Valid)
                    {
                        Mapper.FerryPortbyId.Add(item.FerryPortId, item);
                    }
                    if (item.Valid)
                    {
                        Mapper.FerryConnections.Add(item);
                    }
                    break;
                }

                case TsItemType.Garage:
                {
                    var item = new TsGarageItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    break;
                }

                case TsItemType.Trigger:
                {
                    var item = new TsTriggerItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    break;
                }

                case TsItemType.FuelPump:
                {
                    var item = new TsFuelPumpItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    break;
                }

                case TsItemType.RoadSideItem:
                {
                    var item = new TsRoadSideItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    break;
                }

                case TsItemType.BusStop:
                {
                    var item = new TsBusStopItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    break;
                }

                case TsItemType.TrafficRule:
                {
                    var item = new TsTrafficRuleItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    break;
                }

                case TsItemType.TrajectoryItem:
                {
                    var item = new TsTrajectoryItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    break;
                }

                case TsItemType.MapArea:
                {
                    var item = new TsMapAreaItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    break;
                }

                default:
                {
                    Log.Msg($"Unknown Type: {type} in {Path.GetFileName(FilePath)} @ {lastOffset}");
                    break;
                }
                }
            }

            var nodeCount = BitConverter.ToInt32(Stream, lastOffset);

            for (var i = 0; i < nodeCount; i++)
            {
                TsNode node = new TsNode(this, lastOffset += 0x04);
                if (!Mapper.Nodes.ContainsKey(node.Uid))
                {
                    Mapper.Nodes.Add(node.Uid, node);
                }
                lastOffset += 0x34;
            }
        }