예제 #1
0
        public static byte[] SerializeAndSign(IMyCubeGrid grid, IMyPlayer player, Vector3I block)
        {
            var          c     = grid.GetCubeBlock(block)?.FatBlock as IMyCockpit;
            IMyCharacter pilot = c?.Pilot;

            c?.RemovePilot();

            var ob = (MyObjectBuilder_CubeGrid)grid.GetObjectBuilder();

            if (pilot != null)
            {
                c.AttachPilot(pilot);
            }

            IMyFaction fac  = MyAPIGateway.Session.Factions.TryGetPlayerFaction(player.IdentityId);
            var        data = new ClientData(ob, fac, block, Settings.Instance.HubIP);

            string obStr    = MyAPIGateway.Utilities.SerializeToXML(data);
            string totalStr = DateTime.UtcNow.Ticks + obStr;
            string evalStr  = totalStr + Settings.Instance.Password;

            var m = new MD5();

            m.Value   = evalStr;
            totalStr += m.FingerPrint;

            return(Encoding.UTF8.GetBytes(totalStr));
        }
예제 #2
0
        public void ExportGrid(IMyCubeGrid grid, string path)
        {
            var ob = grid.GetObjectBuilder(true);

            using (var f = File.Open(path, FileMode.CreateNew))
                MyObjectBuilderSerializer.SerializeXML(f, ob);
        }
예제 #3
0
        public grid_logic(IMyCubeGrid new_grid)
        {
            _grid = new_grid;
            _grid.OnBlockAdded   += on_block_added;
            _grid.OnBlockRemoved += on_block_removed;
            sync_helper.register_logic_object(this, _grid.EntityId);
            _ID_on = ((MyObjectBuilder_CubeGrid)_grid.GetObjectBuilder()).DampenersEnabled;

            var block_list = new List <IMySlimBlock>();

            _grid.GetBlocks(block_list,
                            delegate(IMySlimBlock block)
            {
                return(block.FatBlock is IMyThrust || block.FatBlock is IMyGyro || block.FatBlock is IMyCockpit || block.FatBlock is IMyRemoteControl);
            }
                            );
            foreach (var cur_block in block_list)
            {
                on_block_added(cur_block);
            }

            /*
             * if (block_list.Count > 0)
             * {
             *  _ECU = new engine_control_unit(_grid);
             *  foreach (var cur_block in block_list)
             *  {
             *      var thruster = cur_block.FatBlock as IMyThrust;
             *      var gyro     = cur_block.FatBlock as IMyGyro;
             *      if (thruster != null)
             *      {
             *          _ECU.assign_thruster(thruster);
             ++_num_thrusters;
             *      }
             *      if (gyro != null)
             *          _ECU.assign_gyroscope(gyro);
             *  }
             * }
             *
             *
             * block_list.Clear();
             * _grid.GetBlocks(block_list,
             *  delegate (IMySlimBlock block)
             *  {
             *      return block.FatBlock is IMyCockpit || block.FatBlock is IMyRemoteControl;
             *  }
             * );
             * foreach (var cur_controller in block_list)
             * {
             *  _ship_controllers.Add((IMyControllableEntity) cur_controller.FatBlock);
             *  var RC_block = cur_controller.FatBlock as IMyRemoteControl;
             *  if (RC_block != null)
             *      _RC_blocks.Add(RC_block);
             * }
             */
        }
예제 #4
0
 private void GetOB(IMyCubeGrid grid)
 {
     builder = (MyObjectBuilder_CubeGrid)grid.GetObjectBuilder(true);
     foreach (var cube in ((MyCubeGrid)grid).GetFatBlocks())
     {
         if (cube is IMyAttachableTopBlock)
         {
             definition = cube.BlockDefinition;
             return;
         }
     }
 }
예제 #5
0
        public static MyObjectBuilder_CubeGrid CleanGrid(IMyCubeGrid ent)
        {
            MyObjectBuilder_CubeGrid grid = (MyObjectBuilder_CubeGrid)ent.GetObjectBuilder();

            grid.EntityId               = 0;
            grid.AngularVelocity        = new SerializableVector3();
            grid.LinearVelocity         = new SerializableVector3();
            grid.PositionAndOrientation = new MyPositionAndOrientation(new Vector3D(), new Vector3(0, 0, 1), new Vector3(0, 1, 0));
            grid.XMirroxPlane           = null;
            grid.YMirroxPlane           = null;
            grid.ZMirroxPlane           = null;
            grid.IsStatic               = false;
            grid.CreatePhysics          = true;
            grid.IsRespawnGrid          = false;

            foreach (var block in grid.CubeBlocks)
            {
                block.EntityId = 0;
            }

            return(grid);
        }
