public CorridorBuilderMetadata(NitroxVector3 position, int rotation, bool hasTargetBase, NitroxInt3 targetCell) : base(typeof(BaseAddCorridorGhost))
 {
     Position      = position;
     Rotation      = rotation;
     HasTargetBase = hasTargetBase;
     Cell          = targetCell;
 }
        protected override void Execute(CallArgs args)
        {
            NitroxInt3    batchId  = new NitroxInt3(args.Get <int>(0), args.Get <int>(1), args.Get <int>(2));
            List <Entity> entities = batchEntitySpawner.LoadUnspawnedEntities(batchId);

            SendMessage(args.Sender, $"Loaded {entities.Count} entities from batch {batchId}");
        }
Exemple #3
0
        /**
         * It is suspected that 'cache' is a misnomer carried over from when UWE was actually doing procedurally
         * generated worlds.  In the final release, this 'cache' has simply been baked into a final version that
         * we can parse.
         */
        private void ParseCacheCells(NitroxInt3 batchId, string fileName, List <EntitySpawnPoint> spawnPoints)
        {
            using (Stream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                CellsFileHeader cellsFileHeader = serializer.Deserialize <CellsFileHeader>(stream);

                for (int cellCounter = 0; cellCounter < cellsFileHeader.NumCells; cellCounter++)
                {
                    CellHeaderEx cellHeader = serializer.Deserialize <CellHeaderEx>(stream);


                    byte[] serialData = new byte[cellHeader.DataLength];
                    stream.Read(serialData, 0, cellHeader.DataLength);
                    ParseGameObjectsWithHeader(serialData, batchId, cellHeader.CellId, cellHeader.Level, spawnPoints, out bool wasLegacy);

                    if (!wasLegacy)
                    {
                        byte[] legacyData = new byte[cellHeader.LegacyDataLength];
                        stream.Read(legacyData, 0, cellHeader.LegacyDataLength);
                        ParseGameObjectsWithHeader(legacyData, batchId, cellHeader.CellId, cellHeader.Level, spawnPoints, out wasLegacy);

                        byte[] waiterData = new byte[cellHeader.WaiterDataLength];
                        stream.Read(waiterData, 0, cellHeader.WaiterDataLength);
                        ParseGameObjectsFromStream(new MemoryStream(waiterData), batchId, cellHeader.CellId, cellHeader.Level, spawnPoints);
                    }
                }
            }
        }
Exemple #4
0
        public void Equals()
        {
            NitroxInt3 other1 = new NitroxInt3(5, 10, 15);
            NitroxInt3 other2 = new NitroxInt3(15, 10, 5);

            int3.Equals(other1).Should().BeTrue();
            int3.Equals(other2).Should().BeFalse();
        }
Exemple #5
0
        public List <EntitySpawnPoint> ParseBatchData(NitroxInt3 batchId)
        {
            List <EntitySpawnPoint> spawnPoints = new List <EntitySpawnPoint>();

            ParseFile(batchId, "CellsCache", "baked-", "", spawnPoints);

            return(spawnPoints);
        }
Exemple #6
0
        public void LoadAllUnspawnedEntities(System.Threading.CancellationToken token)
        {
            IMap map = NitroxServiceLocator.LocateService <IMap>();

            int totalEntites = 0;

            for (int x = 0; x < map.DimensionsInBatches.X; x++)
            {
                token.ThrowIfCancellationRequested();
                for (int y = 0; y < map.DimensionsInBatches.Y; y++)
                {
                    for (int z = 0; z < map.DimensionsInBatches.Z; z++)
                    {
                        NitroxInt3    batchId         = new NitroxInt3(x, y, z);
                        List <Entity> spawnedEntities = batchEntitySpawner.LoadUnspawnedEntities(batchId, true);

                        lock (entitiesById)
                        {
                            lock (phasingEntitiesByAbsoluteCell)
                            {
                                foreach (Entity entity in spawnedEntities)
                                {
                                    if (entity.ParentId != null)
                                    {
                                        Optional <Entity> opEnt = GetEntityById(entity.ParentId);

                                        if (opEnt.HasValue)
                                        {
                                            entity.Transform.SetParent(opEnt.Value.Transform);
                                        }
                                        else
                                        {
                                            Log.Error("Parent not Found! Are you sure it exists? " + entity.ParentId);
                                        }
                                    }

                                    List <Entity> entitiesInCell = GetEntities(entity.AbsoluteEntityCell);
                                    entitiesInCell.Add(entity);

                                    entitiesById.Add(entity.Id, entity);
                                    totalEntites++;
                                }
                            }
                        }

                        Log.Debug($"Loaded {spawnedEntities.Count} entities from batch ({x}, {y}, {z})");
                    }
                }

                if (totalEntites > 0)
                {
                    Log.Info($"Loading: {(int)((totalEntites/ 504732.0) * 100)}%");
                }
            }
        }
