Ejemplo n.º 1
0
        public Ets2Item(ulong uid, Ets2Sector sector, int offset)
        {
            ItemUID = uid;

            Navigation = new Dictionary<Ets2Item, Tuple<float, float, IEnumerable<Ets2Item>>>();

            Sector = sector;
            FileOffset = offset;
            FilePath = sector.FilePath;

            NodesList = new Dictionary<ulong, Ets2Node>();

            Type = (Ets2ItemType)BitConverter.ToUInt32(sector.Stream, offset);

            int nodeCount;

            switch (Type)
            {
                case Ets2ItemType.Road:
                    StartNodeUID = BitConverter.ToUInt64(sector.Stream, offset + 141);
                    EndNodeUID = BitConverter.ToUInt64(sector.Stream, offset + 149);

                    var lookId = BitConverter.ToUInt32(sector.Stream, offset + 61); // unique UINT32 ID with road look
                    RoadLook = Sector.Mapper.LookupRoadLookID(lookId);

                    // Need to create LUT to translate road_look.sii <> ID
                    // Then we can parse highway routes etc.

                    HideUI = (sector.Stream[offset + 0x37] & 0x02) != 0;

                    // Make sure these UID's exist in the world.
                    if ((StartNodeUID != 0 && sector.Mapper.Nodes.ContainsKey(StartNodeUID)) ||
                        (EndNodeUID != 0 && sector.Mapper.Nodes.ContainsKey(EndNodeUID)))
                    {
                        Valid = true;

                        var stamps = BitConverter.ToInt32(sector.Stream, offset + 433);
                        BlockSize = 437 + stamps*24;
                    }
                    else
                    {
                        Valid = false;
                    }
                    break;

                case Ets2ItemType.Prefab:
                    if (uid == 0x2935de9c700704)
                    {
                        //
                    }

                    nodeCount = BitConverter.ToInt32(sector.Stream, offset + 81);
                    HideUI = (sector.Stream[offset + 0x36] & 0x02) != 0;

                    if (nodeCount > 0x20)
                    {
                        Valid = false;
                        return;
                    }
                    var somethingOffset = offset + 85 + 8*nodeCount;
                    if (somethingOffset < offset || somethingOffset > sector.Stream.Length)
                    {
                        Valid = false;
                        return;
                    }
                    var something = BitConverter.ToInt32(sector.Stream,somethingOffset);

                    if (something < 0 || something > 32)
                    {
                        Valid = false;
                        return;
                    }
                    var OriginOffset = offset + 0x61 + nodeCount*8 + something*8;
                    if (OriginOffset < offset || OriginOffset > sector.Stream.Length)
                    {
                        Valid = false;
                        return;
                    }
                    Origin = sector.Stream[OriginOffset] & 0x03;
                    //Console.WriteLine("PREFAB @ " + uid.ToString("X16") + " origin: " + Origin);
                    var prefabId = (int)BitConverter.ToUInt32(sector.Stream, offset + 57);

                    // Invalidate unreasonable amount of node counts..
                    if (nodeCount < 0x20 && nodeCount != 0)
                    {
                        Valid = true;
                        for (int i = 0; i < nodeCount; i++)
                        {
                            var nodeUid = BitConverter.ToUInt64(sector.Stream, offset + 81 + 4 + i*8);
                            //Console.WriteLine("prefab node link " + i + ": " + nodeUid.ToString("X16"));
                            // TODO: if node is in other sector..
                            if (AddNodeUID(nodeUid) == false)
                            {
                                //Console.WriteLine("Could not add prefab node " + nodeUid.ToString("X16") + " for item " + uid.ToString("X16"));
                                break;
                            }
                        }
                        PrefabNodeUID = NodesList.Keys.FirstOrDefault();
                    }

                    //Console.WriteLine("PREFAB ID: " + prefabId.ToString("X8"));
                    Prefab = sector.Mapper.LookupPrefab(prefabId);
                    if (Prefab == null)
                    {
                        //Console.WriteLine("Prefab ID: " + uid.ToString("X16") + " / " + prefabId.ToString("X") +
                        //                  " not found");
                    }
                    break;

                case Ets2ItemType.Company:
                    Valid = true;

                    // There are 3 nodes subtracted from found in sector:
                    // 1) The node of company itself
                    // 2) The node of loading area
                    // 3) The node of job
                    nodeCount = Sector.Nodes.Count(x => x.ForwardItemUID == uid) - 2;
                    BlockSize = nodeCount*8 + 109;

                    // Invalidate unreasonable amount of node counts..
                    if (nodeCount < 0x20)
                    {
                        var prefabItemUid = BitConverter.ToUInt64(sector.Stream, offset + 73);
                        var loadAreaNodeUid = BitConverter.ToUInt64(sector.Stream, offset + 93);
                        var jobAreaNodeUid = BitConverter.ToUInt64(sector.Stream, offset + 81);

                        if (AddNodeUID(loadAreaNodeUid) == false)
                        {
                            //Console.WriteLine("Could not add loading area node " + loadAreaNodeUid.ToString("X16"));
                        }
                        else if (AddNodeUID(jobAreaNodeUid) == false)
                        {
                            //Console.WriteLine("Could not add job area node" + jobAreaNodeUid.ToString("X16"));
                        }
                        else
                        {
                            for (int i = 0; i < nodeCount; i++)
                            {
                                var nodeUid = BitConverter.ToUInt64(sector.Stream, offset + 113 + i*8);
                                //Console.WriteLine("company node link " + i + ": " + nodeUid.ToString("X16"));
                                if (AddNodeUID(nodeUid) == false)
                                {
                                    //Console.WriteLine("Could not add cargo area node " + nodeUid.ToString("X16") + " for item " + uid.ToString("X16"));
                                    break;
                                }
                            }
                        }
                    }
                    else
                    {
                        Valid = false;
                    }

                    break;

                case Ets2ItemType.Building:
                    var buildingNodeUid1 = BitConverter.ToUInt64(sector.Stream, offset + 73);
                    var buildingNodeUid2 = BitConverter.ToUInt64(sector.Stream, offset + 65);
                    Valid = AddNodeUID(buildingNodeUid1) && AddNodeUID(buildingNodeUid2);
                    BlockSize = 97;
                    break;

                case Ets2ItemType.Sign:
                    var signNodeUid = BitConverter.ToUInt64(sector.Stream, offset + 65);
                    BlockSize = 153;
                    Valid = AddNodeUID(signNodeUid);
                    break;

                case Ets2ItemType.Model:
                    var modelNodeUid = BitConverter.ToUInt64(sector.Stream, offset + 81);
                    BlockSize = 101;
                    Valid = AddNodeUID(modelNodeUid);
                    break;

                case Ets2ItemType.MapOverlay:
                    var mapOverlayNodeUid = BitConverter.ToUInt64(sector.Stream, offset + 65);
                    BlockSize = 73;
                    Valid = AddNodeUID(mapOverlayNodeUid);
                    break;

                case Ets2ItemType.Ferry:
                    var ferryNodeUid = BitConverter.ToUInt64(sector.Stream, offset + 73);
                    BlockSize = 93;
                    Valid = AddNodeUID(ferryNodeUid);
                    break;

                case Ets2ItemType.CutPlane:

                    nodeCount = BitConverter.ToInt32(sector.Stream, offset + 57);

                    // Invalidate unreasonable amount of node counts..
                    if (nodeCount < 0x20)
                    {
                        Valid = true;
                        for (int i = 0; i < nodeCount; i++)
                        {
                            var nodeUid = BitConverter.ToUInt64(sector.Stream, offset + 57 + 4 + i * 8);
                            //Console.WriteLine("cut plane node " + i + ": " + nodeUid.ToString("X16"));
                            if (AddNodeUID(nodeUid) == false)
                            {
                                //Console.WriteLine("Could not add cut plane node " + nodeUid.ToString("X16") + " for item " + uid.ToString("X16"));
                                break;
                            }
                        }
                    }

                    BlockSize = 61 + 8 * nodeCount;
                    break;

                case Ets2ItemType.TrafficRule:
                    nodeCount = BitConverter.ToInt32(sector.Stream, offset + 57);

                    // Invalidate unreasonable amount of node counts..
                    if (nodeCount < 0x20)
                    {
                        Valid = true;
                        for (int i = 0; i < nodeCount; i++)
                        {
                            var nodeUid = BitConverter.ToUInt64(sector.Stream, offset + 57 + 4 + i * 8);
                            //Console.WriteLine("traffic area node " + i + ": " + nodeUid.ToString("X16"));
                            if (AddNodeUID(nodeUid) == false)
                            {
                                //Console.WriteLine("Could not add traffic area node " + nodeUid.ToString("X16") + " for item " + uid.ToString("X16"));
                                break;
                            }
                        }
                    }

                    BlockSize = 73 + 8 * nodeCount;
                    break;

                case Ets2ItemType.Trigger:
                    nodeCount = BitConverter.ToInt32(sector.Stream, offset + 57);

                    // Invalidate unreasonable amount of node counts..
                    if (nodeCount < 0x20)
                    {
                        Valid = true;
                        for (int i = 0; i < nodeCount; i++)
                        {
                            var nodeUid = BitConverter.ToUInt64(sector.Stream, offset + 57 + 4 + i * 8);
                            //Console.WriteLine("trigger node " + i + ": " + nodeUid.ToString("X16"));
                            if (AddNodeUID(nodeUid) == false)
                            {
                                //Console.WriteLine("Could not add trigger node " + nodeUid.ToString("X16") + " for item " + uid.ToString("X16"));
                                break;
                            }
                        }
                    }

                    BlockSize = 117 + 8 * nodeCount;
                    break;

                case Ets2ItemType.BusStop:
                    var busStopUid = BitConverter.ToUInt64(sector.Stream, offset + 73);
                    BlockSize = 81;
                    Valid = AddNodeUID(busStopUid);
                    break;

                case Ets2ItemType.Garage:
                    // TODO: at offset 65 there is a int '1' value.. is it a list?
                    var garageUid = BitConverter.ToUInt64(sector.Stream, offset + 69);
                    BlockSize = 85;
                    Valid = AddNodeUID(garageUid);
                    break;

                case Ets2ItemType.FuelPump:
                    var dunno2Uid = BitConverter.ToUInt64(sector.Stream, offset + 57);
                    BlockSize = 73;
                    Valid = AddNodeUID(dunno2Uid);
                    break;

                case Ets2ItemType.Dunno:
                    Valid = true;
                    break;

                case Ets2ItemType.Service:
                    var locationNodeUid = BitConverter.ToUInt64(sector.Stream, offset + 57);
                    Valid = AddNodeUID(locationNodeUid);
                    BlockSize = 73;
                    break;

                    case Ets2ItemType.City:
                    var CityID = BitConverter.ToUInt64(sector.Stream, offset + 57);
                    var NodeID = BitConverter.ToUInt64(sector.Stream, offset + 73);

                    if ((CityID >> 56) != 0)
                    {
                        break;
                    }
                    City = Sector.Mapper.LookupCityID(CityID);
                    Valid = City != string.Empty && NodeID != 0 && sector.Mapper.Nodes.ContainsKey(NodeID);
                    if (!Valid)
                    {
                        Console.WriteLine("Unknown city ID " + CityID.ToString("X16") + " at " + ItemUID.ToString("X16"));
                    }
                    else
                    {
                        StartNodeUID = NodeID;
                        //Console.WriteLine(CityID.ToString("X16") + " === " + City);
                    }
                    BlockSize = 81;
                    break;

                default:
                    Valid = false;
                    break;
            }

            //if (Valid)
            //    Console.WriteLine("Item " + uid.ToString("X16") + " (" + Type.ToString() + ") is found at " + offset.ToString("X"));
        }
