private bool ValidateBlock(IMyTerminalBlock block, bool callbackRequired = true)
        {
            //check for block deletion?

            //check that we have required permissions to control the block
            if (!Me.HasPlayerAccess(block.OwnerId))
            {
                Echo("ERROR: no permissions for \"" + block.CustomName + "\"");
                return(false);
            }

            //check that the block has required permissions to make callbacks
            if (callbackRequired && !block.HasPlayerAccess(Me.OwnerId))
            {
                Echo("ERROR: no permissions on \"" + block.CustomName + "\"");
                return(false);
            }

            //check that block is functional
            if (!block.IsFunctional)
            {
                Echo("ERROR: non-functional block \"" + block.CustomName + "\"");
                return(false);
            }

            return(true);
        }
Beispiel #2
0
        private void RunContinuousLogic()
        {
            if (_CheckBlock.IsFunctional && _CheckBlock.HasPlayerAccess(Me.OwnerId))
            {
                Echo($"Master: {_CheckBlock.CustomName}\nWorking\n");
            }
            else
            {
                GridTerminalSystem.GetBlocksOfType(_Warheads);
                Echo($"Master: {_CheckBlock.CustomName}\nBroken\nWarheads: {_Warheads.Count}\n");

                if (!countdown)
                {
                    countdown = true;
                    foreach (IMyWarhead warhead in _Warheads)
                    {
                        warhead.IsArmed        = true;
                        warhead.DetonationTime = TIME;
                        warhead.StartCountdown();
                    }
                    Runtime.UpdateFrequency = UpdateFrequency.None;
                    _LogOutput?.WriteText("\nRUN!!!", true);
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// Returns true if the player can access the given terminal block. Blocks without ownership
        /// permissions require the player to have at least friendly relations with a big owner's faction.
        /// </summary>
        public static TerminalPermissionStates GetAccessPermissions(this IMyTerminalBlock block, long plyID = -1)
        {
            IMyCubeGrid grid = block.CubeGrid;
            TerminalPermissionStates accessState;

            if (plyID == -1)
            {
                plyID = MyAPIGateway.Session.LocalHumanPlayer.IdentityId;
            }

            if (block.GetIsBlockOwnable())
            {
                if (block.HasPlayerAccess(plyID))
                {
                    accessState = TerminalPermissionStates.Granted | TerminalPermissionStates.BlockFriendly;
                }
                else
                {
                    accessState = TerminalPermissionStates.Denied | TerminalPermissionStates.BlockUnfriendly;
                }

                return(accessState);
            }
            else
            {
                return(grid.GetAccessPermissions(plyID));
            }
        }
Beispiel #4
0
        void TryAddRelay(MyDataReceiver Receiver)
        {
            if (Receiver == null)
            {
                return;
            }
            if (Receiver == Antenna)
            {
                return;
            }
            if (RelayedReceivers.Contains(Receiver))
            {
                return;
            }
            IMyTerminalBlock ReceiverBlock = (Receiver.Entity as IMyTerminalBlock);

            if (ReceiverBlock != null)
            {
                if (!ReceiverBlock.HasPlayerAccess(AntennaBlock.OwnerId))
                {
                    return;
                }
                if (!ReceiverBlock.IsWorking)
                {
                    return;
                }
                IMyCubeGrid Grid = ReceiverBlock.CubeGrid.GetTopMostParent() as IMyCubeGrid;
                if (Grid == null || Grid == AntennaGrid)
                {
                    return;
                }

                RelayedReceivers.Add(Receiver);
                if (!RelayedGrids.Any(x => x.EntityId == Grid.EntityId))
                {
                    RelayedGrids.Add(Grid);
                    RelayedGridsIngame.Add(MyDetectedEntityInfoHelper.Create(Grid as MyEntity, AntennaBlock.OwnerId));
                }
            }
            else
            {
                IMyCharacter Char = Receiver.Entity as IMyCharacter;
                if (Char != null)
                {
                    if (Char.IsPlayer && !Char.IsDead && AntennaBlock.HasPlayerAccess(Char.ControllerInfo.ControllingIdentityId))
                    {
                        RelayedChars.Add(Char);
                    }
                }
            }
        }
        Dictionary <string, string> ReadBlock(IMyTerminalBlock Block)
        {
            Dictionary <string, string> BlockReadout = new Dictionary <string, string>();

            if (Block == null)
            {
                return(BlockReadout);
            }
            BlockReadout.Add("Type", Block.BlockDefinition.TypeId.ToString().Replace("MyObjectBuilder_", ""));
            BlockReadout.Add("Subtype", Block.BlockDefinition.SubtypeName);
            BlockReadout.Add("EntityID", Block.EntityId.ToString());
            BlockReadout.Add("Grid", Block.CubeGrid.EntityId.ToString());
            BlockReadout.Add("Enabled", (Block is IMyFunctionalBlock ? (Block as IMyFunctionalBlock).Enabled.ToString() : "null"));
            BlockReadout.Add("Functional", Block.IsFunctional.ToString());
            BlockReadout.Add("WorldPosition", Block.GetPosition().ToString());
            BlockReadout.Add("OwnerID", Block.OwnerId.ToString());
            BlockReadout.Add("Accessible", Block.HasPlayerAccess(RadarBlock.OwnerId).ToString());
            BlockReadout.Add("Occlusion", GetBlockOcclusion(Block).ToString());
            return(BlockReadout);
        }
Beispiel #6
0
        void Main()
        {
            List <IMyTerminalBlock> blocks      = GridTerminalSystem.Blocks;
            List <IMyBlockGroup>    blockGroups = GridTerminalSystem.BlockGroups;

            GridTerminalSystem.GetBlocksOfType <IMyCubeBlock>(blocks, FuncTest);
            GridTerminalSystem.SearchBlocksOfName(blockName, blocks, FuncTest);
            var block = GridTerminalSystem.GetBlockWithName(blockName);

            IMyCubeBlock cubeBlock     = block;
            bool         IsBeingHacked = cubeBlock.IsBeingHacked;
            bool         IsFunctional  = cubeBlock.IsFunctional;
            bool         IsWorking     = cubeBlock.IsWorking;

            VRageMath.Vector3I Position = cubeBlock.Position;

            IMyTerminalBlock terminalBlock         = block;
            string           CustomName            = terminalBlock.CustomName;
            string           CustomNameWithFaction = terminalBlock.CustomNameWithFaction;
            string           DetailedInfo          = terminalBlock.DetailedInfo;
            bool             HasLocalPlayerAccess  = terminalBlock.HasLocalPlayerAccess();
            bool             HasPlayerAccess       = terminalBlock.HasPlayerAccess(playerId);

            //terminalBlock.RequestShowOnHUD(enable);
            terminalBlock.SetCustomName(CustomName);
            //terminalBlock.SetCustomName(stringBuilder);
            bool ShowOnHUD = terminalBlock.ShowOnHUD;

            List <ITerminalAction> resultList = new List <ITerminalAction>();

            terminalBlock.GetActions(resultList, FuncTest);
            //terminalBlock.SearchActionsOfName(actionName, resultList, FuncTest);
            //ITerminalAction terminalAction = terminalBlock.GetActionWithName(actionName);

            //string Id = terminalAction.Id;
            //StringBuilder Name = terminalAction.Name;
            //terminalAction.Apply(cubeBlock);

            IMyFunctionalBlock functionalBlock = block as IMyFunctionalBlock;
            bool Enabled = functionalBlock.Enabled;
        }
Beispiel #7
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);
            }

            if (m_docking)
            {
                Communication.SendPrivateInformation(userId, "Server is busy");
                return(true);
            }

            m_docking = true;
            try
            {
                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, $"Unable to find player Id: {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, $"You do not have permission to use '{pylonName}'.  You must either own all the beacons or they must be shared with faction.");
                            return(true);
                        }
                    }

                    // Check for bounding box intsection of other docking zones
                    int intersectElement = 0;
                    if (Entity.CheckForIntersection(testList, beaconList, out intersectElement))
                    {
                        Communication.SendPrivateInformation(userId, $"The docking zone '{pylonName}' intersects with docking zone '{testList.ElementAt( intersectElement ).Key}'.  Make sure you place your docking zones so they don't overlap.");
                        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, $"Docking zone '{pylonName}' already contains the maximum capacity of ships.");
                        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>();
                    Wrapper.GameAction(() =>
                    {
                        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, $"The ship '{dockingEntity.DisplayName}' is too large for it's carrier.  The ship's bounding box must fit inside the docking zone bounding box!");
                            return(true);
                        }

                        if (targetBounding.Contains(ref dockingBounding) != ContainmentType.Contains)
                        {
                            Communication.SendPrivateInformation(userId, $"The ship '{dockingEntity.DisplayName}' is not fully inside the docking zone '{pylonName}'.  Make sure the ship is fully contained inside the docking zone");
                            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, $"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={dockingMass}kg CM={parentMass}kg)");
                            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 is MyCockpit);
                        foreach (IMySlimBlock slim in blocks)
                        {
                            //MyObjectBuilder_Cockpit c = (MyObjectBuilder_Cockpit)slim.FatBlock.GetObjectBuilderCubeBlock();
                            var c = (MyShipController)slim.FatBlock;
                            if (c.Pilot != null)
                            {
                                Communication.SendPrivateInformation(userId, $"Ship in docking zone '{pylonName}' has a pilot!  Please exit the ship before trying to dock.  (Sometimes this can lag a bit.  Wait 10 seconds and try again)");
                                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());

                        // Save ship to file and remove
                        FileInfo info = new FileInfo(Path.Combine(Essentials.PluginPath, "Docking", $"docked_{ownerId}_{parent.EntityId}_{dockingEntity.EntityId}.sbc"));
                        if (!Directory.Exists(info.DirectoryName))
                        {
                            Directory.CreateDirectory(info.DirectoryName);
                        }
                        //CubeGridEntity dockingGrid = new CubeGridEntity((MyObjectBuilder_CubeGrid)dockingEntity.GetObjectBuilder(), dockingEntity);
                        MyObjectBuilder_CubeGrid gridBuilder = CubeGrids.SafeGetObjectBuilder(dockingEntity);
                        if (gridBuilder == null)
                        {
                            Communication.SendPrivateInformation(userId, $"Failed to load entity for export: {dockingEntity.DisplayName}");
                            return(true);
                        }

                        // Save item
                        DockingItem dockItem = new DockingItem
                        {
                            DockedEntityId   = dockingEntity.EntityId,
                            TargetEntityId   = parent.EntityId,
                            PlayerId         = ownerId,
                            DockingBeaconIds = beaconList.Select(s => s.EntityId).ToArray( ),
                            DockedName       = dockingEntity.DisplayName,
                            SavePos          = savePos,
                            SaveQuat         = saveQuat
                        };
                        Docking.Instance.Add(dockItem);

                        // Serialize and save ship to file
                        MyObjectBuilderSerializer.SerializeXML(info.FullName, false, gridBuilder);
                        Wrapper.BeginGameAction(() => dockingEntity.Close( ));

                        Communication.SendPrivateInformation(userId, $"Docked ship '{dockItem.DockedName}' in docking zone '{pylonName}'.");
                        Log.Info("Docked ship \"{0}\" in docking zone \"{1}\". Saved to {2}", dockItem.DockedName, pylonName, info.FullName);

                        /*
                         * // Add a cool down
                         * DockingCooldownItem cItem = new DockingCooldownItem();
                         * cItem.name = pylonName;
                         * cItem.startTime = DateTime.Now;
                         * PluginDocking.CooldownList.Add(cItem);
                         */
                    }
                    else
                    {
                        Communication.SendPrivateInformation(userId, $"No ships in docking zone '{pylonName}'.");
                    }
                }
                else if (beaconList.Count > 4)
                {
                    Communication.SendPrivateInformation(userId, $"Too many beacons with the name or another zone with the name '{pylonName}'.  Place only 4 beacons to create a zone or try a different zone name.");
                }
                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);
            }
            catch (SecurityException ex)
            {
                Log.Error("Can't access docked ship file.", ex);
                return(false);
            }
            catch (UnauthorizedAccessException ex)
            {
                Log.Error("Can't access docked ship file.", ex);
                return(false);
            }
            catch (DirectoryNotFoundException ex)
            {
                Log.Error("Directory does not exist", ex);
                return(false);
            }
            catch (IOException ex)
            {
                Log.Error(ex);
                return(false);
            }
            finally
            {
                m_docking = false;
            }
        }