Exemple #7
0
        public AbsoluteEntityCell(NitroxVector3 worldSpace, int level)
        {
            Level = level;

            NitroxVector3 localPosition = (worldSpace + Map.Main.BatchDimensionCenter) / Map.Main.BatchSize;

            BatchId = NitroxInt3.Floor(localPosition);

            NitroxVector3 cell = (localPosition - BatchId) * GetCellsPerBlock();

            CellId = NitroxInt3.Floor(new NitroxVector3(cell.X + 0.0001f, cell.Y + 0.0001f, cell.Z + 0.0001f));
        }
        public Optional <GameObject> Spawn(Entity entity, Optional <GameObject> parent, EntityCell cellRoot)
        {
            NitroxInt3 cellId  = entity.AbsoluteEntityCell.CellId;
            NitroxInt3 batchId = entity.AbsoluteEntityCell.BatchId;

            cellRoot.liveRoot.name = $"CellRoot {cellId.X}, {cellId.Y}, {cellId.Z}; Batch {batchId.X}, {batchId.Y}, {batchId.Z}";

            NitroxEntity.SetNewId(cellRoot.liveRoot, entity.Id);

            LargeWorldStreamer.main.cellManager.QueueForAwake(cellRoot);

            return(Optional.OfNullable(cellRoot.liveRoot));
        }
Exemple #9
0
        private void ParseGameObjectsFromStream(Stream stream, NitroxInt3 batchId, NitroxInt3 cellId, int level, List <EntitySpawnPoint> spawnPoints)
        {
            LoopHeader gameObjectCount = serializer.Deserialize <LoopHeader>(stream);

            for (int goCounter = 0; goCounter < gameObjectCount.Count; goCounter++)
            {
                GameObject gameObject = DeserializeGameObject(stream);

                if (gameObject.TotalComponents > 0)
                {
                    AbsoluteEntityCell absoluteEntityCell = new AbsoluteEntityCell(batchId, cellId, level);
                    NitroxTransform    transform          = gameObject.GetComponent <NitroxTransform>();
                    spawnPoints.AddRange(entitySpawnPointFactory.From(absoluteEntityCell, transform, gameObject));
                }
            }
        }
Exemple #10
0
        public void ParseFile(NitroxInt3 batchId, string pathPrefix, string prefix, string suffix, List <EntitySpawnPoint> spawnPoints)
        {
            string subnauticaPath = NitroxUser.SubnauticaPath;

            if (string.IsNullOrEmpty(subnauticaPath))
            {
                return;
            }

            string path     = Path.Combine(subnauticaPath, "Subnautica_Data", "StreamingAssets", "SNUnmanagedData", "Build18");
            string fileName = Path.Combine(path, pathPrefix, $"{prefix}batch-cells-{batchId.X}-{batchId.Y}-{batchId.Z}{suffix}.bin");

            if (!File.Exists(fileName))
            {
                return;
            }

            ParseCacheCells(batchId, fileName, spawnPoints);
        }
Exemple #11
0
        public List <Entity> LoadUnspawnedEntities(NitroxInt3 batchId)
        {
            lock (parsedBatches)
            {
                if (parsedBatches.Contains(batchId))
                {
                    return(new List <Entity>());
                }

                parsedBatches.Add(batchId);
            }

            DeterministicBatchGenerator deterministicBatchGenerator = new DeterministicBatchGenerator(seed, batchId);
            List <EntitySpawnPoint>     spawnPoints = batchCellsParser.ParseBatchData(batchId);
            List <Entity> entities = SpawnEntities(spawnPoints, deterministicBatchGenerator);

            if (entities.Count == 0)
            {
                lock (emptyBatchesLock)
                {
                    emptyBatches.Add(batchId);
                }
            }
            else
            {
                Log.Info("Spawning " + entities.Count + " entities from " + spawnPoints.Count + " spawn points in batch " + batchId);
            }

            for (int x = 0; x < entities.Count; x++) // Throws on duplicate Entities already but nice to know which ones
            {
                for (int y = 0; y < entities.Count; y++)
                {
                    if (entities[x] == entities[y] && x != y)
                    {
                        Log.Error("Duplicate Entity detected! " + entities[x]);
                    }
                }
            }

            return(entities);
        }
