예제 #1
0
        public ScenarioVehicle InsertVehicle(int consistIdx, int insertPos, AvailableVehicle vehicle)
        {
            XElement consist = ScenarioXml.Root.Descendants("cConsist").Skip(consistIdx).FirstOrDefault();

            if (consist == null)
            {
                throw new Exception("Consist not found");
            }
            XElement vehicles = consist.Element("RailVehicles");

            bool atEnd = insertPos >= vehicles.Elements("cOwnedEntity").Count();

            var insert = VehicleGenerator.GenerateVehicle(
                atEnd ? vehicles.Elements("cOwnedEntity").Last() : vehicles.Elements("cOwnedEntity").ElementAt(insertPos),
                vehicle);
            var elem = insert.Item1;

            elem.Attribute(XNamespace.Xmlns + "d").Remove();

            if (atEnd)
            {
                vehicles.Add(elem);
            }
            else
            {
                vehicles.Elements("cOwnedEntity").ElementAt(insertPos).AddBeforeSelf(elem);
            }

            // Check InitialRV lists
            var cDriver = consist.Element("Driver").Element("cDriver");

            if (cDriver != null)
            {
                var e = new XElement("e");
                e.SetAttributeValue(Namespace + "type", "cDeltaString");
                e.SetValue(insert.Item2.Number);

                var initialRV = cDriver.Element("InitialRV");
                if (atEnd)
                {
                    initialRV.Add(e);
                }
                else
                {
                    var row = initialRV.Elements("e").ElementAt(insertPos);
                    if (row != null)
                    {
                        row.AddBeforeSelf(e);
                    }
                }
            }

            CreateBlueprintSetPreLoad(vehicle.Provider, vehicle.Product);

            return(insert.Item2);
        }
예제 #2
0
        public static string GetVehicleDisplayName(Vehicle vehicle)
        {
            if (_vehicleDisplayNameTable.ContainsKey(vehicle.XmlPath))
            {
                return(_vehicleDisplayNameTable[vehicle.XmlPath]);
            }
            Log.Debug("GetVehicleDisplayName: {0} is not in table, looking up..", vehicle.XmlPath);
            var binPath = Path.ChangeExtension(vehicle.XmlPath, "bin");

            try
            {
                AvailableVehicle actualVehicle = new AvailableVehicle(binPath);
                _vehicleDisplayNameTable[vehicle.XmlPath] = actualVehicle.DisplayName;
            }
            catch (Exception)
            {
                _vehicleDisplayNameTable[vehicle.XmlPath] = vehicle.Name;
            }
            return(_vehicleDisplayNameTable[vehicle.XmlPath]);
        }
