private ProjectedGrid(ulong activator, IMyProjector p, List <MyObjectBuilder_CubeGrid> grids, GridBounds bounds, GridComponents comps, GridOrientation orientation, bool shiftBuildArea, int blockCount)
 {
     Activator           = activator;
     BlockCount          = blockCount;
     this.p              = p;
     this.grids          = grids;
     this.bounds         = bounds;
     this.comps          = comps;
     finalOrientation    = orientation;
     this.shiftBuildArea = shiftBuildArea;
 }
        public static bool TryCreate(ulong activator, IMyProjector p, bool shiftBuildArea, out ProjectedGrid projectedGrid)
        {
            projectedGrid = null;

            // Ensure the projector is valid and has a projection
            if (p.CubeGrid?.Physics == null)
            {
                Utilities.Notify(Constants.msgError + "bad_physics", activator);
                return(false);
            }

            if (p.ProjectedGrid == null)
            {
                Utilities.Notify(Constants.msgNoGrid, activator);
                return(false);
            }

            MyObjectBuilder_Projector pBuilder = (MyObjectBuilder_Projector)p.GetObjectBuilderCubeBlock(true);

            if (pBuilder.ProjectedGrids == null || pBuilder.ProjectedGrids.Count == 0)
            {
                Utilities.Notify(Constants.msgNoGrid, activator);
                return(false);
            }

            // Prepare list of grids
            List <MyObjectBuilder_CubeGrid> grids = pBuilder.ProjectedGrids;
            int largestIndex = FindLargest(grids);

            MyObjectBuilder_CubeGrid largestGrid = grids[largestIndex];

            if (Utilities.SupportsSubgrids(p))
            {
                if (largestIndex != 0)
                {
                    MyObjectBuilder_CubeGrid temp = grids[0];
                    grids[0]            = largestGrid;
                    grids[largestIndex] = temp;
                }
            }
            else
            {
                grids.Clear();
                grids.Add(largestGrid);
            }

            MatrixD largestMatrixInvert = MatrixD.Invert(largestGrid.PositionAndOrientation.Value.GetMatrix());
            MatrixD targetMatrix        = p.ProjectedGrid.WorldMatrix;

            float scale = GetScale(p);

            GridOrientation orientation = new GridOrientation(p);

            GridComponents comps = null;

            if (!MyAPIGateway.Session.CreativeMode)
            {
                comps = new GridComponents();
            }

            int totalBlocks = 0;

            MyIDModule owner = ((MyCubeBlock)p).IDModule;

            if (activator != 0)
            {
                long temp = MyAPIGateway.Players.TryGetIdentityId(activator);
                if (temp != 0)
                {
                    if (owner.ShareMode == MyOwnershipShareModeEnum.All)
                    {
                        owner = new MyIDModule(temp, MyOwnershipShareModeEnum.Faction);
                    }
                    else
                    {
                        owner = new MyIDModule(temp, owner.ShareMode);
                    }
                }
            }

            Random rand = new Random();

            foreach (MyObjectBuilder_CubeGrid grid in grids)
            {
                totalBlocks += grid.CubeBlocks.Count;
                if (totalBlocks > IPSession.Instance.MapSettings.MaxBlocks)
                {
                    Utilities.Notify(Constants.msgGridLarge, activator);
                    return(false);
                }

                PrepBlocks(rand, owner, grid, comps);
                if (grid.CubeBlocks.Count == 0)
                {
                    Utilities.Notify(Constants.msgGridSmall, activator);
                    return(false);
                }

                grid.IsStatic           = false;
                grid.CreatePhysics      = true;
                grid.Immune             = false;
                grid.DestructibleBlocks = true;

                MatrixD current = grid.PositionAndOrientation.Value.GetMatrix();
                if (scale != 1)
                {
                    current.Translation /= scale;
                }

                MatrixD newWorldMatrix = (current * largestMatrixInvert) * targetMatrix;
                grid.PositionAndOrientation = new MyPositionAndOrientation(ref newWorldMatrix);
                orientation.Include(newWorldMatrix);
            }

            if (totalBlocks < IPSession.Instance.MapSettings.MinBlocks)
            {
                Utilities.Notify(Constants.msgGridSmall, activator);
                return(false);
            }


            if (comps == null)
            {
                comps = new GridComponents();
            }
            else
            {
                comps.ApplySettings(IPSession.Instance.MapSettings);
                int            needed;
                MyDefinitionId neededId;
                if (!comps.HasComponents(Utilities.GetInventories(p), out needed, out neededId))
                {
                    Utilities.Notify(Utilities.GetCompsString(needed, neededId), activator);
                    return(false);
                }
            }


            GridBounds bounds = new GridBounds(p, grids);
            IMyEntity  e      = bounds.GetOverlappingEntity();

            if (e != null && (!shiftBuildArea || !bounds.HasClearArea()))
            {
                Utilities.Notify(Utilities.GetOverlapString(true, e), activator);
                return(false);
            }

            projectedGrid = new ProjectedGrid(activator, p, grids, bounds, comps, orientation, shiftBuildArea, totalBlocks);
            return(true);
        }
        private static void PrepBlocks(Random rand, MyIDModule owner, MyObjectBuilder_CubeGrid grid, GridComponents comps)
        {
            for (int i = grid.CubeBlocks.Count - 1; i >= 0; i--)
            {
                MyObjectBuilder_CubeBlock cubeBuilder = grid.CubeBlocks[i];
                if (cubeBuilder.EntityId == 0)
                {
                    if (!Utilities.RandomEntityId(rand, out cubeBuilder.EntityId))
                    {
                        grid.CubeBlocks.RemoveAtFast(i);
                        continue;
                    }
                }

                cubeBuilder.SetupForProjector();
                MyCubeBlockDefinition def = MyDefinitionManager.Static.GetCubeBlockDefinition(cubeBuilder);
                if (def == null)
                {
                    grid.CubeBlocks.RemoveAtFast(i);
                    continue;
                }

                if (comps != null)
                {
                    comps.Include(def);
                }

                cubeBuilder.Owner     = owner.Owner;
                cubeBuilder.BuiltBy   = owner.Owner;
                cubeBuilder.ShareMode = owner.ShareMode;

                // Since the cross grid entity ids are invalid, remove references to them.
                if (cubeBuilder is MyObjectBuilder_AttachableTopBlockBase)
                {
                    ((MyObjectBuilder_AttachableTopBlockBase)cubeBuilder).ParentEntityId = 0;
                }
                if (cubeBuilder is MyObjectBuilder_MechanicalConnectionBlock)
                {
                    ((MyObjectBuilder_MechanicalConnectionBlock)cubeBuilder).TopBlockId = null;
                }
                if (cubeBuilder is MyObjectBuilder_MotorBase)
                {
                    ((MyObjectBuilder_MotorBase)cubeBuilder).RotorEntityId = null;
                }


                if (cubeBuilder is MyObjectBuilder_FunctionalBlock)
                {
                    ((MyObjectBuilder_FunctionalBlock)cubeBuilder).Enabled = true;
                }
                if (cubeBuilder is MyObjectBuilder_BatteryBlock)
                {
                    MyBatteryBlockDefinition batDef = (MyBatteryBlockDefinition)def;
                    ((MyObjectBuilder_BatteryBlock)cubeBuilder).CurrentStoredPower = batDef.InitialStoredPowerRatio * batDef.MaxStoredPower;
                }
            }
        }