Beispiel #8
0
        public float TryTransferTo(IMyInventory TargetInventory, MyItemType ItemDef, float TargetAmount, IList <IMyInventory> SourceInventories)
        {
            if (TargetInventory == null)
            {
                throw new ArgumentNullException(nameof(TargetInventory));
            }
            if (SourceInventories == null)
            {
                throw new ArgumentNullException(nameof(SourceInventories));
            }
            if (SourceInventories.Count == 0)
            {
                return(0);
            }

            float YetToTransfer          = TargetAmount;
            List <MyInventoryItem> Items = new List <MyInventoryItem>(40);

            foreach (IMyInventory SourceInventory in SourceInventories)
            {
                if (!SourceInventory.Owner.HasInventory)
                {
                    continue;
                }
                if (SourceInventory.Owner is IMyTerminalBlock)
                {
                    IMyTerminalBlock SourceBlock = SourceInventory.Owner as IMyTerminalBlock;
                    if (!SourceBlock.IsFunctional)
                    {
                        continue;
                    }
                    if (!SourceBlock.HasPlayerAccess(MyKernel.Tool.OwnerId))
                    {
                        continue;
                    }
                }

                Items.Clear();
                if (Items.Capacity < 40)
                {
                    Items.Capacity = 40;
                }
                SourceInventory.GetItems(Items);
                foreach (MyInventoryItem Item in Items)
                {
                    MyItemType def    = Item.Type;
                    float      amount = (float)Item.Amount;

                    if (Item.Type != ItemDef)
                    {
                        continue;
                    }
                    float pullAmount = Math.Min(amount, YetToTransfer);
                    if (TargetInventory.CanItemsBeAdded((VRage.MyFixedPoint)pullAmount, Item.Type))
                    {
                        bool pull = SourceInventory.TransferItemTo(TargetInventory, Items.IndexOf(Item), amount: (VRage.MyFixedPoint)pullAmount);
                        if (pull)
                        {
                            YetToTransfer -= pullAmount;
                            if (YetToTransfer <= 0)
                            {
                                return(TargetAmount);
                            }
                        }
                    }
                    else
                    {
                        float FittableAmount = (float)(TargetInventory as Sandbox.Game.MyInventory).ComputeAmountThatFits(Item.Type);
                        if (FittableAmount > pullAmount)
                        {
                            FittableAmount = pullAmount;
                        }
                        bool pull = SourceInventory.TransferItemTo(TargetInventory, Items.IndexOf(Item), amount: (VRage.MyFixedPoint)FittableAmount);
                        if (pull)
                        {
                            YetToTransfer -= (float)FittableAmount;
                            return(TargetAmount - YetToTransfer);
                        }
                    }
                }
            }
            return(TargetAmount - YetToTransfer);
        }