Beispiel #1
0
        private static void WriteTerminalsAndSpawnPads(List <PlanetSideObject> _objList, List <PlanetSideObject> children, PlanetSideObject parent, StreamWriter logWriter)
        {
            var terminalTypes             = new[] { "order_terminal", "spawn_terminal", "cert_terminal", "order_terminal", "vanu_equipment_term" };
            var terminalTypesWithSpawnPad = new[] { "ground_vehicle_terminal", "air_vehicle_terminal", "vehicle_terminal",
                                                    "vehicle_terminal_combined", "dropship_vehicle_terminal", "vanu_air_vehicle_term", "vanu_vehicle_term" };

            var allTerminalTypes = terminalTypes.Concat(terminalTypesWithSpawnPad);

            var spawnPadList = children.Where(x => x.ObjectType == "mb_pad_creation" ||
                                              x.ObjectType == "dropship_pad_doors" ||
                                              x.ObjectType == "vanu_vehicle_creation_pad")
                               .ToList();

            foreach (var terminal in children.Where(x => allTerminalTypes.Contains(x.ObjectType)))
            {
                // SoE in their infinite wisdom decided to remap vehicle_terminal to vehicle_terminal_combined in certain cases in the game_objects.adb file.
                // As such, we have to work around it.

                /*
                 *  startup.pak-out/game_objects.adb.lst:1097:add_property amp_station child_remap vehicle_terminal vehicle_terminal_combined
                 *  startup.pak-out/game_objects.adb.lst:7654:add_property comm_station child_remap vehicle_terminal vehicle_terminal_combined
                 *  startup.pak-out/game_objects.adb.lst:7807:add_property cryo_facility child_remap vehicle_terminal vehicle_terminal_combined
                 */
                if (terminal.ObjectType == "vehicle_terminal" &&
                    (parent.ObjectType == "amp_station" ||
                     parent.ObjectType == "comm_station" ||
                     parent.ObjectType == "cryo_facility"))
                {
                    terminal.ObjectType = "vehicle_terminal_combined";
                }

                // The scala codebase also uses ground_vehicle_terminal as the object type instead of vehicle_terminal, so we'll map to that for now.
                if (terminal.ObjectType == "vehicle_terminal")
                {
                    terminal.ObjectType = "ground_vehicle_terminal";
                }

                logWriter.WriteLine($"LocalObject({terminal.GUID}, Terminal.Constructor(Vector3({terminal.AbsX}f, {terminal.AbsY}f, {terminal.AbsZ}f), {terminal.ObjectType}), owning_building_guid = {_objList.SingleOrDefault(x => x.Id == terminal.Owner)?.GUID ?? 0})");

                if (terminalTypesWithSpawnPad.Contains(terminal.ObjectType))
                {
                    // find closest spawn pad to this terminal
                    var searchDistance  = 25;
                    var closestSpawnPad = spawnPadList.Select(x => new {
                        Distance = DistanceN(new float[] { terminal.AbsX, terminal.AbsY, terminal.AbsZ },
                                             new float[] { x.AbsX, x.AbsY, x.AbsZ }),
                        x
                    }
                                                              ).OrderBy(x => x.Distance).First(x => x.Distance <= searchDistance).x;

                    // It appears that spawn pads have a default rotation that it +90 degrees from where it should be, presumably the model is rotated differently to the expected orientation - this can be handled here in the map generation
                    // On top of that, some spawn pads also have an additional rotation (vehiclecreationzorientoffset) when spawning vehicles set in game_objects.adb.lst - this should be handled on the Scala side
                    var adjustedYaw = closestSpawnPad.YawDegrees - 90;

                    logWriter.WriteLine($"LocalObject({closestSpawnPad.GUID}, VehicleSpawnPad.Constructor(Vector3({closestSpawnPad.AbsX}f, {closestSpawnPad.AbsY}f, {closestSpawnPad.AbsZ}f), {closestSpawnPad.ObjectType}, Vector3(0, 0,{adjustedYaw})), owning_building_guid = {_objList.Single(x => x.Id == closestSpawnPad.Owner).GUID}, terminal_guid = {terminal.GUID})");
                }
            }
        }