예제 #6
0
        static public float CalculateMass(IMyEntity entity)
        {
            if (!(entity is IMyCubeGrid))
            {
                return(0f);
            }

            float mass = 0f;

            IMyCubeGrid grid = (IMyCubeGrid)entity;
            MyObjectBuilder_CubeGrid gridObject = (MyObjectBuilder_CubeGrid)grid.GetObjectBuilder();
            List <IMySlimBlock>      blocks     = new List <IMySlimBlock>();

            grid.GetBlocks(blocks, null);
            foreach (IMySlimBlock block in blocks)
            {
                MyObjectBuilder_CubeBlock blockObject = block.GetCopyObjectBuilder();
                MyCubeBlockDefinition     cubeDef     = MyDefinitionManager.Static.GetCubeBlockDefinition(blockObject);
                mass += cubeDef.Mass;
            }

            return(mass);
        }
예제 #7
0
        static MyObjectBuilder_CubeGrid CreateNewGridOB(IMyCubeGrid grid, MyObjectBuilder_CubeBlock blockOb, string gridName)
        {
            MyCubeGrid internalGrid         = (MyCubeGrid)grid;
            MyObjectBuilder_CubeGrid gridOb = null;

            int blockCount = internalGrid.BlocksCount;

            if (blockCount > 1000)
            {
                gridOb = FastGridOBClone(internalGrid, blockOb, gridName);
            }
            else
            {
                gridOb               = (MyObjectBuilder_CubeGrid)grid.GetObjectBuilder();
                gridOb.DisplayName   = gridName;
                gridOb.IsStatic      = false;
                gridOb.ConveyorLines = null;

                if (gridOb.OxygenAmount != null && gridOb.OxygenAmount.Length > 0)
                {
                    gridOb.OxygenAmount = new float[0];
                }

                if (gridOb.BlockGroups != null)
                {
                    gridOb.BlockGroups.Clear();
                }

                gridOb.CubeBlocks.Clear();
                gridOb.CubeBlocks.Add(blockOb);
            }

            MyAPIGateway.Entities.RemapObjectBuilder(gridOb);

            return(gridOb);
        }
예제 #8
0
        public void LoadFromCubeGrid(IMyCubeGrid grid)
        {
            base.LoadFromEntity(grid as IMyEntity);

            IngameGrid = grid;

            //IngameGrid = grid;
            DisplayName = grid.DisplayName;
            // ToDo: get all owners instead of big (for targeting)
            BigOwners = grid.BigOwners;
            // ToDo: get real spawn owners (for spawning)
            SpawnOwners = grid.BigOwners;
            //IMyEntity entity = grid as IMyEntity;
            Builder = grid.GetObjectBuilder() as MyObjectBuilder_CubeGrid;

            if (Builder == null) {
                Log.Error("Got null builder for entity " + EntityId +
                    ". We will be unable to save it now.", "LoadFromCubeGrid");
            }
            else {
                //Log.Error("Filling builder nulls for " + EntityId, "LoadFromCubeGrid");
                //Builder.FillNullsWithDefaults();
            }
        }
예제 #9
0
        public static MyObjectBuilder_CubeGrid SafeGetObjectBuilder( IMyCubeGrid grid )
        {
            MyObjectBuilder_CubeGrid gridBuilder = null;
            try
            {
                gridBuilder = (MyObjectBuilder_CubeGrid)grid.GetObjectBuilder( );
            }
            catch
            {
            }

            return gridBuilder;
        }