Пример #4
0
        private static bool PrepBlocks(ulong activator, MyIDModule owner, MyObjectBuilder_CubeGrid grid, GridComponents comps)
        {
            foreach (MyObjectBuilder_CubeBlock cubeBuilder in grid.CubeBlocks)
            {
                if (cubeBuilder.EntityId == 0)
                {
                    if (!Constants.RandomEntityId(out cubeBuilder.EntityId))
                    {
                        return(false);
                    }
                }

                cubeBuilder.SetupForProjector();
                MyCubeBlockDefinition def = MyDefinitionManager.Static.GetCubeBlockDefinition(cubeBuilder);
                if (def == null)
                {
                    Constants.Notify(Constants.msgUnknownBlock, activator);
                    return(false);
                }

                if (comps != null)
                {
                    comps.Include(def);
                }

                cubeBuilder.Owner     = owner.Owner;
                cubeBuilder.BuiltBy   = owner.Owner;
                cubeBuilder.ShareMode = owner.ShareMode;

                // Since the cross grid entity ids are invalid, remove references to them.
                if (cubeBuilder is MyObjectBuilder_AttachableTopBlockBase)
                {
                    ((MyObjectBuilder_AttachableTopBlockBase)cubeBuilder).ParentEntityId = 0;
                }
                if (cubeBuilder is MyObjectBuilder_MechanicalConnectionBlock)
                {
                    ((MyObjectBuilder_MechanicalConnectionBlock)cubeBuilder).TopBlockId = null;
                }

                if (cubeBuilder is MyObjectBuilder_FunctionalBlock)
                {
                    ((MyObjectBuilder_FunctionalBlock)cubeBuilder).Enabled = true;
                }
                if (cubeBuilder is MyObjectBuilder_BatteryBlock)
                {
                    MyBatteryBlockDefinition batDef = (MyBatteryBlockDefinition)def;
                    ((MyObjectBuilder_BatteryBlock)cubeBuilder).CurrentStoredPower = batDef.InitialStoredPowerRatio * batDef.MaxStoredPower;
                }
            }

            return(true);
        }