Beispiel #2
0
        private static void ProcessLSTPseRelativeObjects(List <Pse_RelativeObject> pseRelativeObjects, List <PlanetSideObject> identifiableObjects, PlanetSideObject ownerObject, ref int id)
        {
            foreach (var line in pseRelativeObjects)
            {
                if (!_objectsWithGuids.Contains(line.ObjectName.ToLower()))
                {
                    continue;
                }
                Console.WriteLine($"Processing sub-object {line.ObjectName}");

                var uber = _ubrData.Single(x =>
                                           x.Value.Entries.Select(y => y.Name).Contains(line.ObjectName.ToLower()));
                var mesh = UBRReader.GetMeshSystem(line.ObjectName, uber.Value);

                var(relativeObjectRotX, relativeObjectRotY)  = MathFunctions.RotateXY(line.RelX, line.RelY, MathFunctions.DegreesToRadians(ownerObject.YawDegrees));
                (float x, float y, float z)relativeObjectPos = (relativeObjectRotX + ownerObject.AbsX, relativeObjectRotY + ownerObject.AbsY, line.RelZ + ownerObject.AbsZ);

                var relativeObjectRotationDegrees = MathFunctions.PS1RotationToDegrees((int)line.Yaw);

                // Process any sub-objects in the ubr file for this relative object (e.g. bfr_door within bfr_building ubr)
                foreach (var meshItem in mesh.PortalSystem.MeshItems)
                {
                    if (!_objectsWithGuids.Contains(meshItem.AssetName))
                    {
                        continue;
                    }

                    var subObjectRotationDegrees = MathFunctions.TransformToRotationDegrees(meshItem.Transform);

                    var(subObjectRotX, subObjectRotY) = MathFunctions.RotateXY(meshItem.Transform[12], meshItem.Transform[13], MathFunctions.DegreesToRadians(ownerObject.YawDegrees + relativeObjectRotationDegrees));
                    identifiableObjects.Add(new PlanetSideObject
                    {
                        Id            = id,
                        ObjectName    = meshItem.AssetName,
                        ObjectType    = meshItem.AssetName,
                        Owner         = ownerObject.Id,
                        AbsX          = relativeObjectPos.x + subObjectRotX,
                        AbsY          = relativeObjectPos.y + subObjectRotY,
                        AbsZ          = relativeObjectPos.z + line.RelZ,
                        IsChildObject = true
                    });
                    id++;
                }
            }
        }
Beispiel #3
0
        private static void WriteSpawnTubes(List <PlanetSideObject> _objList, List <PlanetSideObject> children, PlanetSideObject parent, StreamWriter logWriter)
        {
            var respawnTubeTypes = new[] { "respawn_tube", "mb_respawn_tube", "redoubt_floor", "vanu_spawn_room_pad" };

            foreach (var spawnTube in children.Where(x => respawnTubeTypes.Contains(x.ObjectType)))
            {
                var tubeType = "";
                if (_towerTypes.Contains(parent?.ObjectType))
                {
                    tubeType = "respawn_tube_tower";
                }
                else if (parent?.ObjectType.Contains("VT_building", StringComparison.OrdinalIgnoreCase) ?? false)
                {
                    tubeType = "respawn_tube_sanctuary";
                }

                logWriter.WriteLine(tubeType == ""
                    ? $"LocalObject({spawnTube.GUID}, SpawnTube.Constructor(Vector3({spawnTube.AbsX}f, {spawnTube.AbsY}f, {spawnTube.AbsZ}f), Vector3(0, 0, {spawnTube.YawDegrees})), owning_building_guid = {_objList.Single(x => x.Id == spawnTube.Owner).GUID})"
                    : $"LocalObject({spawnTube.GUID}, SpawnTube.Constructor(Vector3({spawnTube.AbsX}f, {spawnTube.AbsY}f, {spawnTube.AbsZ}f), {tubeType}, Vector3(0, 0, {spawnTube.YawDegrees})), owning_building_guid = {_objList.Single(x => x.Id == spawnTube.Owner).GUID})");
            }
        }