예제 #10
0
        // /admin movefrom x y z x y z radius
        public override bool HandleCommand(ulong userId, string command)
        {
            string[]            words    = command.Split(' ');
            HashSet <IMyEntity> entities = new HashSet <IMyEntity>( );

            Wrapper.GameAction(() =>
            {
                MyAPIGateway.Entities.GetEntities(entities, x => x is IMyCubeGrid);
            });

            HashSet <long> playerOwners = new HashSet <long>();

            foreach (IMyEntity entity in entities)
            {
                IMyCubeGrid grid = (IMyCubeGrid)entity;
                MyObjectBuilder_CubeGrid gridBlock = (MyObjectBuilder_CubeGrid)grid.GetObjectBuilder();

                foreach (MyObjectBuilder_CubeBlock block in gridBlock.CubeBlocks)
                {
                    if (block.Owner == 0)
                    {
                        continue;
                    }

                    if (!playerOwners.Contains(block.Owner))
                    {
                        playerOwners.Add(block.Owner);
                    }
                }
            }

            Communication.SendPrivateInformation(userId, string.Format("Total block owners: {0}", playerOwners.Count));

            int count = 0;

            foreach (long owner in playerOwners)
            {
                ulong steamId = PlayerMap.Instance.GetPlayerItemFromPlayerId(owner).SteamId;
                if (steamId == 0)
                {
                    count++;
                }
            }

            Communication.SendPrivateInformation(userId, string.Format("Total owners without a steam Id: {0}", count));
            HashSet <long> badPlayers = new HashSet <long>();
            HashSet <long> noLogin    = new HashSet <long>();

            foreach (long owner in playerOwners)
            {
                MyObjectBuilder_Checkpoint.PlayerItem item = PlayerMap.Instance.GetPlayerItemFromPlayerId(owner);
                if (item.SteamId == 0)
                {
                    continue;
                }

                if (!Players.Instance.PlayerLogins.ContainsKey(item.SteamId))
                {
                    Communication.SendPrivateInformation(userId, string.Format("No login information: {0}", item.Name));
                    noLogin.Add(owner);
                    continue;
                }

                PlayerItem playerItem = Players.Instance.PlayerLogins[item.SteamId];
                if (DateTime.Now - playerItem.LastLogin > TimeSpan.FromDays(20))
                {
                    Communication.SendPrivateInformation(userId, string.Format("Player hasn't logged in 20 days: {0}", item.Name));
                    badPlayers.Add(owner);
                }
            }

            Communication.SendPrivateInformation(userId, string.Format("Users not logged in the last 20 days: {0}", badPlayers.Count));
            Communication.SendPrivateInformation(userId, string.Format("Users with no login information: {0}", noLogin.Count));

            /*
             * count = 0;
             * List<CubeGridEntity> grids = SectorObjectManager.Instance.GetTypedInternalData<CubeGridEntity>();
             * foreach(CubeGridEntity grid in grids)
             * {
             *      Thread.Sleep(100);
             *      foreach (CubeBlockEntity block in grid.CubeBlocks)
             *      {
             *              MyObjectBuilder_CubeBlock blockBuilder = (MyObjectBuilder_CubeBlock)block.Export();
             *              if (badPlayers.Contains(blockBuilder.Owner) || noLogin.Contains(blockBuilder.Owner))
             *              {
             *                      //grid.DeleteCubeBlock(block);
             *                      block.Dispose();
             *                      count++;
             *              }
             *      }
             * }
             */

            Wrapper.GameAction(() =>
            {
                MyAPIGateway.Entities.GetEntities(entities, x => x is IMyCubeGrid);

                foreach (IMyEntity entity in entities)
                {
                    IMyCubeGrid grid           = (IMyCubeGrid)entity;
                    List <IMySlimBlock> blocks = new List <IMySlimBlock>();
                    grid.GetBlocks(blocks, x => x.FatBlock != null && x.FatBlock.OwnerId != 0);
                    foreach (IMySlimBlock block in blocks)
                    {
                        IMyCubeBlock cubeBlock = (IMyCubeBlock)block.FatBlock;
                        if (badPlayers.Contains(cubeBlock.OwnerId) || noLogin.Contains(cubeBlock.OwnerId))
                        {
                            grid.RazeBlock(cubeBlock.Min);
                            count++;
                        }
                    }
                }
            });

            Communication.SendPrivateInformation(userId, string.Format("Blocks disposed: {0}", count));

            return(true);
        }