Exemple #12
0
        public void ParseFile(NitroxInt3 batchId, string pathPrefix, string prefix, string suffix, List <EntitySpawnPoint> spawnPoints)
        {
            List <string> errors         = new List <string>();
            string        subnauticaPath = GameInstallationFinder.Instance.FindGame(errors);

            if (subnauticaPath == null)
            {
                Log.Error($"Could not locate Subnautica installation directory: {Environment.NewLine}{string.Join(Environment.NewLine, errors)}");
                return;
            }

            string path     = Path.Combine(subnauticaPath, "Subnautica_Data", "StreamingAssets", "SNUnmanagedData", "Build18");
            string fileName = Path.Combine(path, pathPrefix, $"{prefix}batch-cells-{batchId.X}-{batchId.Y}-{batchId.Z}{suffix}.bin");

            if (!File.Exists(fileName))
            {
                return;
            }

            ParseCacheCells(batchId, fileName, spawnPoints);
        }
Exemple #13
0
        private void ParseGameObjectsWithHeader(byte[] data, NitroxInt3 batchId, NitroxInt3 cellId, int level, List <EntitySpawnPoint> spawnPoints, out bool wasLegacy)
        {
            wasLegacy = false;

            if (data.Length == 0)
            {
                return;
            }

            Stream stream = new MemoryStream(data);

            StreamHeader header = serializer.Deserialize <StreamHeader>(stream);

            if (ReferenceEquals(header, null))
            {
                return;
            }

            ParseGameObjectsFromStream(stream, batchId, cellId, level, spawnPoints);

            wasLegacy = (header.Version < 9);

            return;
        }
Exemple #14
0
 public DeterministicBatchGenerator(string seed, NitroxInt3 batchId)
 {
     random = new Random(seed.GetHashCode() + batchId.GetHashCode());
 }
Exemple #15
0
 public void Setup()
 {
     int3 = new NitroxInt3(5, 10, 15);
 }
Exemple #16
0
 public void Floor()
 {
     NitroxInt3.Floor(5.1f, 10.4f, 15.5f).Should().Be(int3);
 }
Exemple #17
0
 public void Ceil()
 {
     NitroxInt3.Ceil(4.1f, 9.4f, 14.5f).Should().Be(int3);
 }
Exemple #18
0
 public static Int3 ToUnity(this NitroxInt3 v)
 {
     return(new Int3(v.X, v.Y, v.Z));
 }
Exemple #19
0
 public NitroxInt3 GetCellSize(NitroxInt3 blocksPerBatch)
 {
     return(GetCellSize(Level, blocksPerBatch));
 }
Exemple #20
0
 public AbsoluteEntityCell(NitroxInt3 batchId, NitroxInt3 cellId, int level)
 {
     BatchId = batchId;
     CellId  = cellId;
     Level   = level;
 }
 public BaseModuleRotationMetadata(NitroxInt3 cell, int direction) : base(typeof(BaseAddModuleGhost))
 {
     Cell      = cell;
     Direction = direction;
 }
Exemple #22
0
 public AnchoredFaceRotationMetadata(NitroxInt3 cell, int faceDirection, int faceType) : base(typeof(BaseAddFaceGhost))
 {
     Cell      = cell;
     Direction = faceDirection;
     FaceType  = faceType;
 }
 public DeterministicBatchGenerator(NitroxInt3 batchId)
 {
     random = new Random(batchId.GetHashCode());
 }
Exemple #24
0
 public static NitroxInt3 GetCellSize(int level, NitroxInt3 blocksPerBatch)
 {
     // Our own implementation for BatchCells.GetCellSize, that works on the server and client.
     return(blocksPerBatch / GetCellsPerBlock(level));
 }