Beispiel #4
0
        private static void ProcessObject(List <PlanetSideObject> identifiableObjects, MapObject entry, ref int id, int?mapId, bool isTopLevel = false)
        {
            if (!_objectsWithGuids.Contains(entry.ObjectType))
            {
                return;
            }
            Console.WriteLine($"Processing {entry.ObjectType}");

            // Load the relevant *.lst files for this object
            var(peHiddens, peEdits, pseRelativeObjects) = LSTReader.ReadLSTFile(_planetsideModReadyFolder, entry.ObjectType, entry.LstType);

            // Get the root mesh for this object
            var uberData = _ubrData.First(x =>
                                          x.Value.Entries.Select(y => y.Name).Contains(entry.ObjectType, StringComparer.OrdinalIgnoreCase));

            var objectRotationDegrees = MathFunctions.PS1RotationToDegrees(entry.HorizontalRotation);
            var objectRotationRadians = MathFunctions.DegreesToRadians(objectRotationDegrees);

            var entryObject = new PlanetSideObject
            {
                Id            = id,
                ObjectName    = entry.ObjectName,
                ObjectType    = entry.ObjectType,
                AbsX          = entry.HorizontalPosition,
                AbsY          = entry.VerticalPosition,
                AbsZ          = entry.HeightPosition,
                YawDegrees    = objectRotationDegrees,
                MapID         = mapId,
                IsChildObject = !isTopLevel
            };

            identifiableObjects.Add(entryObject);
            id++;

            var parentRotationClockwise =
                MathFunctions.CounterClockwiseToClockwiseRotation(entry.HorizontalRotation);

            // Get the sub-entities from the UBR file that would have a GUID within this object
            var baseMesh = UBRReader.GetMeshSystem(entry.ObjectType, uberData.Value);

            foreach (var meshItem in baseMesh.PortalSystem.MeshItems)
            {
                // If it's not an entity that would be assigned a GUID we don't care about it and should skip it
                if (!_objectsWithGuids.Contains(meshItem.AssetName, StringComparer.OrdinalIgnoreCase))
                {
                    continue;
                }

                // If a line is in the pe_hidden list it should be removed from the game world e.g. Neti pad_landing is removed where the BFR building now exists
                if (peHiddens.Any(x => x.InstanceName == meshItem.InstanceName))
                {
                    continue;
                }

                var(rotX, rotY) = MathFunctions.RotateXY(meshItem.Transform[12], meshItem.Transform[13],
                                                         objectRotationRadians);
                var meshItemYaw = MathFunctions.TransformToRotationDegrees(meshItem.Transform);

                // Convert from CCW to CW and apply 180 degree offset
                var yaw = parentRotationClockwise + (360 - (180 - meshItemYaw));

                identifiableObjects.Add(new PlanetSideObject
                {
                    Id            = id,
                    ObjectName    = meshItem.AssetName,
                    ObjectType    = meshItem.AssetName,
                    Owner         = entryObject.Id,
                    AbsX          = entry.HorizontalPosition + rotX,
                    AbsY          = entry.VerticalPosition + rotY,
                    AbsZ          = entry.HeightPosition + meshItem.Transform[14],
                    YawDegrees    = MathFunctions.NormalizeDegrees((int)yaw),
                    IsChildObject = true
                });
                id++;
            }

            ProcessLSTPeEdits(peEdits, identifiableObjects, objectRotationRadians, baseX: entry.HorizontalPosition, baseY: entry.VerticalPosition, baseZ: entry.HeightPosition, ownerId: entryObject.Id, id: ref id);

            ProcessLSTPseRelativeObjects(pseRelativeObjects, identifiableObjects, ownerObject: entryObject, id: ref id);
        }