예제 #11
0
        private void Process(CommandFeedback feedback, IMyCubeGrid grid)
        {
            if (grid.CustomName == null || !grid.CustomName.StartsWithICase("EqProcBuild"))
            {
                return;
            }
            var ob = grid.GetObjectBuilder(true) as MyObjectBuilder_CubeGrid;

            if (ob == null)
            {
                return;
            }
            this.Info("Begin processing {0}", grid.CustomName);
            feedback?.Invoke("Processing {0}", grid.CustomName);
            try
            {
                var dummyDel  = new List <MyTuple <MyObjectBuilder_CubeBlock, string> >();
                var blockKeep = new List <MyObjectBuilder_CubeBlock>();
                var blockMap  = new Dictionary <Vector3I, MyObjectBuilder_CubeBlock>(Vector3I.Comparer);
                foreach (var block in ob.CubeBlocks)
                {
                    var mount = false;
                    foreach (var name in block.ConfigNames())
                    {
                        if (!name.StartsWithICase(MountDelegated) && !name.StartsWithICase(ReservedSpaceDelegated))
                        {
                            continue;
                        }
                        dummyDel.Add(MyTuple.Create(block, name));
                        mount = true;
                        break;
                    }
                    if (mount)
                    {
                        continue;
                    }

                    var      blockMin = (Vector3I)block.Min;
                    Vector3I blockMax;
                    BlockTransformations.ComputeBlockMax(block, out blockMax);
                    for (var rangeItr = new Vector3I_RangeIterator(ref blockMin, ref blockMax); rangeItr.IsValid(); rangeItr.MoveNext())
                    {
                        blockMap[rangeItr.Current] = block;
                    }
                    blockKeep.Add(block);
                }
                this.Info("Found {0} blocks to keep, {1} block mounts to remap", blockKeep.Count, dummyDel.Count);
                foreach (var pair in dummyDel)
                {
                    var block   = pair.Item1;
                    var useName = pair.Item2;

                    IEnumerable <Base6Directions.Direction> dirs = Base6Directions.EnumDirections;
                    var def       = MyDefinitionManager.Static.GetCubeBlockDefinition(pair.Item1);
                    var transform = new MatrixI(block.BlockOrientation);
                    if (def?.MountPoints != null)
                    {
                        var mountDirs = new HashSet <Base6Directions.Direction>();
                        foreach (var mount in def.MountPoints)
                        {
                            mountDirs.Add(Base6Directions.GetDirection(Vector3I.TransformNormal(mount.Normal, ref transform)));
                        }
                    }

                    var args     = useName.Split(' ');
                    var keepArgs = new List <string>(args.Length);
                    foreach (var arg in args)
                    {
                        if (arg.StartsWithICase(PartDummyUtils.ArgumentMountDirection))
                        {
                            Base6Directions.Direction dir;
                            if (Enum.TryParse(arg.Substring(2), out dir))
                            {
                                dirs = new[] { transform.GetDirection(Base6Directions.GetOppositeDirection(dir)) }
                            }
                            ;
                            else
                            {
                                this.Error("Failed to parse direction argument \"{0}\"", arg);
                                feedback?.Invoke("Error: Failed to parse direction argument \"{0}\"", arg);
                            }
                        }
                        else
                        {
                            keepArgs.Add(arg);
                        }
                    }
                    useName = string.Join(" ", keepArgs);

                    MyObjectBuilder_CubeBlock outputBlock = null;
                    var outputDir = Base6Directions.Direction.Forward;
                    foreach (var dir in dirs)
                    {
                        MyObjectBuilder_CubeBlock tmp;
                        if (!blockMap.TryGetValue(block.Min + Base6Directions.GetIntVector(dir), out tmp))
                        {
                            continue;
                        }
                        if (tmp.ConfigNames().Any(x => x.StartsWithICase(MountDelegated)))
                        {
                            continue;
                        }
                        if (outputBlock != null)
                        {
                            this.Error("Multiple directions found for {0}", pair.Item2);
                            feedback?.Invoke("Error: Multiple directions found for {0}", pair.Item2);
                        }
                        outputBlock = tmp;
                        outputDir   = dir;
                    }
                    if (outputBlock == null || !ApplyDelegate(ob, block, useName, outputBlock, outputDir))
                    {
                        this.Error("Failed to find delegated mount point for {0}", pair.Item2);
                        feedback?.Invoke("Error: Failed to find delegated mount point for {0}", pair.Item2);
                    }
                }
                ob.CubeBlocks = blockKeep;

                // Grab related grids!
                var relatedGrids = new HashSet <IMyCubeGrid> {
                    grid
                };
                var scanRelated           = new Queue <IMyCubeGrid>();
                var relatedGridController = new Dictionary <IMyCubeGrid, IMyCubeBlock>();
                scanRelated.Enqueue(grid);
                while (scanRelated.Count > 0)
                {
                    var          subGrid = scanRelated.Dequeue();
                    IMyCubeBlock controllerForThisGrid = null;
                    relatedGridController.TryGetValue(subGrid, out controllerForThisGrid);

                    subGrid.GetBlocks(null, (y) =>
                    {
                        var x = y?.FatBlock;
                        if (x == null)
                        {
                            return(false);
                        }
                        var childGrid = (x as IMyMechanicalConnectionBlock)?.TopGrid;
                        if (childGrid != null && relatedGrids.Add(childGrid))
                        {
                            scanRelated.Enqueue(childGrid);
                            relatedGridController[childGrid] = x.CubeGrid == grid ? x : controllerForThisGrid;
                        }
                        var parentGrid = (x as IMyAttachableTopBlock)?.Base?.CubeGrid;
                        // ReSharper disable once InvertIf
                        if (parentGrid != null && relatedGrids.Add(parentGrid))
                        {
                            scanRelated.Enqueue(parentGrid);
                            relatedGridController[parentGrid] = x.CubeGrid == grid ? x : controllerForThisGrid;
                        }
                        return(false);
                    });
                }
                relatedGrids.Remove(grid);
                var removedNoController = relatedGrids.RemoveWhere(x => !relatedGridController.ContainsKey(x));
                if (removedNoController > 0)
                {
                    this.Error("Failed to find the mechanical connection block for all subgrids.  {0} will be excluded",
                               removedNoController);
                    feedback?.Invoke("Error: Failed to find the mechanical connection block for all subgrids.  {0} will be excluded",
                                     removedNoController);
                }
                // Need to add reserved space for subgrids so they don't overlap.  So compute that.  Yay!
                foreach (var rel in relatedGrids)
                {
                    IMyCubeBlock root;
                    if (!relatedGridController.TryGetValue(rel, out root))
                    {
                        this.Error("Unable to find the mechanical connection for grid {0}", rel.CustomName);
                        feedback?.Invoke("Error: Unable to find the mechanical connection for grid {0}",
                                         rel.CustomName);
                        continue;
                    }
                    MyObjectBuilder_CubeBlock blockDest;
                    if (blockMap.TryGetValue(root.Min, out blockDest))
                    {
                        var blockLocal = (MatrixD) new MatrixI(blockDest.BlockOrientation).GetFloatMatrix();
                        blockLocal.Translation = (Vector3I)blockDest.Min * grid.GridSize;
                        var blockWorld = MatrixD.Multiply(blockLocal, grid.WorldMatrix);

                        var worldAABB = rel.WorldAABB;
                        worldAABB = Utilities.TransformBoundingBox(worldAABB, MatrixD.Invert(blockWorld));
                        var gridAABB = new BoundingBoxI(Vector3I.Floor(worldAABB.Min / grid.GridSize), Vector3I.Ceiling(worldAABB.Max / grid.GridSize));
                        var code     = $"{PartMetadata.ReservedSpacePrefix} NE:{gridAABB.Min.X}:{gridAABB.Min.Y}:{gridAABB.Min.Z} PE:{gridAABB.Max.X}:{gridAABB.Max.Y}:{gridAABB.Max.Z}";
                        this.Info("Added reserved space for subgrid {0}: Spec is \"{1}\"", rel.CustomName, code);
                        if (blockDest.Name == null || blockDest.Name.Trim().Length == 0)
                        {
                            blockDest.Name = code;
                        }
                        else
                        {
                            blockDest.Name += PartMetadata.MultiUseSentinel + code;
                        }
                    }
                    else
                    {
                        this.Error("Unable to find the OB for grid block {0} ({1}, {2}, {3}).  Is it a delegate?", (root as IMyTerminalBlock)?.CustomName ?? root.Name, root.Min.X, root.Min.Y, root.Min.Z);
                        feedback?.Invoke("Unable to the find OB for grid block {0} ({1}, {2}, {3}).  Was it a delegate?", (root as IMyTerminalBlock)?.CustomName ?? root.Name, root.Min.X, root.Min.Y, root.Min.Z);
                    }
                }

                var allGrids = new List <MyObjectBuilder_CubeGrid>(relatedGrids.Count + 1)
                {
                    ob
                };
                allGrids.AddRange(relatedGrids.Select(relGrid => relGrid.GetObjectBuilder(false)).OfType <MyObjectBuilder_CubeGrid>());

                // Compose description: TODO I'd love if this actually worked :/
                // var storage = new MyPartMetadata();
                // storage.InitFromGrids(ob, allGrids);
                // var data = Convert.ToBase64String(MyAPIGateway.Utilities.SerializeToBinary(storage.GetObjectBuilder()));

                var defOut = new MyObjectBuilder_PrefabDefinition()
                {
                    Id        = new SerializableDefinitionId(typeof(MyObjectBuilder_PrefabDefinition), grid.CustomName),
                    CubeGrids = allGrids.ToArray()
                };

                var fileName = grid.CustomName + ".sbc";
                this.Info("Saving {1} grids as {0}", fileName, defOut.CubeGrids.Length);
                feedback?.Invoke("Saving {1} grids as {0}", fileName, defOut.CubeGrids.Length);

                var mishMash = new MyObjectBuilder_Definitions()
                {
                    Prefabs = new MyObjectBuilder_PrefabDefinition[] { defOut }
                };
                var writer = MyAPIGateway.Utilities.WriteBinaryFileInLocalStorage(fileName, typeof(DesignTools));
                var obCode = MyAPIGateway.Utilities.SerializeToXML(mishMash);
                obCode = obCode.Replace("encoding=\"utf-16\"", "encoding=\"utf-8\"");
                writer.Write(Encoding.UTF8.GetBytes(obCode));
                writer.Close();
            }
            catch (Exception e)
            {
                this.Error("Failed to parse.  Error:\n{0}", e.ToString());
            }
        }