예제 #3
0
        public static Tuple <XElement, ScenarioVehicle> GenerateVehicle(XElement prevElem, AvailableVehicle vehicle)
        {
            var retVehicle = new ScenarioVehicle();

            retVehicle.CopyFrom(vehicle);

            XDocument doc;

            XmlNamespaceManager mgr = new XmlNamespaceManager(new NameTable());

            mgr.AddNamespace("d", "http://www.kuju.com/TnT/2003/Delta");
            XmlParserContext ctx = new XmlParserContext(null, mgr, null, XmlSpace.Default);

            using (XmlReader reader = XmlReader.Create(new StringReader(VehicleTemplates.GetXml(vehicle.Type)), null, ctx))
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(reader);
                doc = XDocument.Parse(xmlDoc.OuterXml);
            }

            var cOwnedEntity = doc.Root;

            XElement typeSpecificElement;

            switch (vehicle.Type)
            {
            case VehicleType.Engine:
                typeSpecificElement = cOwnedEntity.Element("Component").Element("cEngine");
                break;

            case VehicleType.Wagon:
                typeSpecificElement = cOwnedEntity.Element("Component").Element("cWagon");
                break;

            case VehicleType.Tender:
                typeSpecificElement = cOwnedEntity.Element("Component").Element("cTender");
                break;

            default:
                throw new Exception("Unknown vehicle type!");
            }

            typeSpecificElement.Element("UniqueNumber").SetValue(retVehicle.Number);

            var followers     = typeSpecificElement.Element("Followers");
            var prevFollowers = prevElem.Element("Component").Descendants("Followers").First().Elements("Network-cTrackFollower");

            foreach (var cTrackFollower in prevFollowers)
            {
                var newFollower = new XElement(cTrackFollower);
                followers.Add(newFollower);
            }

            XElement cEntityContainer = cOwnedEntity
                                        .Element("Component").Element("cEntityContainer").Element("StaticChildrenMatrix");

            for (var i = 0; i < vehicle.EntityCount; i++)
            {
                var newNode = Utilities.GenerateEntityContainerItem();
                cEntityContainer.Add(newNode);
            }

            XElement cCargoComponent = cOwnedEntity
                                       .Element("Component").Element("cCargoComponent").Element("InitialLevel");

            for (var i = 0; i < vehicle.CargoCount; i++)
            {
                var newNode = Utilities.GenerateCargoComponentItem(
                    vehicle.CargoComponents[i].Item1,
                    vehicle.CargoComponents[i].Item2);
                cCargoComponent.Add(newNode);
            }

            var cPosOri = new XElement(prevElem.Element("Component").Element("cPosOri"));

            cOwnedEntity.Element("Component").Add(cPosOri);

            cOwnedEntity.Element("Name").SetValue(vehicle.Name);

            var idElements = cOwnedEntity
                             .DescendantsAndSelf()
                             .Where(elem => elem.Attribute(Namespace + "id") != null);

            Random idRandom = new Random();

            foreach (var elem in idElements)
            {
                var id = idRandom.Next(100000000, 999999999);
                elem.SetAttributeValue(Namespace + "id", id);
            }

            var entityId = cOwnedEntity.Element("EntityID");

            entityId.Add(Utilities.GenerateCGUID());

            XElement cAbsoluteBlueprintID = cOwnedEntity
                                            .Element("BlueprintID").Element("iBlueprintLibrary-cAbsoluteBlueprintID");

            cAbsoluteBlueprintID
            .Element("BlueprintSetID").Element("iBlueprintLibrary-cBlueprintSetID").Element("Provider")
            .SetValue(vehicle.Provider);
            cAbsoluteBlueprintID
            .Element("BlueprintSetID").Element("iBlueprintLibrary-cBlueprintSetID").Element("Product")
            .SetValue(vehicle.Product);
            cAbsoluteBlueprintID.Element("BlueprintID").SetValue(vehicle.BlueprintId);

            if (vehicle.IsReskin)
            {
                cAbsoluteBlueprintID = cOwnedEntity
                                       .Element("ReskinBlueprintID").Element("iBlueprintLibrary-cAbsoluteBlueprintID");
                cAbsoluteBlueprintID
                .Element("BlueprintSetID").Element("iBlueprintLibrary-cBlueprintSetID").Element("Provider")
                .SetValue(vehicle.ReskinProvider);
                cAbsoluteBlueprintID
                .Element("BlueprintSetID").Element("iBlueprintLibrary-cBlueprintSetID").Element("Product")
                .SetValue(vehicle.ReskinProduct);
                cAbsoluteBlueprintID.Element("BlueprintID").SetValue(vehicle.ReskinBlueprintId);
            }

            return(new Tuple <XElement, ScenarioVehicle>(cOwnedEntity, retVehicle));
        }