Ejemplo n.º 2
0
        public Ets2Item(ulong uid, Ets2Sector sector, int offset)
        {
            ItemUID = uid;

            Navigation = new Dictionary <Ets2Item, Tuple <float, float, IEnumerable <Ets2Item> > >();

            Sector     = sector;
            FileOffset = offset;
            FilePath   = sector.FilePath;

            NodesList = new Dictionary <ulong, Ets2Node>();

            Type = (Ets2ItemType)BitConverter.ToUInt32(sector.Stream, offset);

            int nodeCount;

            switch (Type)
            {
            case Ets2ItemType.Road:
                StartNodeUID = BitConverter.ToUInt64(sector.Stream, offset + 141);
                EndNodeUID   = BitConverter.ToUInt64(sector.Stream, offset + 149);

                var lookId = BitConverter.ToUInt32(sector.Stream, offset + 61);     // unique UINT32 ID with road look
                RoadLook = Sector.Mapper.LookupRoadLookID(lookId);

                // Need to create LUT to translate road_look.sii <> ID
                // Then we can parse highway routes etc.

                HideUI = (sector.Stream[offset + 0x37] & 0x02) != 0;

                // Make sure these UID's exist in the world.
                if ((StartNodeUID != 0 && sector.Mapper.Nodes.ContainsKey(StartNodeUID)) || (EndNodeUID != 0 && sector.Mapper.Nodes.ContainsKey(EndNodeUID)))
                {
                    Valid = true;

                    var stamps = BitConverter.ToInt32(sector.Stream, offset + 433);
                    BlockSize = 437 + stamps * 24;
                }
                else
                {
                    Valid = false;
                }
                break;

            case Ets2ItemType.Prefab:
                if (uid == 0x2935de9c700704)
                {
                    //
                }

                nodeCount = BitConverter.ToInt32(sector.Stream, offset + 81);
                HideUI    = (sector.Stream[offset + 0x36] & 0x02) != 0;

                if (nodeCount > 0x20)
                {
                    Valid = false;
                    return;
                }
                var somethingOffset = offset + 85 + 8 * nodeCount;
                if (somethingOffset < offset || somethingOffset > sector.Stream.Length)
                {
                    Valid = false;
                    return;
                }
                var something = BitConverter.ToInt32(sector.Stream, somethingOffset);

                if (something < 0 || something > 32)
                {
                    Valid = false;
                    return;
                }
                var OriginOffset = offset + 0x61 + nodeCount * 8 + something * 8;
                if (OriginOffset < offset || OriginOffset > sector.Stream.Length)
                {
                    Valid = false;
                    return;
                }
                Origin = sector.Stream[OriginOffset] & 0x03;
                //Console.WriteLine("PREFAB @ " + uid.ToString("X16") + " origin: " + Origin);
                var prefabId = (int)BitConverter.ToUInt32(sector.Stream, offset + 57);

                // Invalidate unreasonable amount of node counts..
                if (nodeCount < 0x20 && nodeCount != 0)
                {
                    Valid = true;
                    for (int i = 0; i < nodeCount; i++)
                    {
                        var nodeUid = BitConverter.ToUInt64(sector.Stream, offset + 81 + 4 + i * 8);
                        //Console.WriteLine("prefab node link " + i + ": " + nodeUid.ToString("X16"));
                        // TODO: if node is in other sector..
                        if (AddNodeUID(nodeUid) == false)
                        {
                            //Console.WriteLine("Could not add prefab node " + nodeUid.ToString("X16") + " for item " + uid.ToString("X16"));
                            break;
                        }
                    }
                    PrefabNodeUID = NodesList.Keys.FirstOrDefault();
                }

                //Console.WriteLine("PREFAB ID: " + prefabId.ToString("X8"));
                Prefab = sector.Mapper.LookupPrefab(prefabId);
                if (Prefab == null)
                {
                    //Console.WriteLine("Prefab ID: " + uid.ToString("X16") + " / " + prefabId.ToString("X") +
                    //                  " not found");
                }
                break;

            case Ets2ItemType.Company:
                Valid = true;

                // There are 3 nodes subtracted from found in sector:
                // 1) The node of company itself
                // 2) The node of loading area
                // 3) The node of job
                nodeCount = Sector.Nodes.Count(x => x.ForwardItemUID == uid) - 2;
                BlockSize = nodeCount * 8 + 109;

                // Invalidate unreasonable amount of node counts..
                if (nodeCount < 0x20)
                {
                    var prefabItemUid   = BitConverter.ToUInt64(sector.Stream, offset + 73);
                    var loadAreaNodeUid = BitConverter.ToUInt64(sector.Stream, offset + 93);
                    var jobAreaNodeUid  = BitConverter.ToUInt64(sector.Stream, offset + 81);

                    if (AddNodeUID(loadAreaNodeUid) == false)
                    {
                        //Console.WriteLine("Could not add loading area node " + loadAreaNodeUid.ToString("X16"));
                    }
                    else if (AddNodeUID(jobAreaNodeUid) == false)
                    {
                        //Console.WriteLine("Could not add job area node" + jobAreaNodeUid.ToString("X16"));
                    }
                    else
                    {
                        for (int i = 0; i < nodeCount; i++)
                        {
                            var nodeUid = BitConverter.ToUInt64(sector.Stream, offset + 113 + i * 8);
                            //Console.WriteLine("company node link " + i + ": " + nodeUid.ToString("X16"));
                            if (AddNodeUID(nodeUid) == false)
                            {
                                //Console.WriteLine("Could not add cargo area node " + nodeUid.ToString("X16") + " for item " + uid.ToString("X16"));
                                break;
                            }
                        }
                    }
                }
                else
                {
                    Valid = false;
                }

                break;

            case Ets2ItemType.Building:
                var buildingNodeUid1 = BitConverter.ToUInt64(sector.Stream, offset + 73);
                var buildingNodeUid2 = BitConverter.ToUInt64(sector.Stream, offset + 65);
                Valid     = AddNodeUID(buildingNodeUid1) && AddNodeUID(buildingNodeUid2);
                BlockSize = 97;
                break;

            case Ets2ItemType.Sign:
                var signNodeUid = BitConverter.ToUInt64(sector.Stream, offset + 65);
                BlockSize = 153;
                Valid     = AddNodeUID(signNodeUid);
                break;

            case Ets2ItemType.Model:
                var modelNodeUid = BitConverter.ToUInt64(sector.Stream, offset + 81);
                BlockSize = 101;
                Valid     = AddNodeUID(modelNodeUid);
                break;

            case Ets2ItemType.MapOverlay:
                var mapOverlayNodeUid = BitConverter.ToUInt64(sector.Stream, offset + 65);
                BlockSize = 73;
                Valid     = AddNodeUID(mapOverlayNodeUid);
                break;

            case Ets2ItemType.Ferry:
                var ferryNodeUid = BitConverter.ToUInt64(sector.Stream, offset + 73);
                BlockSize = 93;
                Valid     = AddNodeUID(ferryNodeUid);
                break;

            case Ets2ItemType.CutPlane:

                nodeCount = BitConverter.ToInt32(sector.Stream, offset + 57);

                // Invalidate unreasonable amount of node counts..
                if (nodeCount < 0x20)
                {
                    Valid = true;
                    for (int i = 0; i < nodeCount; i++)
                    {
                        var nodeUid = BitConverter.ToUInt64(sector.Stream, offset + 57 + 4 + i * 8);
                        //Console.WriteLine("cut plane node " + i + ": " + nodeUid.ToString("X16"));
                        if (AddNodeUID(nodeUid) == false)
                        {
                            //Console.WriteLine("Could not add cut plane node " + nodeUid.ToString("X16") + " for item " + uid.ToString("X16"));
                            break;
                        }
                    }
                }

                BlockSize = 61 + 8 * nodeCount;
                break;

            case Ets2ItemType.TrafficRule:
                nodeCount = BitConverter.ToInt32(sector.Stream, offset + 57);

                // Invalidate unreasonable amount of node counts..
                if (nodeCount < 0x20)
                {
                    Valid = true;
                    for (int i = 0; i < nodeCount; i++)
                    {
                        var nodeUid = BitConverter.ToUInt64(sector.Stream, offset + 57 + 4 + i * 8);
                        //Console.WriteLine("traffic area node " + i + ": " + nodeUid.ToString("X16"));
                        if (AddNodeUID(nodeUid) == false)
                        {
                            //Console.WriteLine("Could not add traffic area node " + nodeUid.ToString("X16") + " for item " + uid.ToString("X16"));
                            break;
                        }
                    }
                }

                BlockSize = 73 + 8 * nodeCount;
                break;

            case Ets2ItemType.Trigger:
                nodeCount = BitConverter.ToInt32(sector.Stream, offset + 57);

                // Invalidate unreasonable amount of node counts..
                if (nodeCount < 0x20)
                {
                    Valid = true;
                    for (int i = 0; i < nodeCount; i++)
                    {
                        var nodeUid = BitConverter.ToUInt64(sector.Stream, offset + 57 + 4 + i * 8);
                        //Console.WriteLine("trigger node " + i + ": " + nodeUid.ToString("X16"));
                        if (AddNodeUID(nodeUid) == false)
                        {
                            //Console.WriteLine("Could not add trigger node " + nodeUid.ToString("X16") + " for item " + uid.ToString("X16"));
                            break;
                        }
                    }
                }

                BlockSize = 117 + 8 * nodeCount;
                break;

            case Ets2ItemType.BusStop:
                var busStopUid = BitConverter.ToUInt64(sector.Stream, offset + 73);
                BlockSize = 81;
                Valid     = AddNodeUID(busStopUid);
                break;

            case Ets2ItemType.Garage:
                // TODO: at offset 65 there is a int '1' value.. is it a list?
                var garageUid = BitConverter.ToUInt64(sector.Stream, offset + 69);
                BlockSize = 85;
                Valid     = AddNodeUID(garageUid);
                break;

            case Ets2ItemType.FuelPump:
                var dunno2Uid = BitConverter.ToUInt64(sector.Stream, offset + 57);
                BlockSize = 73;
                Valid     = AddNodeUID(dunno2Uid);
                break;

            case Ets2ItemType.Dunno:
                Valid = true;
                break;

            case Ets2ItemType.Service:
                var locationNodeUid = BitConverter.ToUInt64(sector.Stream, offset + 57);
                Valid     = AddNodeUID(locationNodeUid);
                BlockSize = 73;
                break;

            case Ets2ItemType.City:
                var CityID = BitConverter.ToUInt64(sector.Stream, offset + 57);
                var NodeID = BitConverter.ToUInt64(sector.Stream, offset + 73);

                if ((CityID >> 56) != 0)
                {
                    break;
                }
                City  = Sector.Mapper.LookupCityID(CityID);
                Valid = City != string.Empty && NodeID != 0 && sector.Mapper.Nodes.ContainsKey(NodeID);
                if (!Valid)
                {
                    Console.WriteLine("Unknown city ID " + CityID.ToString("X16") + " at " + ItemUID.ToString("X16"));
                }
                else
                {
                    StartNodeUID = NodeID;
                    //Console.WriteLine(CityID.ToString("X16") + " === " + City);
                }
                BlockSize = 81;
                break;

            default:
                Valid = false;
                break;
            }

            //if (Valid)
            //    Console.WriteLine("Item " + uid.ToString("X16") + " (" + Type.ToString() + ") is found at " + offset.ToString("X"));
        }