예제 #12
0
        /// <summary>
        /// Rebuilds our conveyor dictionary.  This lets us check if two entities are connected by conveyors quickly.
        /// </summary>
        /// <param name="entities"></param>
        public static void RebuildConveyorList(HashSet <IMyEntity> entities)
        {
            m_rebuild     = false;
            m_lastRebuild = DateTime.Now;
            DateTime start = DateTime.Now;

            try
            {
                //Logging.Instance.WriteLine(String.Format("Count: {0}", entities.Count));

                m_conveyorCache.Clear();
                m_conveyorConnected.Clear();
                foreach (IMyEntity entity in entities)
                {
                    if (!(entity is IMyCubeGrid))
                    {
                        continue;
                    }

                    IMyCubeGrid grid = (IMyCubeGrid)entity;

                    MyObjectBuilder_CubeGrid gridObject = (MyObjectBuilder_CubeGrid)grid.GetObjectBuilder();

                    if (gridObject == null || gridObject.ConveyorLines == null)
                    {
                        continue;
                    }

                    foreach (MyObjectBuilder_ConveyorLine line in gridObject.ConveyorLines)
                    {
/*
 *                                              if (slimBlockStart != null && slimBlockStart.FatBlock != null && slimBlockStart.FatBlock.BlockDefinition.TypeId == typeof(MyObjectBuilder_ConveyorConnector))
 *                                              {
 * //							Logging.Instance.WriteLine(string.Format("Conveyor Functional: {0} - {1} - {2} - {3} - {4} - {5}", slimBlockStart.FatBlock.IsFunctional, slimBlockStart.FatBlock.IsWorking, IsFunctional(slimBlockStart.FatBlock), slimBlockStart.BuildIntegrity, slimBlockStart.BuildLevelRatio, slimBlockStart.MaxIntegrity));
 *                                              }
 *
 *                                              if (slimBlockEnd != null && slimBlockEnd.FatBlock != null && slimBlockEnd.FatBlock.BlockDefinition.TypeId == typeof(MyObjectBuilder_ConveyorConnector))
 *                                              {
 * //							Logging.Instance.WriteLine(string.Format("Conveyor Functional: {0} - {1} - {2} - {3} - {4} - {5}", slimBlockEnd.FatBlock.IsFunctional, slimBlockEnd.FatBlock.IsWorking, IsFunctional(slimBlockEnd.FatBlock), slimBlockEnd.BuildIntegrity, slimBlockEnd.BuildLevelRatio, slimBlockEnd.MaxIntegrity));
 *                                              }
 *
 *                                              Logging.Instance.WriteLine(string.Format("Start: {0}", slimBlockStart.FatBlock.BlockDefinition.SubtypeName));
 *                                              Logging.Instance.WriteLine(string.Format("End: {0}", slimBlockEnd.FatBlock.BlockDefinition.SubtypeName));
 */
                        IMySlimBlock slimBlockStart = grid.GetCubeBlock((Vector3I)line.StartPosition);
                        if (slimBlockStart == null || slimBlockStart.FatBlock == null || !slimBlockStart.FatBlock.IsFunctional)
                        {
                            continue;
                        }

                        IMySlimBlock slimBlockEnd = grid.GetCubeBlock((Vector3I)line.EndPosition);
                        if (slimBlockEnd == null || slimBlockEnd.FatBlock == null || !slimBlockEnd.FatBlock.IsFunctional)
                        {
                            continue;
                        }

                        ConnectConveyorBlocks(slimBlockStart, slimBlockEnd);
                    }

                    if (m_conveyorConnected.ContainsKey(grid.EntityId))
                    {
                        long[] connectedBlockId = m_conveyorConnected[grid.EntityId];
                        m_conveyorConnected.Remove(grid.EntityId);
                        ConnectConveyorBlocks(connectedBlockId);
                    }
                }

                foreach (KeyValuePair <long, long[]> p in m_conveyorConnected)
                {
                    ConnectConveyorBlocks(p.Value);
                }

                //Logging.Instance.WriteLine(String.Format("Size: {0}", m_conveyorCache.Count));
            }
            catch (Exception ex)
            {
                Logging.Instance.WriteLine(String.Format("RebuildConveyorList: {0}", ex.ToString()));
            }

            if (Core.Debug)
            {
                Logging.Instance.WriteLine(String.Format("RebuildConveyorList {0}ms", (DateTime.Now - start).Milliseconds));
            }
        }