예제 #4
0
        public void ReplaceVehicle(int consistIdx, int vehicleIdx, AvailableVehicle newVehicle)
        {
            // Locate the consist and vehicle
            XElement consist = ScenarioXml.Root.Descendants("cConsist").Skip(consistIdx).FirstOrDefault();

            if (consist == null)
            {
                throw new Exception("Consist not found");
            }
            XElement vehicle = consist.Element("RailVehicles").Descendants("cOwnedEntity").Skip(vehicleIdx).FirstOrDefault();

            if (vehicle == null)
            {
                throw new Exception("Vehicle not found");
            }

            // Update blueprint ID in Scenario.bin
            XElement blueprintID     = vehicle.Element("BlueprintID").Element("iBlueprintLibrary-cAbsoluteBlueprintID");
            var      origBlueprintID = blueprintID.Element("BlueprintID").Value;

            blueprintID.Element("BlueprintSetID").Element("iBlueprintLibrary-cBlueprintSetID").Element("Provider").SetValue(newVehicle.Provider);
            blueprintID.Element("BlueprintSetID").Element("iBlueprintLibrary-cBlueprintSetID").Element("Product").SetValue(newVehicle.Product);
            blueprintID.Element("BlueprintID").SetValue(newVehicle.BlueprintId);
            vehicle.Element("Name").SetValue(newVehicle.Name);

            // Update reskin info
            XElement reskinBlueprintID = vehicle.Element("ReskinBlueprintID").Element("iBlueprintLibrary-cAbsoluteBlueprintID");

            if (newVehicle.IsReskin)
            {
                Log.Debug("ReplaceVehicle: Reskin set to {0}", newVehicle.ReskinXmlPath);
                reskinBlueprintID.Element("BlueprintSetID").Element("iBlueprintLibrary-cBlueprintSetID").Element("Provider").SetValue(newVehicle.ReskinProvider);
                reskinBlueprintID.Element("BlueprintSetID").Element("iBlueprintLibrary-cBlueprintSetID").Element("Product").SetValue(newVehicle.ReskinProduct);
                reskinBlueprintID.Element("BlueprintID").SetValue(newVehicle.ReskinBlueprintId);
            }
            else
            {
                // Remove reskin info
                Log.Debug("ReplaceVehicle: Remove reskin info");
                reskinBlueprintID.Element("BlueprintSetID").Element("iBlueprintLibrary-cBlueprintSetID").Element("Provider").SetValue("");
                reskinBlueprintID.Element("BlueprintSetID").Element("iBlueprintLibrary-cBlueprintSetID").Element("Product").SetValue("");
                reskinBlueprintID.Element("BlueprintID").SetValue("");
            }

            // Update engine and wagon dependent parameters
            XElement cElement = vehicle.Descendants().Where(element => element.Name == "cWagon" || element.Name == "cEngine" || element.Name == "cTender").FirstOrDefault();

            if (cElement == null)
            {
                throw new Exception("Cannot find cWagon or cEngine element!");
            }

            if (cElement.Name == "cEngine" && newVehicle.Type != VehicleType.Engine)
            {
                // We should remove additional nodes for engines
                cElement.Elements()
                .Where(element => element.Name == "DisabledEngine" || element.Name == "AWSTimer" || element.Name == "AWSExpired" || element.Name == "TPWSDistance")
                .Remove();

                vehicle.Element("Component").Element("cEngineSimContainer").Remove();
            }
            if (cElement.Name == "cTender" && newVehicle.Type != VehicleType.Tender)
            {
                // We should remove additional nodes for tenders
                cElement.Elements()
                .Where(element => element.Name == "CoalLevel" || element.Name == "WaterLevel")
                .Remove();
            }

            if (newVehicle.Type == VehicleType.Wagon)
            {
                cElement.Name = "cWagon";
            }
            else if (newVehicle.Type == VehicleType.Engine && cElement.Name != "cEngine")
            {
                // We should create additional nodes for engines
                cElement.Name = "cEngine";
                Log.Debug("Creating additional nodes for replacement {0}", newVehicle.DisplayName);
                XElement disabledEngine = new XElement("DisabledEngine");
                disabledEngine.SetAttributeValue(Namespace + "type", "bool");
                disabledEngine.SetValue("0");

                XElement awsTimer = new XElement("AWSTimer");
                awsTimer.SetAttributeValue(Namespace + "type", "sFloat32");
                awsTimer.SetAttributeValue(Namespace + "alt_encoding", "0000000000000000");
                awsTimer.SetAttributeValue(Namespace + "precision", "string");
                awsTimer.SetValue("0");

                XElement awsExpired = new XElement("AWSExpired");
                awsExpired.SetAttributeValue(Namespace + "type", "bool");
                awsExpired.SetValue("0");

                XElement tpwsDistance = new XElement("TPWSDistance");
                tpwsDistance.SetAttributeValue(Namespace + "type", "sFloat32");
                tpwsDistance.SetAttributeValue(Namespace + "alt_encoding", "0000000000000000");
                tpwsDistance.SetAttributeValue(Namespace + "precision", "string");
                tpwsDistance.SetValue("0");

                cElement.Add(disabledEngine, awsTimer, awsExpired, tpwsDistance);

                Random idRandom = new Random();

                int id;
                do
                {
                    id = idRandom.Next(100000000, 999999999);
                } while (ScenarioXml.Descendants().Where(elem => (elem.Attribute(Namespace + "id") != null && elem.Attribute(Namespace + "id").Value == id.ToString())).Any());
                XElement cEngineSimContainer = new XElement("cEngineSimContainer");
                cEngineSimContainer.SetAttributeValue(Namespace + "id", id.ToString());
                vehicle.Element("Component").Add(cEngineSimContainer);
            }
            else if (newVehicle.Type == VehicleType.Tender && cElement.Name != "cTender")
            {
                cElement.Name = "cTender";
                Log.Debug("Creating additional tender nodes for replacement {0}", newVehicle.DisplayName);

                XElement coalLevel = new XElement("CoalLevel");
                coalLevel.SetAttributeValue(Namespace + "type", "sFloat32");
                coalLevel.SetAttributeValue(Namespace + "alt_encoding", "0000000000000000");
                coalLevel.SetAttributeValue(Namespace + "precision", "string");
                coalLevel.SetValue("0");

                XElement waterLevel = new XElement("WaterLevel");
                waterLevel.SetAttributeValue(Namespace + "type", "sFloat32");
                waterLevel.SetAttributeValue(Namespace + "alt_encoding", "0000000000000000");
                waterLevel.SetAttributeValue(Namespace + "precision", "string");
                waterLevel.SetValue("0");

                cElement.Add(coalLevel, waterLevel);
            }

            // Cargo component count matching
            XElement cCargoComponent = vehicle.Element("Component").Element("cCargoComponent").Element("InitialLevel");
            int      cargoCount      = cCargoComponent.Elements().Count();

            if (newVehicle.CargoCount > cargoCount)
            {
                Log.Debug("Need to create cargo initial level holders {0} -> {1}", cargoCount, newVehicle.CargoCount);
                for (int i = cargoCount; i < newVehicle.CargoCount; ++i)
                {
                    XElement newNode = new XElement("e");
                    newNode.SetAttributeValue(Namespace + "type", "sFloat32");
                    newNode.SetAttributeValue(Namespace + "alt_encoding", "0000000000000000");
                    newNode.SetAttributeValue(Namespace + "precision", "string");
                    newNode.SetValue("0");
                    cCargoComponent.Add(newNode);
                }
            }
            else if (newVehicle.CargoCount < cargoCount)
            {
                Log.Debug("Need to remove cargo initial level holders {0} -> {1}", cargoCount, newVehicle.CargoCount);
                cCargoComponent.Elements().Take(cargoCount - newVehicle.CargoCount).Remove();
            }

            // Entity container count matching
            XElement cEntityContainer = vehicle.Element("Component").Element("cEntityContainer").Element("StaticChildrenMatrix");
            int      entityCount      = cEntityContainer.Elements().Count();

            if (newVehicle.EntityCount > entityCount)
            {
                Log.Debug("Need to add entities {0} -> {1}", entityCount, newVehicle.EntityCount);
                for (int i = entityCount; i < newVehicle.EntityCount; ++i)
                {
                    XElement newNode = new XElement("e");
                    newNode.SetAttributeValue(Namespace + "numElements", "16");
                    newNode.SetAttributeValue(Namespace + "elementType", "sFloat32");
                    newNode.SetAttributeValue(Namespace + "precision", "string");
                    newNode.SetValue("1.0000000 0.0000000 0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 0.0000000 0.0000000 1.0000000");
                    cEntityContainer.Add(newNode);
                }
            }
            else if (newVehicle.EntityCount < entityCount)
            {
                Log.Debug("Need to remove entities {0} -> {1}", entityCount, newVehicle.EntityCount);
                cEntityContainer.Elements().Take(entityCount - newVehicle.EntityCount).Remove();
            }

            // If the consist is driven by the player, loco name in ScenarioProperties.xml should be updated
            if (consist.Element("Driver").Element("cDriver") != null)
            {
                XElement cDriver = consist.Element("Driver").Element("cDriver");
                if (cDriver.Element("PlayerDriver") != null)
                {
                    if (cDriver.Element("PlayerDriver").Value == "1")
                    {
                        Log.Debug("Train is driven by player; checking whether the loco is swapped");
                        var      key = cDriver.Element("ServiceName").Descendants("Key").First().Value;
                        XElement sDriverFrontEndDetails = ScenarioProperties.Root.Element("FrontEndDriverList")
                                                          .Elements("sDriverFrontEndDetails").Where(element => element.Element("ServiceName").Element("Localisation-cUserLocalisedString").Element("Key").Value == key).FirstOrDefault();
                        if (sDriverFrontEndDetails == null)
                        {
                            Log.Debug("Could not find sDriverFrontEndDetails with key {0}!", key);
                        }
                        else
                        {
                            var consistLocoBlueprintId = sDriverFrontEndDetails.Element("LocoBP").Descendants("BlueprintID").First().Value;
                            if (consistLocoBlueprintId == origBlueprintID)
                            {
                                Log.Debug("Update new sDriverFrontEndDetails to Blueprint ID {0}", newVehicle.BlueprintId);
                                XElement destLocalisedString = sDriverFrontEndDetails.Element("LocoName").Element("Localisation-cUserLocalisedString");
                                XElement origLocalisedString = newVehicle.NameLocalisedString;
                                Utilities.CopyUserLocalisedString(destLocalisedString, origLocalisedString);
                                sDriverFrontEndDetails.Element("LocoBP").Descendants("Provider").First().Value    = newVehicle.Provider;
                                sDriverFrontEndDetails.Element("LocoBP").Descendants("Product").First().Value     = newVehicle.Product;
                                sDriverFrontEndDetails.Element("LocoBP").Descendants("BlueprintID").First().Value = newVehicle.BlueprintId;
                                sDriverFrontEndDetails.Element("LocoAuthor").Value = newVehicle.Provider;
                                string newVehicleXmlPath = newVehicle.XmlPath;
                                sDriverFrontEndDetails.Element("FilePath").Value = newVehicleXmlPath.Substring(0, newVehicleXmlPath.LastIndexOf('\\'));
                            }
                        }
                    }
                }
            }

            CreateBlueprintSetPreLoad(newVehicle.Provider, newVehicle.Product);
            if (newVehicle.IsReskin)
            {
                CreateBlueprintSetPreLoad(newVehicle.ReskinProvider, newVehicle.ReskinProduct);
            }
        }