예제 #1
0
        public static ConstructionCopy RemapAndBuild(ProceduralConstruction construction, RoomRemapper remapper = null)
        {
            ConstructionCopy grids = null;

            foreach (var room in construction.Rooms)
            {
                if (grids == null)
                {
                    grids = new ConstructionCopy(room, remapper);
                }
                else
                {
                    grids.AppendRoom(room);
                }
            }
            return(grids);
        }
예제 #2
0
        public void Remap(ProceduralRoom room, ConstructionCopy dest)
        {
            if (dest.PrimaryGrid.GridSizeEnum != room.Part.PrimaryCubeSize)
            {
                throw new ArgumentException("Primary grid cube size and room's primary cube size differ");
            }
            // Setup remap parameters
            {
                var localTransform = Remap <GridRemap_LocalTransform>();
                localTransform.LocalTransform = room.Transform;
            }

            {
                var naming = Remap <GridRemap_Names>();
                naming.PrefixFor(GridRemap_Names.RemapType.All, room.GetName() + " ");
            }

            {
                var coloring = Remap <Coloring>();
                coloring.OverrideColor      = DebugRoomColors ? (SerializableVector3?)Utilities.NextColor.ColorToHSV() : null;
                coloring.HueRotation        = room.Owner.Seed.Faction.HueRotation;
                coloring.SaturationModifier = room.Owner.Seed.Faction.SaturationModifier;
                coloring.ValueModifier      = room.Owner.Seed.Faction.ValueModifier;
            }

            {
                var ownership = Remap <GridRemap_Ownership>();
                var faction   = room.Owner.Seed.Faction.GetOrCreateFaction();
                ownership.OwnerID              = faction?.FounderId ?? 0;
                ownership.ShareMode            = MyOwnershipShareModeEnum.Faction;
                ownership.UpgradeShareModeOnly = true;
            }

            var worldTransform = Remap <GridRemap_WorldTransform>();
            {
                var roomTransformScaled = room.Transform.GetFloatMatrix();
                roomTransformScaled.Translation *= MyDefinitionManager.Static.GetCubeSize(dest.PrimaryGrid.GridSizeEnum);

                var prefabPrimaryGridNewWorldMatrix = Matrix.Multiply(roomTransformScaled,
                                                                      dest.PrimaryGrid.PositionAndOrientation?.GetMatrix() ?? MatrixD.Identity);
                var prefabPrimaryGridOldWorldMatrix = room.Part.PrimaryGrid.PositionAndOrientation?.GetMatrix() ??
                                                      MatrixD.Identity;


                var prefabOldToNew = Matrix.Multiply(Matrix.Invert(prefabPrimaryGridOldWorldMatrix),
                                                     prefabPrimaryGridNewWorldMatrix);

                worldTransform.WorldTransform      = prefabOldToNew;
                worldTransform.WorldLinearVelocity = dest.PrimaryGrid.LinearVelocity;
            }

            // Grab OB copies
            var timer = new Stopwatch();

            timer.Restart();
            var roomGrid   = CloneUtilities.CloneFast(room.Part.PrimaryGrid);
            var otherGrids = room.Part.Prefab.CubeGrids.Where(x => x != room.Part.PrimaryGrid).Select(CloneUtilities.CloneFast).ToList();
            var allGrids   = new List <MyObjectBuilder_CubeGrid>(otherGrids)
            {
                roomGrid
            };

            Logger.Debug("Cloned {0} grids in {1}", allGrids.Count, timer.Elapsed);


            // Remap entity IDs
            timer.Restart();
            MyAPIGateway.Entities.RemapObjectBuilderCollection(allGrids);
            // If we have a primary ID copy it now.
            if (dest.PrimaryGrid.EntityId != 0)
            {
                var constRemapID = new ConstantEntityRemap(new Dictionary <long, long> {
                    [roomGrid.EntityId] = dest.PrimaryGrid.EntityId
                });
                // Anything referring to the root grid's entity ID needs to be changed to the old grid.
                foreach (var c in allGrids)
                {
                    c.Remap(constRemapID);
                }
            }
            else // otherwise, skip
            {
                dest.PrimaryGrid.EntityId = roomGrid.EntityId;
            }
            Logger.Debug("Remapped {0} grid IDs in {1}", allGrids.Count, timer.Elapsed);

            // Apply remap operators
            m_allPre.RemapAndReset(allGrids);
            m_primary.RemapAndReset(new[] { roomGrid });
            m_auxiliary.RemapAndReset(otherGrids);
            m_allPost.RemapAndReset(allGrids);

            // Merge data into primary grid from room grid
            dest.PrimaryGrid.CubeBlocks.Capacity += roomGrid.CubeBlocks.Count;
            dest.PrimaryGrid.CubeBlocks.AddRange(roomGrid.CubeBlocks);

            dest.PrimaryGrid.BlockGroups.Capacity += roomGrid.BlockGroups.Count;
            dest.PrimaryGrid.BlockGroups.AddRange(roomGrid.BlockGroups);

            // Seems suboptimal?  Can we transform this and only invalidate ones on a room border?
            dest.PrimaryGrid.ConveyorLines.Clear();

            // Not even going to try.
            dest.PrimaryGrid.OxygenAmount = null;
            dest.PrimaryGrid.Skeleton     = null;

            // Add aux grids
            dest.AuxGrids.AddRange(otherGrids);

            dest.BoundingBox = BoundingBoxD.CreateMerged(dest.BoundingBox, Utilities.TransformBoundingBox((BoundingBoxD)room.BoundingBoxBoth, worldTransform.WorldTransform));
        }