예제 #13
0
        public override bool HandleCommand(ulong userId, string[] words)
        {
            if (!PluginSettings.Instance.DockingEnabled)
            {
                return(false);
            }

            if (words.Length < 1)
            {
                Communication.SendPrivateInformation(userId, GetHelp());
                return(true);
            }

            String pylonName = String.Join(" ", words);

            /*
             * int timeLeft;
             * if (Entity.CheckCoolDown(pylonName, out timeLeft))
             * {
             * Communication.Message(String.Format("The docking zone '{0}' is on cooldown.  Please wait a {1} seconds before trying to dock/undock again.", pylonName, Math.Max(0, timeLeft)));
             * return;
             * }
             */

            if (PlayerMap.Instance.GetPlayerIdsFromSteamId(userId).Count < 1)
            {
                Communication.SendPrivateInformation(userId, string.Format("Unable to find player Id: {0}", userId));
                return(true);
            }

            long playerId = PlayerMap.Instance.GetPlayerIdsFromSteamId(userId).First();

            Dictionary <String, List <IMyCubeBlock> > testList;
            List <IMyCubeBlock> beaconList;

            DockingZone.FindByName(pylonName, out testList, out beaconList, playerId);
            if (beaconList.Count == 4)
            {
                // Check ownership
                foreach (IMyCubeBlock entityBlock in beaconList)
                {
                    IMyTerminalBlock terminal = (IMyTerminalBlock)entityBlock;
                    if (!terminal.HasPlayerAccess(playerId))
                    {
                        Communication.SendPrivateInformation(userId, string.Format("You do not have permission to use '{0}'.  You must either own all the beacons or they must be shared with faction.", pylonName));
                        return(true);
                    }
                }

                // Check for bounding box intsection of other docking zones
                int intersectElement = 0;
                if (Entity.CheckForIntersection(testList, beaconList, out intersectElement))
                {
                    Communication.SendPrivateInformation(userId, string.Format("The docking zone '{0}' intersects with docking zone '{1}'.  Make sure you place your docking zones so they don't overlap.", pylonName, testList.ElementAt(intersectElement).Key));
                    return(true);
                }

                // Check if ship already docked in this zone
                IMyCubeBlock       e             = beaconList[0];
                IMyCubeGrid        parent        = (IMyCubeGrid)e.Parent;
                long[]             beaconListIds = beaconList.Select(b => b.EntityId).ToArray();
                long               ownerId       = beaconList.First().OwnerId;
                List <DockingItem> checkItems    = Docking.Instance.Find(d => d.PlayerId == ownerId && d.TargetEntityId == parent.EntityId && d.DockingBeaconIds.Intersect(beaconListIds).Count() == 4);
                if (checkItems.Count >= PluginSettings.Instance.DockingShipsPerZone)
                {
                    Communication.SendPrivateInformation(userId, string.Format("Docking zone already '{0}' already contains the maximum capacity of ships.", pylonName));
                    return(true);
                }

                // Figure out center of docking area, and other distance information
                double   maxDistance = 99;
                Vector3D vPos        = new Vector3D(0, 0, 0);

                foreach (IMyCubeBlock b in beaconList)
                {
                    Vector3D beaconPos = Entity.GetBlockEntityPosition(b);
                    vPos += beaconPos;
                }

                vPos = vPos / 4;
                foreach (IMyCubeBlock b in beaconList)
                {
                    Vector3D beaconPos = Entity.GetBlockEntityPosition(b);
                    maxDistance = Math.Min(maxDistance, Vector3D.Distance(vPos, beaconPos));
                }

                // Find ship in docking area
                IMyCubeGrid         dockingEntity = null;
                HashSet <IMyEntity> cubeGrids     = new HashSet <IMyEntity>();
                MyAPIGateway.Entities.GetEntities(cubeGrids, f => f is IMyCubeGrid);
                foreach (IMyCubeGrid gridCheck in cubeGrids)
                {
                    if (gridCheck.IsStatic || gridCheck == parent)
                    {
                        continue;
                    }

                    double distance = Vector3D.Distance(gridCheck.GetPosition(), vPos);
                    if (distance < maxDistance)
                    {
                        dockingEntity = gridCheck;
                        break;
                    }
                }

                // Figure out if the ship fits in docking area, and then save ship
                if (dockingEntity != null)
                {
                    // Get bounding box of both the docking zone and docking ship
                    OrientedBoundingBoxD targetBounding  = Entity.GetBoundingBox(beaconList);
                    OrientedBoundingBoxD dockingBounding = Entity.GetBoundingBox(dockingEntity);

                    // Make sure the docking zone contains the docking ship.  If they intersect or are disjointed, then fail
                    if (!Entity.GreaterThan(dockingBounding.HalfExtent * 2, targetBounding.HalfExtent * 2))
                    {
                        Communication.SendPrivateInformation(userId, string.Format("The ship '{0}' is too large for it's carrier.  The ship's bounding box must fit inside the docking zone bounding box!", dockingEntity.Name));
                        return(true);
                    }

                    if (targetBounding.Contains(ref dockingBounding) != ContainmentType.Contains)
                    {
                        Communication.SendPrivateInformation(userId, string.Format("The ship '{0}' is not fully inside the docking zone '{1}'.  Make sure the ship is fully contained inside the docking zone", dockingEntity.Name, pylonName));
                        return(true);
                    }

                    // Calculate the mass and ensure the docking ship is less than half the mass of the dock
                    float parentMass  = Entity.CalculateMass(parent);
                    float dockingMass = Entity.CalculateMass(dockingEntity);
                    if (dockingMass > parentMass)
                    {
                        Communication.SendPrivateInformation(userId, string.Format("The ship you're trying to dock is too heavy for it's carrier.  The ship mass must be less than half the large ship / stations mass! (DM={0}kg CM={1}kg)", dockingMass, parentMass));
                        return(true);
                    }

                    // Check to see if the ship is piloted, if it is, error out.
                    // TODO: Check to see if we can get a real time copy of this entity?
                    List <IMySlimBlock> blocks = new List <IMySlimBlock>();
                    dockingEntity.GetBlocks(blocks, x => x.FatBlock != null && x.FatBlock.BlockDefinition.TypeId == typeof(MyObjectBuilder_Cockpit));
                    foreach (IMySlimBlock slim_cbe in blocks)
                    {
                        MyObjectBuilder_Cockpit c = (MyObjectBuilder_Cockpit)slim_cbe.FatBlock.GetObjectBuilderCubeBlock();
                        if (c.Pilot != null)
                        {
                            Communication.SendPrivateInformation(userId, string.Format("Ship in docking zone '{0}' has a pilot!  Please exit the ship before trying to dock.  (Sometimes this can lag a bit.  Wait 10 seconds and try again)", pylonName));
                            return(true);
                        }
                    }

                    // Save position and rotation information.  Some fun stuff here.
                    // Get our dock rotation as a quaternion
                    Quaternion saveQuat = Quaternion.CreateFromRotationMatrix(parent.WorldMatrix.GetOrientation());
                    // Transform docked ship's local position by inverse of the the parent (unwinds parent) and save it for when we undock
                    Vector3D savePos = Vector3D.Transform(dockingEntity.GetPosition() - parent.GetPosition(), Quaternion.Inverse(saveQuat));
                    // Get local rotation of dock ship, and save it for when we undock
                    saveQuat = Quaternion.Inverse(saveQuat) * Quaternion.CreateFromRotationMatrix(dockingEntity.WorldMatrix.GetOrientation());

                    // Serialize and save ship to file, then remove it
                    // Save item
                    DockingItem dockItem = new DockingItem();
                    dockItem.DockedEntityId   = dockingEntity.EntityId;
                    dockItem.TargetEntityId   = parent.EntityId;
                    dockItem.PlayerId         = ownerId;
                    dockItem.DockingBeaconIds = beaconList.Select(s => s.EntityId).ToArray();
                    dockItem.DockedName       = dockingEntity.DisplayName;
                    dockItem.SavePos          = savePos;
                    dockItem.SaveQuat         = saveQuat;
                    Docking.Instance.Add(dockItem);

                    // Save ship to file and remove
                    FileInfo       info        = new FileInfo(Essentials.PluginPath + String.Format("\\Docking\\docked_{0}_{1}_{2}.sbc", ownerId, parent.EntityId, dockingEntity.EntityId));
                    CubeGridEntity dockingGrid = new CubeGridEntity((MyObjectBuilder_CubeGrid)dockingEntity.GetObjectBuilder(), dockingEntity);
                    if (!CubeGrids.WaitForLoadingEntity(dockingGrid))
                    {
                        Communication.SendPrivateInformation(userId, string.Format("Failed to load entity for export: {0}", dockingGrid.EntityId));
                        return(true);
                    }

                    dockingGrid.Export(info);
                    dockingGrid.Dispose();

                    Communication.SendPrivateInformation(userId, string.Format("Docked ship '{0}' in docking zone '{1}'.", dockItem.DockedName, pylonName));

                    /*
                     * // Add a cool down
                     * DockingCooldownItem cItem = new DockingCooldownItem();
                     * cItem.name = pylonName;
                     * cItem.startTime = DateTime.Now;
                     * PluginDocking.CooldownList.Add(cItem);
                     */
                }
                else
                {
                    Communication.SendPrivateInformation(userId, string.Format("No ships in docking zone '{0}'.", pylonName));
                }
            }
            else if (beaconList.Count > 4)
            {
                Communication.SendPrivateInformation(userId, string.Format("Too many beacons with the name or another zone with the name '{0}'.  Place only 4 beacons to create a zone or try a different zone name.", pylonName));
            }
            else
            {
                Communication.SendPrivateInformation(userId, string.Format("Can not locate docking zone '{0}'.  There must be 4 beacons with the name '{0}' to create a docking zone.  Beacons must be fully built!", pylonName));
            }

            return(true);
        }