VRageMath.Vector3D? IMyCubeGrid.GetLineIntersectionExactAll(ref VRageMath.LineD line, out double distance, out IMySlimBlock intersectedBlock)
 {
     MySlimBlock block;
     var retVal = GetLineIntersectionExactAll(ref line, out distance, out block);
     intersectedBlock = block;
     return retVal;
 }
示例#2
0
 public HullClassifier(IMySlimBlock block)
 {
     SlimBlock = block;
     FatBlock = block.FatBlock;
     m_SubTypeName = FatBlock.BlockDefinition.SubtypeName;
     Class = HullClassFromSubTypeString(m_SubTypeName);
 }
示例#3
0
        /// <summary>
        /// If we recognize the block's subtype as belonging to a classifier, return true
        /// </summary>
        public static bool isClassifierBlock(IMySlimBlock block)
        {
            IMyCubeBlock fatblock = block.FatBlock;
            if (fatblock != null && fatblock is Ingame.IMyBeacon) {
                String subTypeName = fatblock.BlockDefinition.SubtypeName;
                if (subTypeName.Contains(SHARED_SUBTYPE))
                    return true;
            }

            return false;
        }
        public bool Contains(IMySlimBlock block)
        {
            if (block.CubeGrid == null)
                return false;

            // FatBlock is null for non functional blocks such as armor
            if (block.FatBlock != null)
                return Contains(block.FatBlock);

            // since some blocks aren't an entity we have to deal with them otherwise
            // we'll create an grid that acts as substitute for the block to get an entity that has a collision
            // TODO find a better suited way to get the boundings of an armor block
            var worldPosition = block.CubeGrid.GetPosition() + block.Position;

            // creating grid
            var gridBuilder = new MyObjectBuilder_CubeGrid()
            {
                PersistentFlags = MyPersistentEntityFlags2.None,
                PositionAndOrientation = new MyPositionAndOrientation(worldPosition, Vector3.Forward, Vector3.Up),
                DisplayName = "substitute",
                GridSizeEnum = block.CubeGrid.GridSizeEnum
            };

            // creating cube block
            MyObjectBuilder_CubeBlock cube = new MyObjectBuilder_CubeBlock();
            cube.Min = block.Position;
            cube.SubtypeName = block.CubeGrid.GridSizeEnum == MyCubeSize.Large ? "LargeBlockArmorBlock" : "SmallBlockArmorBlock";
            cube.BuildPercent = 0;
            gridBuilder.CubeBlocks.Add(cube);

            // add grid
            MyAPIGateway.Entities.RemapObjectBuilder(gridBuilder);
            var entity = MyAPIGateway.Entities.CreateFromObjectBuilder(gridBuilder);
            var grid = entity as IMyCubeGrid;
            var blocks = new List<IMySlimBlock>();

            // get blocks
            grid.GetBlocks(blocks, b => b != null);

            if (blocks.Count > 0)
            {
                // found block
                var cubeBlock = blocks[0].FatBlock;
                bool isInside = Contains(cubeBlock);
                grid.Close();
                return isInside;
            }

            return false;
        }
示例#5
0
		/// <summary>
		/// if added is a thruster, call newThruster()
		/// </summary>
		/// <param name="added">block that was added</param>
		private void grid_OnBlockAdded(IMySlimBlock added)
		{
			MainLock.MainThread_ReleaseExclusive();
			try
			{
				if (added.FatBlock == null)
					return;

				if (added.FatBlock is IMyThrust)
					newThruster(added);
			}
			catch (Exception e)
			{ myLogger.alwaysLog("Exception: " + e, "grid_OnBlockAdded()", Logger.severity.ERROR); }
			finally
			{ MainLock.MainThread_AcquireExclusive(); }
		}
示例#6
0
        /// <summary>
        /// Does the passed block belong to this group?
        /// </summary>
        public bool appliesToBlock(IMySlimBlock block)
        {
            // IMySlimBlock.ToString() does:
            // FatBlock != null ? FatBlock.ToString() : BlockDefinition.DisplayNameText.ToString();
            // which is nice since we're not allowed access to BlockDefinition of a SlimBlock
            String blockString = block.ToString().ToLower();

            log("Does " + blockString + " belong in group " + SubTypeStrings.ToString() + " ? ",
                "appliedToBlock", Logger.severity.TRACE);

            foreach (String subType in SubTypeStrings) {
                if (blockString.Contains(subType.ToLower())) {
                    log("It does!", "appliedToBlock", Logger.severity.TRACE);
                    return true;
                }
            }
            log("It doesn't", "appliedToBlock", Logger.severity.TRACE);
            return false;
        }
示例#7
0
        public static void grid_OnBlockAdded(IMySlimBlock obj)
        {
            try
            {
                Logger.Log.Debug("BeaconSecurity.grid_OnBlockAdded {0}", obj);

                MyCubeGrid grid = obj.CubeGrid as MyCubeGrid;
                if (grid == null)
                    return;

                bool removing = false;
                if (!grid.DestructibleBlocks && Core.Settings != null && Core.Settings.BuildingNotAllowed)
                {
                    Logger.Log.Debug(" * DestructibleBlocks {0}, so block removed...", grid.DestructibleBlocks);
                    removing = true;
                }

                // check admins grids
                if (Core.Settings != null && Core.Settings.IndestructibleNoBuilds && Core.Settings.Indestructible.Contains(grid.EntityId) && !Core.Settings.IndestructibleOverrideBuilds.Contains(grid.EntityId))
                {
                    Logger.Log.Debug(" * Target '{0}' in indestructible list, so block removed...", grid.DisplayName);
                    removing = true;
                }

                if (removing)
                {
                    Logger.Log.Debug("RTY Grid: {0} {1} OBJ: {2} {3} POS: {4} {5}", grid, grid is IMyCubeGrid, obj, obj is IMySlimBlock, obj.Position, obj.CubeGrid.PositionComp);
                    Core.EnqueueRemoveBlock(obj);
                    //m_handler = new MyTimer.TimerEventHandler((a, b, c, d, e) =>
                    //{
                    //    TryToRemoveBlockFromGrid((grid as IMyCubeGrid), obj);
                    //});

                    //MyTimer.StartOneShot(10, m_handler);
                }
            }
            catch (Exception ex)
            {
                Logger.Log.Error("Exception grid_OnBlockAdded in {0}", ex.Message);
            }
        }
示例#8
0
        public WeldBlock(Mover mover, AllNavigationSettings navSet, PseudoBlock welder, IMySlimBlock block)
            : base(mover, navSet)
        {
            this.m_logger = new Logger(GetType().Name, () => mover.Block.CubeGrid.DisplayName, () => block.getBestName(), () => m_stage.ToString());
            this.m_offset = welder.Block.LocalAABB.GetLongestDim() * 0.5f; // this works for default welders, may not work if mod has an exotic design
            this.m_welder = welder;
            this.m_targetSlim = block;
            this.m_timeout_start = Globals.UpdateCount + TimeoutStart;

            IMyCubeBlock Projector = ((MyCubeGrid)block.CubeGrid).Projector;
            if (Projector != null)
            {
                this.m_weldProjection = true;
                this.m_otherGrid = Projector.CubeGrid;
                this.m_slimTarget_initDmg = 1f;
                this.m_targetCell = Projector.CubeGrid.WorldToGridInteger(block.CubeGrid.GridIntegerToWorld(block.Position));
            }
            else
            {
                this.m_weldProjection = false;
                this.m_slimTarget_initDmg = block.Damage();
                this.m_targetCell = block.Position;
            }

            m_navSet.Settings_Task_NavEngage.NavigatorMover = this;
            m_navSet.Settings_Task_NavEngage.NavigatorRotator = this;
            m_navSet.Settings_Task_NavEngage.DestinationEntity = m_realGrid;

            IEnumerator<Vector3I> neighbours = this.m_targetSlim.ForEachNeighbourCell();
            while (neighbours.MoveNext())
            {
                Vector3I cell = m_weldProjection ? Projector.CubeGrid.WorldToGridInteger(block.CubeGrid.GridIntegerToWorld(neighbours.Current)) : neighbours.Current;
                m_neighbours.Add(cell);
                if (this.m_realGrid.GetCubeBlock(cell) == null)
                    m_emptyNeighbours.Add(cell);
            }

            m_targetSlim.ComputeWorldCenter(out m_targetWorld);
            m_lineUp.To = m_targetWorld;
        }
示例#9
0
 private void updateProjectorsWithout(IMySlimBlock block)
 {
     // update projectors
     // track these outside of block types, because those are currently user-configurable
     InGame.IMyProjector projector = block.FatBlock as InGame.IMyProjector;
     if (projector != null) {
         log("Removed a projector", "blockRemoved");
         m_Projectors.Remove(projector.EntityId);
     }
 }
示例#10
0
 /// <summary>
 /// Decrements the BlockType counts for a given removed block
 /// </summary>
 private void updateBlockTypeCountsWithout(IMySlimBlock block)
 {
     BlockType[] types = s_Settings.BlockTypes;
     for (int i = 0; i < types.Length; i++) {
         BlockType type = types[i];
         if (type.appliesToBlock(block)) {
             m_BlockTypeCounts[i]--;
             log(type.DisplayName + " count now: " + m_BlockTypeCounts[i], "updateBlockCountsWithout");
             return;
         }
     }
 }
示例#11
0
        /// <summary>
        /// Applies the new class if block is a Classifier and we can reserve the Class
        /// Returns true if this was a happy update,
        /// false if the block needs to be removed
        /// </summary>
        /// <param name="block"></param>
        private VIOLATION_TYPE updateClassifiersWith(IMySlimBlock block)
        {
            log("", "updateClassificationWith");
            try {
                // If it's not a classifier, we don't care about it
                if (!HullClassifier.isClassifierBlock(block)) {
                    return VIOLATION_TYPE.NONE;
                }

                // load up the classifier helper object
                HullClassifier classifier = new HullClassifier(block);
                HullClass.CLASS classID = classifier.Class;
                log("Adding a classifier for class " + classID + " - " +
                    s_Settings.HullRules[(int)classID].DisplayName,
                    "updateClassificationWith");

                addClassifier(classifier);

                // Ensure it's the right type for this grid
                if (s_Settings.HullRules[(int)classifier.Class].ShouldBeStation && !m_Grid.IsStatic) {
                    return VIOLATION_TYPE.SHOULD_BE_STATIC;
                }

                // Two classifiers not allowed
                if (m_Classifiers.Count > 1) {
                    return VIOLATION_TYPE.TOO_MANY_CLASSIFIERS;
                }

                // Too many per Player/Faction not allowed
                if (!checkClassAllowed(classID)) {
                    return VIOLATION_TYPE.TOO_MANY_OF_CLASS;
                }
            }
            catch (Exception e) {
                log("Error: " + e, "updateClassificationWith", Logger.severity.ERROR);
            }

            return VIOLATION_TYPE.NONE;
        }
        private static bool DoesGridHaveTarget(IMyCubeGrid grid, IMySlimBlock block, bool disabling = false)
        {
            if (m_scanCache.Count < 1)
            {
                BoundingSphereD sphere = new BoundingSphereD(grid.GetPosition(), PluginSettings.Instance.DynamicTurretTargetDistance);
                m_scanCache = MyAPIGateway.Entities.GetEntitiesInSphere(ref sphere);
            }

            /*
             * HashSet<IMyEntity> testEntities = new HashSet<IMyEntity>();
             * try
             * {
             *      MyAPIGateway.Entities.GetEntities(testEntities);
             * }
             * catch
             * {
             *      return false;
             * }
             */
            //bool found = false;
            foreach (IMyEntity testEntity in m_scanCache)
            {
                if ((IMyEntity)grid == testEntity)
                {
                    continue;
                }

                if (!testEntity.InScene)
                {
                    continue;
                }

                if (testEntity is IMyCubeBlock)
                {
                    continue;

                    /*
                     * IMyCubeBlock cubeBlock = (IMyCubeBlock)testEntity;
                     * if (cubeBlock.OwnerId == 0)
                     *      continue;
                     *
                     * if (PluginSettings.Instance.DynamicTurretManagementType == DynamicTurretManagementTypes.AllButOwner)
                     * {
                     *      if (block.FatBlock.GetUserRelationToOwner(cubeBlock.OwnerId) != Sandbox.Common.MyRelationsBetweenPlayerAndBlock.Owner)
                     *      {
                     *              Console.WriteLine("Block: Not owner");
                     *              return true;
                     *      }
                     * }
                     *
                     * if (PluginSettings.Instance.DynamicTurretManagementType == DynamicTurretManagementTypes.NeutralAndEnemy)
                     * {
                     *      if (block.FatBlock.GetUserRelationToOwner(cubeBlock.OwnerId) == Sandbox.Common.MyRelationsBetweenPlayerAndBlock.Enemies ||
                     *              block.FatBlock.GetUserRelationToOwner(cubeBlock.OwnerId) == Sandbox.Common.MyRelationsBetweenPlayerAndBlock.Neutral)
                     *      {
                     *              Console.WriteLine("Block: Enemy or Neutral: {0} {1} {2}", cubeBlock.OwnerId, cubeBlock.Parent.DisplayName, cubeBlock.BlockDefinition);
                     *              return true;
                     *      }
                     * }
                     *
                     * if (PluginSettings.Instance.DynamicTurretManagementType == DynamicTurretManagementTypes.Enemy)
                     * {
                     *      if (block.FatBlock.GetUserRelationToOwner(cubeBlock.OwnerId) == Sandbox.Common.MyRelationsBetweenPlayerAndBlock.Enemies)
                     *      {
                     * //							Console.WriteLine("Block: Enemy: {0} {1} {2}", cubeBlock.OwnerId, cubeBlock.Parent.DisplayName, cubeBlock.BlockDefinition);
                     *              return true;
                     *      }
                     * }
                     */
                }

                if (testEntity is IMyCubeGrid)
                {
                    if (PluginSettings.Instance.DynamicTurretManagementType == DynamicTurretManagementTypes.All)
                    {
                        return(true);
                    }

                    IMyCubeGrid testGrid = (IMyCubeGrid)testEntity;
                    // Always enable if grid has no owner.  Seems suspect.  Might be a user trying to abuse a no ownership ship.

                    /*
                     * if (testGrid.BigOwners.Count < 1 && testGrid.SmallOwners.Count < 1)
                     * {
                     *      //if(!(testEntity is IMyControllableEntity))
                     *      //Console.WriteLine("Grid: No owner");
                     *      return true;
                     * }
                     */

                    foreach (long owner in testGrid.BigOwners)
                    {
                        if (PluginSettings.Instance.DynamicTurretManagementType == DynamicTurretManagementTypes.AllButOwner)
                        {
                            if (block.FatBlock.GetUserRelationToOwner(owner) != MyRelationsBetweenPlayerAndBlock.Owner)
                            {
                                //Console.WriteLine("Grid: Not owner");
                                return(true);
                            }
                        }

                        if (PluginSettings.Instance.DynamicTurretManagementType == DynamicTurretManagementTypes.NeutralAndEnemy)
                        {
                            if (block.FatBlock.GetUserRelationToOwner(owner) == MyRelationsBetweenPlayerAndBlock.Enemies ||
                                block.FatBlock.GetUserRelationToOwner(owner) == MyRelationsBetweenPlayerAndBlock.Neutral)
                            {
                                //Console.WriteLine("Grid: Enemy or Neutral: {0} {1}", owner, grid.DisplayName);
                                return(true);
                            }
                        }

                        if (PluginSettings.Instance.DynamicTurretManagementType == DynamicTurretManagementTypes.Enemy)
                        {
                            if (block.FatBlock.GetUserRelationToOwner(owner) == MyRelationsBetweenPlayerAndBlock.Enemies)
                            {
                                //Console.WriteLine("{3} Target: Grid - Enemy: {0} - {1} ({2})", block.FatBlock.OwnerId, owner, testEntity.DisplayName, ((IMyTerminalBlock)block.FatBlock).Parent.DisplayName);

                                //Console.WriteLine("Grid: Enemy: {0} {1}", owner, grid.DisplayName);
                                return(true);
                            }
                        }
                    }

                    foreach (long owner in testGrid.SmallOwners)
                    {
                        if (PluginSettings.Instance.DynamicTurretManagementType == DynamicTurretManagementTypes.AllButOwner)
                        {
                            if (block.FatBlock.GetUserRelationToOwner(owner) != MyRelationsBetweenPlayerAndBlock.Owner)
                            {
                                //Console.WriteLine("Grid: Not owner");
                                return(true);
                            }
                        }

                        if (PluginSettings.Instance.DynamicTurretManagementType == DynamicTurretManagementTypes.NeutralAndEnemy)
                        {
                            if (block.FatBlock.GetUserRelationToOwner(owner) == MyRelationsBetweenPlayerAndBlock.Enemies ||
                                block.FatBlock.GetUserRelationToOwner(owner) == MyRelationsBetweenPlayerAndBlock.Neutral)
                            {
                                //Console.WriteLine("Grid: Enemy or Neutral: {0} {1}", owner, grid.DisplayName);
                                return(true);
                            }
                        }

                        if (PluginSettings.Instance.DynamicTurretManagementType == DynamicTurretManagementTypes.Enemy)
                        {
                            if (block.FatBlock.GetUserRelationToOwner(owner) == MyRelationsBetweenPlayerAndBlock.Enemies)
                            {
                                //Console.WriteLine("Grid: Enemy: {0} {1}", owner, grid.DisplayName);
                                return(true);
                            }
                        }
                    }
                }
                else
                {
                    if (PluginSettings.Instance.DynamicTurretManagementType == DynamicTurretManagementTypes.All)
                    {
                        return(true);
                    }

                    if (testEntity is IMyCharacter)
//					var builderBase = testEntity.GetObjectBuilder();
//					if (builderBase is MyObjectBuilder_Character)
                    {
                        IMyPlayer   player   = null;
                        IMyIdentity identity = null;
                        long        playerId = 0;
                        try
                        {
                            identity = m_identityCache.FirstOrDefault(x => x.DisplayName == testEntity.DisplayName);
                            //List<IMyPlayer> players = new List<IMyPlayer>();
                            //MyAPIGateway.Players.GetPlayers(players);
                            //player = players.FirstOrDefault(x => x.DisplayName == testEntity.DisplayName);

                            if (player == null)
                            {
                                /*
                                 * //player = players.FirstOrDefault(x => x.Controller != null && x.Controller.ControlledEntity != null && x.Controller.ControlledEntity.Entity != null && x.Controller.ControlledEntity.Entity.EntityId == testEntity.EntityId);
                                 * if(testEntity is IMyControllableEntity)
                                 * {
                                 *      IMyControllableEntity control = (IMyControllableEntity)testEntity;
                                 *      List<PlayerMap.InternalPlayerItem> items = PlayerMap.Instance.GetPlayerItemsFromPlayerName(control.Entity.DisplayName);
                                 *      if (items != null)
                                 *              playerId = items.First().playerId;
                                 * }
                                 */
                            }
                        }
                        catch
                        {
                            //Console.WriteLine("{3} Target: Character - Unknown: {0} - {1} ({2})", block.FatBlock.OwnerId, testEntity.EntityId, testEntity.DisplayName, ((IMyTerminalBlock)block.FatBlock).Parent.DisplayName);
                            //Console.WriteLine("Unknown1: {0}", testEntity.DisplayName);
                            return(true);
                        }

                        if (identity == null)
                        {
                            //Console.WriteLine("{3} Target: Character - Unknown2: {0} - {1} ({2})", block.FatBlock.OwnerId, testEntity.EntityId, testEntity.DisplayName, ((IMyTerminalBlock)block.FatBlock).Parent.DisplayName);
                            //Console.WriteLine("Unknown2: {0} - {1}", testEntity.DisplayName, testEntity.GetFriendlyName());
                            return(true);
                            //continue;
                        }

                        if (identity != null)
                        {
                            playerId = identity.PlayerId;
                        }

                        if (player != null)
                        {
                            playerId = player.PlayerID;
                        }

                        if (PluginSettings.Instance.DynamicTurretManagementType == DynamicTurretManagementTypes.AllButOwner && block.FatBlock.GetUserRelationToOwner(playerId) != MyRelationsBetweenPlayerAndBlock.Owner)
                        {
                            //Console.WriteLine("Character: Not Owner: {0} - {1}", block.FatBlock.OwnerId, playerId);
                            return(true);
                        }

                        if (PluginSettings.Instance.DynamicTurretManagementType == DynamicTurretManagementTypes.NeutralAndEnemy)
                        {
                            if (block.FatBlock.GetUserRelationToOwner(playerId) == MyRelationsBetweenPlayerAndBlock.Enemies ||
                                block.FatBlock.GetUserRelationToOwner(playerId) == MyRelationsBetweenPlayerAndBlock.Neutral)
                            {
                                //Console.WriteLine("Character: Enemy or Neutral: {0} - {1}", block.FatBlock.OwnerId, playerId);
                                return(true);
                            }
                        }

                        if (PluginSettings.Instance.DynamicTurretManagementType == DynamicTurretManagementTypes.Enemy)
                        {
                            if (block.FatBlock.GetUserRelationToOwner(playerId) == MyRelationsBetweenPlayerAndBlock.Enemies)
                            {
                                //Console.WriteLine("{3} Target: Character - Enemy: {0} - {1} ({2})", block.FatBlock.OwnerId, playerId, testEntity.DisplayName, ((IMyTerminalBlock)block.FatBlock).Parent.DisplayName);
                                return(true);
                            }
                        }
                    }
                }
            }

            return(false);
        }
示例#13
0
        /// <summary>
        /// Forces a block to be removed, usually in the case of a rule violation.
        /// </summary>
        /// <param name="b"></param>
        private void removeBlock(IMySlimBlock b)
        {
            // spawn materials in place so they're not lost

            // TODO: determine best inventory target
            //IMyInventory inventory = null;

            // WAITING: once Keen accepts this PR
            // https://github.com/KeenSoftwareHouse/SpaceEngineers/pull/52
            // the below will spawn materials in the inventory if it exists and has space,
            // or otherwise as floating objects in space,
            //b.FullyDismount(inventory);
            //b.MoveItemsFromConstructionStockpile(inventory);
            //b.SpawnConstructionStockpile();

            m_Grid.RemoveBlock(b, true);
        }
        private void AddConnectedGridBlock(NaniteDeconstructionGrid deconstruct, IMySlimBlock slimBlock)
        {
            if (slimBlock.FatBlock == null)
            {
                return;
            }

            IMyCubeBlock cubeBlock  = (IMyCubeBlock)slimBlock.FatBlock;
            IMySlimBlock otherBlock = null;

            if (cubeBlock is IMyPistonBase)
            {
                IMyPistonBase pistonBase = (IMyPistonBase)cubeBlock;
                if (pistonBase.Top != null)
                {
                    MyCubeBlock cubeOther = (MyCubeBlock)pistonBase.Top;

                    if (deconstruct.GridsProcessed.Contains(cubeOther.CubeGrid))
                    {
                        return;
                    }

                    if (!deconstruct.AddingGridList.Contains(cubeOther.SlimBlock))
                    {
                        deconstruct.AddingGridList.Add(cubeOther.SlimBlock);
                        otherBlock = cubeOther.SlimBlock;
                    }
                }
            }
            else if (cubeBlock is Ingame.IMyShipConnector)
            {
                Ingame.IMyShipConnector connector = (Ingame.IMyShipConnector)cubeBlock;
                if (connector.Status == Sandbox.ModAPI.Ingame.MyShipConnectorStatus.Connected)
                {
                    MyCubeBlock cubeOther = (MyCubeBlock)connector.OtherConnector;

                    if (deconstruct.GridsProcessed.Contains(cubeOther.CubeGrid))
                    {
                        return;
                    }

                    if (!deconstruct.AddingGridList.Contains(cubeOther.SlimBlock))
                    {
                        deconstruct.AddingGridList.Add(cubeOther.SlimBlock);
                        otherBlock = cubeOther.SlimBlock;
                    }
                }
            }
            else if (cubeBlock is IMyAttachableTopBlock)
            {
                var motorRotor = cubeBlock as IMyAttachableTopBlock;
                if (motorRotor.Base != null)
                {
                    MyCubeBlock cubeOther = motorRotor.Base as MyCubeBlock;

                    if (deconstruct.GridsProcessed.Contains(cubeOther.CubeGrid))
                    {
                        return;
                    }

                    if (!deconstruct.AddingGridList.Contains(cubeOther.SlimBlock))
                    {
                        deconstruct.AddingGridList.Add(cubeOther.SlimBlock);
                        otherBlock = cubeOther.SlimBlock;
                    }
                }
            }
            else if (cubeBlock is IMyMechanicalConnectionBlock)
            {
                var motorBase = cubeBlock as IMyMechanicalConnectionBlock;
                if (motorBase.TopGrid != null)
                {
                    var cubeOther = motorBase.Top as MyCubeBlock;

                    if (deconstruct.GridsProcessed.Contains(cubeOther.CubeGrid))
                    {
                        return;
                    }

                    if (!deconstruct.AddingGridList.Contains(cubeOther.SlimBlock))
                    {
                        deconstruct.AddingGridList.Add(cubeOther.SlimBlock);
                        otherBlock = cubeOther.SlimBlock;
                    }
                }
            }
        }
        IEnumerator <bool> GrindBlocks(ICollection <IMySlimBlock> Blocks)
        {
            if (Blocks.Count == 0)
            {
                yield return(false);
            }
            if (MyKernel.TermControls.ToolMode == true)
            {
                yield return(false);
            }

            if (MyKernel.TermControls.DistanceMode)
            {
                IMySlimBlock ClosestBlock = Blocks.OrderBy(x => Vector3D.DistanceSquared(x.CubeGrid.GridIntegerToWorld(x.Position), MyKernel.Block.GetPosition())).First();
                Blocks.Clear();
                Blocks.Add(ClosestBlock);
            }
            float SpeedRatio = (VanillaToolConstants.GrinderSpeed * NominalWorkingFrequency * MyKernel.TermControls.SpeedMultiplier * WeldGrindSpeedMultiplier) / Blocks.Count;

            foreach (IMySlimBlock Block in Blocks)
            {
                Block.DoDamage(0, MyStringHash.GetOrCompute("Grind"), true, null, MyKernel.Block.EntityId);
            }

            int grindedBlocks = 0;

            if (MyKernel.Session.Settings.AllowAsyncWelding)
            {
                Action worker = () =>
                {
                    foreach (IMySlimBlock Block in Blocks)
                    {
                        grindedBlocks++;
                        MyAPIGateway.Parallel.StartBackground(() => Grind(Block, SpeedRatio, Raze: false));
                    }
                };
                bool   completed = false;
                Action callback  = () => completed = true;
                MyAPIGateway.Parallel.StartBackground(worker, callback);
                while (!completed)
                {
                    yield return(true);
                }

                List <IMySlimBlock> blocksToRaze = Blocks.Where(x => x.IsFullyDismounted).ToList();
                foreach (IMySlimBlock Block in blocksToRaze)
                {
                    Block.CubeGrid.RazeBlock(Block.Position);
                }
            }
            else
            {
                Stopwatch watch = new Stopwatch();
                foreach (IMySlimBlock Block in Blocks)
                {
                    grindedBlocks++;
                    //WriteToLog($"GrindBlocks", $"Block pre-grind", EemRdx.SessionModules.LoggingLevelEnum.DebugLog);
                    watch.Start();
                    Grind(Block, SpeedRatio);
                    //WriteToLog($"GrindBlocks", $"Block post-grind", EemRdx.SessionModules.LoggingLevelEnum.DebugLog);
                    watch.Stop();
                    if ((grindedBlocks + 1) < Blocks.Count)
                    {
                        yield return(true);
                    }
                }
                watch.Stop();
                if (MyAPIGateway.Session.IsServer && MyKernel.Session.Settings.Debug)
                {
                    WriteToLog($"GrindBlocks[{MyKernel.Block.CustomName}]", $"Grinding in total took {Math.Round(watch.Elapsed.TotalMilliseconds, 3)}ms", EemRdx.SessionModules.LoggingLevelEnum.ProfilingLog);
                }
            }

            //WriteToLog($"GrindBlocks", $"Exiting GrindBlocks", EemRdx.SessionModules.LoggingLevelEnum.DebugLog);
            yield return(false);
        }
示例#16
0
 /// <summary>
 ///     Checks if given slim block is projected or a preview.
 /// </summary>
 /// <param name="slimBlock">The given slim block to check.</param>
 /// <returns>Return true if if slim block is projected or a preview.</returns>
 public static bool IsProjected(this IMySlimBlock slimBlock)
 {
     return(slimBlock.CubeGrid.IsProjected());
 }
示例#17
0
        /// <summary>
        ///     MUST CALL RECREATEFACTION FIRST!
        /// </summary>
        /// <param name="ob"></param>
        /// <param name="playerId"></param>
        public static void FindPositionAndSpawn(MyObjectBuilder_CubeGrid ob, long playerId, Vector3I controlledBlock)
        {
            MyAPIGateway.Entities.RemapObjectBuilder(ob);
            ob.IsStatic = false;
            IMyEntity  ent = MyAPIGateway.Entities.CreateFromObjectBuilder(ob);
            IMyFaction fac = MyAPIGateway.Session.Factions.TryGetPlayerFaction(playerId);

            foreach (MyObjectBuilder_CubeBlock block in ob.CubeBlocks)
            {
                block.Owner = playerId;
                var c = block as MyObjectBuilder_Cockpit;
                if (c == null)
                {
                    continue;
                }
                c.Pilot = null;
            }

            Vector3D pos = RandomPositionFromPoint(Vector3D.Zero, Random.NextDouble() * Settings.Instance.SpawnRadius);

            ent.SetPosition(MyAPIGateway.Entities.FindFreePlace(pos, (float)ent.WorldVolume.Radius) ?? pos);

            IMyPlayer player = GetPlayerById(playerId);

            if (fac != null)
            {
                var entities = new HashSet <IMyEntity>();
                MyAPIGateway.Entities.GetEntities(entities);
                foreach (IMyEntity entity in entities)
                {
                    var g = entity as IMyCubeGrid;
                    if (g == null)
                    {
                        continue;
                    }

                    if (g.BigOwners.Count == 0)
                    {
                        continue;
                    }

                    long       owner = g.BigOwners[0];
                    IMyFaction f     = MyAPIGateway.Session.Factions.TryGetPlayerFaction(owner);
                    if (f != fac)
                    {
                        continue;
                    }

                    Vector3D p = RandomPositionFromPoint(g.GetPosition(), 100);
                    ent.SetPosition(MyAPIGateway.Entities.FindFreePlace(p, (float)ent.WorldVolume.Radius) ?? p);

                    break;
                }
            }
            MyAPIGateway.Entities.AddEntity(ent);
            ((IMyCubeGrid)ent).ChangeGridOwnership(playerId, MyOwnershipShareModeEnum.Faction);

            IMySlimBlock slim = ((IMyCubeGrid)ent).GetCubeBlock(controlledBlock);

            if (slim?.FatBlock is IMyCockpit && player?.Character != null)
            {
                var c = (IMyCockpit)slim.FatBlock;
                player.Character.SetPosition(c.GetPosition());
                c.AttachPilot(player.Character);
            }
            else
            {
                Vector3D cPos = RandomPositionFromPoint(ent.WorldVolume.Center, ent.WorldVolume.Radius + 10);
                player?.Character?.SetPosition(cPos);
            }
        }
示例#18
0
 public EasyBlock(IMyTerminalBlock Block)
 {
     this.Block = Block;
     this.slim  = null;
 }
示例#19
0
        /// <summary>
        /// Adds thruster to thrustersInDirection
        /// </summary>
        /// <param name="thruster">The new thruster</param>
        private void newThruster(IMySlimBlock thruster)
        {
            if (TP_ThrustOverride == null)
                TP_ThrustOverride = ((IMyTerminalBlock)thruster.FatBlock).GetProperty("Override") as ITerminalProperty<float>;

            using (lock_thrustersInDirection.AcquireExclusiveUsing())
            thrustersInDirection[Base6Directions.GetFlippedDirection(thruster.FatBlock.Orientation.Forward)].Add(thruster.FatBlock as MyThrust);
            if (TP_ThrustOverride.GetValue(thruster.FatBlock) != 0f)
                TP_ThrustOverride.SetValue(thruster.FatBlock, 0f);
        }
示例#20
0
        public void TargetIntersectionCheck()
        {
            _entityScanList.Clear();
            _voxelScanList.Clear();
            _entityScanList = new List <MyLineSegmentOverlapResult <MyEntity> >();
            MyGamePruningStructure.GetTopmostEntitiesOverlappingRay(ref Line, _entityScanList);

            IMyCubeGrid closestGrid         = null;
            double      closestGridDistance = -1;

            MySafeZone closestZone         = null;
            double     closestZoneDistance = -1;

            IMyCharacter closestCharacter         = null;
            double       closestCharacterDistance = -1;

            foreach (var item in _entityScanList)
            {
                var targetGrid   = item.Element as IMyCubeGrid;
                var targetZone   = item.Element as MySafeZone;
                var targetVoxel  = item.Element as MyVoxelBase;
                var targetPlayer = item.Element as IMyCharacter;

                if (targetGrid != null)
                {
                    if (targetGrid == _collisionSystem.RemoteControl.SlimBlock.CubeGrid || _collisionSystem.RemoteControl.SlimBlock.CubeGrid.IsSameConstructAs(targetGrid))
                    {
                        continue;
                    }

                    if (closestGrid == null || (closestGrid != null && item.Distance < closestGridDistance))
                    {
                        closestGrid         = targetGrid;
                        closestGridDistance = item.Distance;
                    }
                }

                if (targetZone != null)
                {
                    if (closestZone == null || (closestZone != null && item.Distance < closestZoneDistance))
                    {
                        closestZone         = targetZone;
                        closestZoneDistance = item.Distance;
                    }
                }

                if (targetVoxel != null)
                {
                    _voxelScanList.Add(targetVoxel);
                }

                if (targetPlayer != null)
                {
                    if (closestCharacter == null || (closestCharacter != null && item.Distance < closestCharacterDistance))
                    {
                        closestCharacter         = targetPlayer;
                        closestCharacterDistance = item.Distance;
                    }
                }
            }

            if (closestGrid != null)
            {
                double minDist        = 0;
                double maxDist        = 0;
                bool   boxCheckResult = closestGrid.PositionComp.WorldAABB.Intersect(ref Ray, out minDist, out maxDist);

                Vector3D startBox = boxCheckResult ? (minDist - 5) * DirectionVector + StartPosition : StartPosition;
                Vector3D endBox   = boxCheckResult ? (maxDist + 5) * DirectionVector + StartPosition : EndPosition;

                var blockPos = closestGrid.RayCastBlocks(startBox, endBox);

                if (!blockPos.HasValue)
                {
                    return;
                }

                IMySlimBlock slimBlock = closestGrid.GetCubeBlock(blockPos.Value);

                if (slimBlock == null)
                {
                    return;
                }

                Vector3D blockPosition = Vector3D.Zero;
                slimBlock.ComputeWorldCenter(out blockPosition);


                GridCoords   = blockPosition;
                GridDistance = Vector3D.Distance(blockPosition, StartPosition);
                GridEntity   = closestGrid;
                GridOwner    = OwnershipHelper.GetOwnershipTypes(closestGrid, false);
                GridRelation = OwnershipHelper.GetTargetReputation(_collisionSystem.Owner, closestGrid, false);
            }

            if (closestZone != null)
            {
                SafezoneEntity   = closestZone;
                SafezoneCoords   = closestZoneDistance * DirectionVector + StartPosition;
                SafezoneDistance = closestZoneDistance;
            }

            if (closestCharacter != null)
            {
                PlayerEntity   = closestCharacter;
                PlayerCoords   = PlayerEntity.PositionComp.WorldAABB.Center;
                PlayerDistance = closestCharacterDistance;
            }
        }
        private void CreateRemovalOrder(NaniteDeconstructionGrid deconstruct, IMySlimBlock startBlock)
        {
            IMySlimBlock currentBlock = startBlock;

            deconstruct.AddingList.Clear();
            deconstruct.GridsProcessed.Clear();

            while (true)
            {
                if (!deconstruct.GridsProcessed.Contains(currentBlock.CubeGrid))
                {
                    ((MyCubeGrid)currentBlock.CubeGrid).OnGridSplit += OnGridSplit;
                    deconstruct.GridsProcessed.Add(currentBlock.CubeGrid);
                }

                MyObjectBuilder_CubeBlock block = (MyObjectBuilder_CubeBlock)currentBlock.GetObjectBuilder();
                MyCubeBlockDefinition     blockDefinition;
                MyDefinitionManager.Static.TryGetCubeBlockDefinition(block.GetId(), out blockDefinition);

                // Get real block max
                Vector3I Max = Vector3I.Zero;
                Vector3I Min = block.Min;
                ComputeMax(blockDefinition, block.BlockOrientation, ref Min, out Max);

                AddNeighbours(deconstruct, currentBlock, Min, new Vector3I(Min.X, Max.Y, Max.Z), -Vector3I.UnitX);
                AddNeighbours(deconstruct, currentBlock, Min, new Vector3I(Max.X, Min.Y, Max.Z), -Vector3I.UnitY);
                AddNeighbours(deconstruct, currentBlock, Min, new Vector3I(Max.X, Max.Y, Min.Z), -Vector3I.UnitZ);
                AddNeighbours(deconstruct, currentBlock, new Vector3I(Max.X, Min.Y, Min.Z), Max, Vector3I.UnitX);
                AddNeighbours(deconstruct, currentBlock, new Vector3I(Min.X, Max.Y, Min.Z), Max, Vector3I.UnitY);
                AddNeighbours(deconstruct, currentBlock, new Vector3I(Min.X, Min.Y, Max.Z), Max, Vector3I.UnitZ);

                // Check if currentBlock is a connector of some kind, then follow it
                AddConnectedGridBlock(deconstruct, currentBlock);

                // Add to removal list
                if (!deconstruct.RemoveList.Contains(currentBlock))
                {
                    deconstruct.RemoveList.AddStart(currentBlock);
                }

                if (deconstruct.AddingList.Count < 1 && deconstruct.AddingGridList.Count < 1)
                {
                    break;
                }

                if (deconstruct.AddingList.Count < 1 && deconstruct.AddingGridList.Count > 0)
                {
                    currentBlock = deconstruct.AddingGridList[0];
                    deconstruct.AddingGridList.Remove(currentBlock);
                    //deconstruct.TreePosition++;
                    //deconstruct.GridTree.Add(new Node<IMySlimBlock>(currentBlock));
                }
                else
                {
                    currentBlock = deconstruct.AddingList[0];
                    deconstruct.AddingList.Remove(currentBlock);
                }
            }

            // Find user defined priority blocks for deconstruction.
            FindPriorityBlocks(deconstruct, startBlock);

            Logging.Instance.WriteLine(string.Format("Block Count: {0}", deconstruct.RemoveList.Count));
            //Logging.Instance.WriteLine(string.Format("Grid Count: {0}", deconstruct.GridsProcessed.Count));
            //Logging.Instance.WriteLine(string.Format("Tree Size: {0}", deconstruct.GridTree.Sum(x => x.All.Count())));
        }
        private void ProcessItem(IMySlimBlock target)
        {
            if (Sync.IsServer)
            {
                if (!IsEnabled())
                {
                    Logging.Instance.WriteLine("CANCELLING Deconstruction Target due to being disabled");
                    CancelTarget(target);
                    return;
                }

                if (!NaniteConstructionPower.HasRequiredPowerForCurrentTarget((IMyFunctionalBlock)m_constructionBlock.ConstructionBlock))
                {
                    Logging.Instance.WriteLine("CANCELLING Deconstruction Target due to power shortage");
                    CancelTarget(target);
                    return;
                }

                if (m_constructionBlock.FactoryState != NaniteConstructionBlock.FactoryStates.Active)
                {
                    return;
                }

                NaniteGrinder grinder = (NaniteGrinder)m_constructionBlock.ToolManager.Tools.FirstOrDefault(x => x.TargetBlock == target && x is NaniteGrinder);
                if (grinder == null)
                {
                    double distance = EntityHelper.GetDistanceBetweenBlockAndSlimblock((IMyCubeBlock)m_constructionBlock.ConstructionBlock, target);
                    int    time     = (int)Math.Max(GetMinTravelTime() * 1000f, (distance / GetSpeed()) * 1000f);
                    grinder = new NaniteGrinder(m_constructionBlock, target, (int)(time / 2.5f), NaniteConstructionManager.Settings.DeconstructionPerformanceFriendly);
                    m_constructionBlock.ToolManager.Tools.Add(grinder);
                    m_constructionBlock.SendAddTarget(target, TargetTypes.Deconstruction);
                }

                if (m_areaTargetBlocks.ContainsKey(target.CubeGrid))
                {
                    if (!m_areaTargetBlocks[target.CubeGrid].IsInsideBox(target.CubeGrid.WorldAABB, false))
                    {
                        CancelTarget(target);
                        RemoveGridTarget(target.CubeGrid);
                        return;
                    }

                    if (target.CubeGrid.Physics.LinearVelocity.LengthSquared() != 0f || target.CubeGrid.Physics.AngularVelocity.LengthSquared() != 0f)
                    {
                        CancelTarget(target);
                        return;
                    }
                }

                if (target.IsDestroyed || target.IsFullyDismounted || target.CubeGrid.GetCubeBlock(target.Position) == null || (target.FatBlock != null && target.FatBlock.Closed))
                {
                    CompleteTarget(target);
                    return;
                }

                if (target.CubeGrid.Closed)
                {
                    Logging.Instance.WriteLine("CANCELLING Deconstruction Target due to grid being closed");
                    CancelTarget(target);
                    return;
                }

                if (EntityHelper.GetDistanceBetweenBlockAndSlimblock((IMyCubeBlock)m_constructionBlock.ConstructionBlock, target) > m_maxDistance)
                {
                    Logging.Instance.WriteLine("CANCELLING Deconstruction Target due to target being out of range");
                    CancelTarget(target);
                    return;
                }
            }

            CreateDeconstructionParticle(target);
        }
示例#23
0
        /// <summary>
        /// Called when a block is removed.  Decrements counts and checks for declassification.
        /// </summary>
        /// <param name="removed"></param>
        private void blockRemoved(IMySlimBlock removed)
        {
            try {
                updateClassificationWithout(removed);
                decrementBlockCount();
                updateBlockTypeCountsWithout(removed);
                updateProjectorsWithout(removed);

                log(removed.ToString() + " removed from grid '" + m_Grid.DisplayName +
                    "'. Total Count now: " + m_BlockCount, "blockRemoved");

                m_CheckCleanupNextUpdate = true;

            } catch (Exception e) {
                log("Error: " + e, "blockRemoved");
            }
        }
示例#24
0
 void IMyProjector.Build(IMySlimBlock cubeBlock, long owner, long builder)
 {
     Build((MySlimBlock)cubeBlock, owner, builder);
 }
示例#25
0
        /*public static bool IsPeacefulNPC(this IMyFaction Faction)
         * {
         *  try
         *  {
         *      if (!Faction.IsNPC()) return false;
         *      return Diplomacy.LawfulFactionsTags.Contains(Faction.Tag);
         *  }
         *  catch (Exception Scrap)
         *  {
         *      AISessionCore.LogError("Faction.IsPeacefulNPC", Scrap);
         *      return false;
         *  }
         * }*/

        public static float GetHealth(this IMySlimBlock Block)
        {
            return(Math.Min(Block.DamageRatio, Block.BuildLevelRatio));
        }
        internal bool ProcessMissingComponents(IMySlimBlock target)
        {
            if (MyAPIGateway.Session.CreativeMode)
            {
                return(true);
            }

            int pos = 0;

            try
            {
                IMyInventory inventory = GetConstructionInventory();
                if (inventory == null)
                {
                    Logging.Instance.WriteLine(string.Format("Inventory {0} is null.", inventory == null));
                    return(false);
                }

                Dictionary <string, int> missingComponents = new Dictionary <string, int>();
                // Target block is on a real grid
                if (target.CubeGrid.Physics != null)
                {
                    target.GetMissingComponents(missingComponents);
                    if (missingComponents.Count == 0)
                    {
                        return(true);
                    }
                }
                else // Target block is projection, let's just put 1 item in it
                {
                    try
                    {
                        MyCubeBlockDefinition blockDefinition = (MyCubeBlockDefinition)target.BlockDefinition;
                        missingComponents.Add(blockDefinition.Components[0].Definition.Id.SubtypeName, 1);
                    }
                    catch (Exception ex)
                    {
                        Logging.Instance.WriteLine(string.Format("Process Error: {0}", ex.ToString()));
                        return(false);
                    }
                }

                foreach (var item in inventory.GetItems().ToList())
                {
                    if (missingComponents.ContainsKey(item.Content.SubtypeName))
                    {
                        var amount = (float)missingComponents[item.Content.SubtypeName];
                        if (amount >= (float)item.Amount)
                        {
                            amount = (float)item.Amount;
                        }

                        missingComponents[item.Content.SubtypeName] -= (int)item.Amount;
                        if (missingComponents[item.Content.SubtypeName] <= 0)
                        {
                            missingComponents.Remove(item.Content.SubtypeName);
                        }

                        inventory.RemoveItemsOfType((int)amount, (MyObjectBuilder_PhysicalObject)item.Content);
                    }
                }

                if (missingComponents.Count == 0)
                {
                    return(true);
                }

                return(false);
            }
            catch (Exception ex)
            {
                Logging.Instance.WriteLine(string.Format("Exception {0} : {1}", pos, ex.ToString()));
                return(false);
            }
        }
示例#27
0
        /// <summary>
        /// Updates the appearance of the block if the integrity has changed. Only used for welding/griding.
        /// </summary>
        private static void UpdateBlockModel(IMySlimBlock realBlock, IMyCubeGrid holoGrid)
        {
            IMySlimBlock holoBlock = holoGrid.GetCubeBlock(realBlock.Position);
            Static.logger.debugLog(holoBlock == null, "holoBlock == null", Logger.severity.FATAL);

            float realIntegrityRatio = (realBlock.BuildIntegrity - realBlock.CurrentDamage) / realBlock.MaxIntegrity;
            float holoIntegrityRatio = (holoBlock.BuildIntegrity - holoBlock.CurrentDamage) / holoBlock.MaxIntegrity;

            if (realIntegrityRatio == holoIntegrityRatio)
                return;

            float min, max;
            if (realIntegrityRatio > holoIntegrityRatio)
            {
                max = realIntegrityRatio;
                min = holoIntegrityRatio;
            }
            else
            {
                max = holoIntegrityRatio;
                min = realIntegrityRatio;
            }

            if (((MyCubeBlockDefinition)realBlock.BlockDefinition).ModelChangeIsNeeded(min, max))
            {
                holoGrid.RemoveBlock(holoBlock);

                MyObjectBuilder_CubeBlock objBuilder = realBlock.GetObjectBuilder();
                objBuilder.EntityId = 0L;
                holoGrid.AddBlock(objBuilder, false);

                IMyCubeBlock cubeBlock = holoGrid.GetCubeBlock(realBlock.Position).FatBlock;
                if (cubeBlock != null)
                    SetupProjection(cubeBlock);
            }
        }
 public static double GetDistanceBetweenBlockAndSlimblock(IMyCubeBlock block, IMySlimBlock slimBlock)
 {
     return(Vector3D.Distance(block.GetPosition(), GetBlockPosition(slimBlock)));
 }
		public static void SetBuildPercent(IMySlimBlock block, float percent)
		{
			try
			{
				// Set locally
				object constructionManager = GetEntityFieldValue(block, CubeBlockConstructionManagerField);
				float maxIntegrity = (float)InvokeEntityMethod(constructionManager, ConstructionManagerGetMaxIntegrityMethod);
				float integrity = percent * maxIntegrity;
				float build = percent * maxIntegrity;
				InvokeEntityMethod(constructionManager, ConstructionManagerSetIntegrityBuildValuesMethod, new object[] { build, integrity });

				// Broadcast to players
				Type someEnum = CubeGridEntity.InternalType.GetNestedType(CubeGridNetworkManager.CubeGridIntegrityChangeEnumClass);
				Array someEnumValues = someEnum.GetEnumValues();
				object enumValue = someEnumValues.GetValue(0);
				object netManager = BaseObject.InvokeEntityMethod(block.CubeGrid, CubeGridNetworkManager.CubeGridGetNetManagerMethod);
				BaseObject.InvokeEntityMethod(netManager, CubeGridNetworkManager.CubeGridNetManagerBroadcastCubeBlockBuildIntegrityValuesMethod, new object[] { block, enumValue, 0L });
			}
			catch (Exception ex)
			{
				LogManager.ErrorLog.WriteLineAndConsole(string.Format("SetBuildPercent(): {0}", ex.ToString()));
			}

		}
 public static Vector3D GetBlockPosition(IMySlimBlock slimBlock)
 {
     return(slimBlock.CubeGrid.GridIntegerToWorld(slimBlock.Position));
 }
示例#31
0
 BuildCheckResult IMyProjector.CanBuild(IMySlimBlock projectedBlock, bool checkHavokIntersections)
 {
     return(CanBuild((MySlimBlock)projectedBlock, checkHavokIntersections));
 }
示例#32
0
 public static Vector3D GetPosition(this IMySlimBlock block)
 {
     return(block.CubeGrid.GridIntegerToWorld(block.Position));
 }
        IEnumerator <bool> WeldAndPlaceBlocks(ICollection <IMySlimBlock> RealBlocks, ICollection <IMySlimBlock> ProjectedBlocks)
        {
            if (RealBlocks == null || ProjectedBlocks == null)
            {
                yield return(false);
            }
            if (RealBlocks.Count == 0 && ProjectedBlocks.Count == 0)
            {
                yield return(false);
            }
            if (MyKernel.TermControls.ToolMode == false)
            {
                yield return(false);
            }
            if (!SafeZonesHelper.IsActionAllowed(MyKernel.Block.GetPosition(), MySafeZoneAction.Welding | MySafeZoneAction.Building, MyKernel.Block.EntityId))
            {
                yield return(false);
            }

            bool ShouldContinue = RealBlocks.Count > 0 || ProjectedBlocks.Count > 0;

            //MyKernel.SessionBase.Log.DebugLog.WriteToLog($"WeldAndPlaceBlocks", $"Entry Point: real blocks: {RealBlocks.Count}, projected blocks: {ProjectedBlocks.Count}, should continue: {ShouldContinue}");

            if (!ShouldContinue)
            {
                yield return(false);
            }

            if (MyKernel.TermControls.DistanceMode && RealBlocks.Count > 0)
            {
                IMySlimBlock FarthestBlock = RealBlocks.OrderBy(x => Vector3D.DistanceSquared(x.CubeGrid.GridIntegerToWorld(x.Position), MyKernel.Block.GetPosition())).Last();
                RealBlocks.Clear();
                RealBlocks.Add(FarthestBlock);
                //MyKernel.SessionBase.Log.DebugLog.WriteToLog($"WeldAndPlaceBlocks", $"Selected block for distance mode");
            }

            float        SpeedRatio   = NominalWorkingFrequency * MyKernel.TermControls.SpeedMultiplier * WeldGrindSpeedMultiplier * (VanillaToolConstants.WelderSpeed / RealBlocks.Count);
            float        BoneFixSpeed = VanillaToolConstants.WelderBoneRepairSpeed * NominalWorkingFrequency;
            IMyProjector Projector    = null;

            if (ProjectedBlocks.Count > 0)
            {
                Projector = ((ProjectedBlocks.First().CubeGrid as MyCubeGrid).Projector as IMyProjector);
            }

            //MyKernel.SessionBase.Log.DebugLog.WriteToLog($"WeldAndPlaceBlocks", $"Checked for projectors");

            if (!MyAPIGateway.Session.CreativeMode)
            {
                Dictionary <string, int> RequiredComponentNames = new Dictionary <string, int>();

                {
                    Action worker = () =>
                    {
                        foreach (IMySlimBlock Block in RealBlocks)
                        {
                            Block.GetMissingComponents(RequiredComponentNames);
                        }
                    };
                    bool   completed = false;
                    Action callback  = () => completed = true;
                    MyAPIGateway.Parallel.StartBackground(worker, callback);
                    while (!completed)
                    {
                        yield return(true);
                    }
                }

                //MyKernel.SessionBase.Log.DebugLog.WriteToLog($"WeldAndPlaceBlocks", $"Got missing components");

                foreach (IMySlimBlock Block in ProjectedBlocks)
                {
                    var FirstItem = ((MyCubeBlockDefinition)Block.BlockDefinition).Components[0].Definition.Id;
                    if (RequiredComponentNames.ContainsKey(FirstItem.SubtypeName))
                    {
                        RequiredComponentNames[FirstItem.SubtypeName] += 1;
                    }
                    else
                    {
                        RequiredComponentNames.Add(FirstItem.SubtypeName, 1);
                    }
                }

                //MyKernel.SessionBase.Log.DebugLog.WriteToLog($"WeldAndPlaceBlocks", $"Got missing components for projected blocks");

                Dictionary <MyItemType, float> RequiredComponents = new Dictionary <MyItemType, float>();
                var list = RequiredComponentNames.ToList();

                foreach (KeyValuePair <string, int> kvp in list)
                {
                    //MyKernel.SessionBase.Log.DebugLog.WriteToLog($"WeldAndPlaceBlocks", $"Trying to generate itemtype...");
                    //MyKernel.SessionBase.Log.DebugLog.WriteToLog($"WeldAndPlaceBlocks", $"for {kvp.Key}");
                    MyItemType itemtype = new MyItemType("MyObjectBuilder_Component", kvp.Key);
                    //MyKernel.SessionBase.Log.DebugLog.WriteToLog($"WeldAndPlaceBlocks", $"Generated item value");
                    //MyKernel.SessionBase.Log.DebugLog.WriteToLog($"WeldAndPlaceBlocks", $"(item: {itemtype.SubtypeId}, amount: {kvp.Value})");
                    RequiredComponents.Add(itemtype, kvp.Value);
                }

                //MyKernel.SessionBase.Log.DebugLog.WriteToLog($"WeldAndPlaceBlocks", $"Reassembled missing dictionary");

                List <IMyTerminalBlock> InventoryOwners = new List <IMyTerminalBlock>(MyKernel.Inventory.InventoryOwners);
                InventoryOwners.Add(MyKernel.Tool);

                InventoryModule.CalculateMissingItems(RequiredComponents, MyKernel.Inventory.GetAggregateItemsFor(InventoryOwners));

                //MyKernel.SessionBase.Log.DebugLog.WriteToLog($"WeldAndPlaceBlocks", $"Calculated aggregate missing components");

                if (MyKernel.Tool.UseConveyorSystem)
                {
                    Dictionary <MyItemType, float> _RqComponents = new Dictionary <MyItemType, float>(RequiredComponents);
                    foreach (var RequiredComponent in RequiredComponents)
                    {
                        float pulledAmount = MyKernel.Inventory.TryTransferTo(ToolCargo, RequiredComponent.Key, RequiredComponent.Value, InventoryOwners);
                        _RqComponents[RequiredComponent.Key] -= pulledAmount;
                    }
                    RequiredComponents = _RqComponents;
                    //MyKernel.SessionBase.Log.DebugLog.WriteToLog($"WeldAndPlaceBlocks", $"Pulled missing components");
                }

                MyKernel.ResponderModule.UpdateMissing(RequiredComponents);

                yield return(true);

                int weldedBlocks = 0;
                List <IMySlimBlock> UnweldedBlocks = new List <IMySlimBlock>();
                foreach (IMySlimBlock Block in RealBlocks)
                {
                    if (Block.CanContinueBuild(ToolCargo) || Block.HasDeformation)
                    {
                        if (MyKernel.Session.Settings.AllowAsyncWelding)
                        {
                            if (CanWeldInAsyncMode(Block))
                            {
                                MyAPIGateway.Parallel.StartBackground(() => Weld(Block, SpeedRatio, BoneFixSpeed));
                            }
                            else
                            {
                                Weld(Block, SpeedRatio, BoneFixSpeed);
                            }
                        }
                        else
                        {
                            Weld(Block, SpeedRatio, BoneFixSpeed);
                        }
                        weldedBlocks++;
                        if (!MyKernel.Session.Settings.AllowAsyncWelding && weldedBlocks != RealBlocks.Count - 1)
                        {
                            yield return(true);
                        }
                    }
                    else
                    {
                        UnweldedBlocks.Add(Block);
                    }
                }

                //MyKernel.SessionBase.Log.DebugLog.WriteToLog($"WeldAndPlaceBlocks", $"Welded real blocks");

                if (weldedBlocks > 0)
                {
                    yield return(true);
                }

                int placedBlocks = 0;
                List <IMySlimBlock> NonplacedBlocksByLimit     = new List <IMySlimBlock>();
                List <IMySlimBlock> NonplacedBlocksByResources = new List <IMySlimBlock>();
                List <IMySlimBlock> PlaceableProjectedBlocks   = new List <IMySlimBlock>();

                foreach (IMySlimBlock Block in ProjectedBlocks)
                {
                    MyCubeBlockDefinition blockDef = Block.BlockDefinition as MyCubeBlockDefinition;
                    if (MyKernel.Tool.IsWithinWorldLimits(Projector, blockDef.BlockPairName, blockDef.PCU))
                    {
                        var FirstItem = blockDef.Components[0].Definition.Id;
                        if (ToolCargo.GetItemAmount(FirstItem) >= 1)
                        {
                            PlaceableProjectedBlocks.Add(Block);
                        }
                        else
                        {
                            NonplacedBlocksByResources.Add(Block);
                        }
                    }
                    else
                    {
                        NonplacedBlocksByLimit.Add(Block);
                    }
                }

                foreach (IMySlimBlock Block in PlaceableProjectedBlocks)
                {
                    var FirstItem = ((MyCubeBlockDefinition)Block.BlockDefinition).Components[0].Definition.Id;
                    Projector.Build(Block, MyKernel.Tool.OwnerId, MyKernel.Tool.EntityId, false);
                    ToolCargo.RemoveItemsOfType(1, FirstItem);
                    placedBlocks++;
                    if (placedBlocks != ProjectedBlocks.Count - 1)
                    {
                        yield return(true);
                    }
                }

                if (UnweldedBlocks.Count > 0)
                {
                    StringBuilder UnweldedReport = new StringBuilder();
                    UnweldedReport.AppendLine($"Failed to weld {UnweldedBlocks.Count} blocks:");
                    List <IGrouping <MyObjectBuilderType, IMySlimBlock> > unweldedByType = UnweldedBlocks.GroupBy(x => x.BlockDefinition.Id.TypeId).ToList();
                    foreach (IGrouping <MyObjectBuilderType, IMySlimBlock> grouping in unweldedByType)
                    {
                        UnweldedReport.AppendLine($"{grouping.Key.ToString().Replace("MyObjectBuilder_", "")} ({grouping.Count()})");
                    }

                    if (NonplacedBlocksByLimit.Count > 0 || NonplacedBlocksByResources.Count > 0)
                    {
                        UnweldedReport.AppendLine();
                    }

                    MyKernel.ResponderModule.UpdateStatusReport(UnweldedReport, append: true);
                }

                if (NonplacedBlocksByLimit.Count > 0)
                {
                    StringBuilder NonplacedReport = new StringBuilder();
                    NonplacedReport.AppendLine($"Failed to place {UnweldedBlocks.Count} blocks,");
                    NonplacedReport.AppendLine($"reached the PCU/block limit:");
                    List <IGrouping <MyObjectBuilderType, IMySlimBlock> > unplacedByType = UnweldedBlocks.GroupBy(x => x.BlockDefinition.Id.TypeId).ToList();
                    foreach (IGrouping <MyObjectBuilderType, IMySlimBlock> grouping in unplacedByType)
                    {
                        NonplacedReport.AppendLine($"{grouping.Key.ToString().Replace("MyObjectBuilder_", "")} ({grouping.Count()})");
                    }

                    MyKernel.ResponderModule.UpdateStatusReport(NonplacedReport, append: true);
                }

                if (NonplacedBlocksByResources.Count > 0)
                {
                    StringBuilder NonplacedReport = new StringBuilder();
                    NonplacedReport.AppendLine($"Failed to place {UnweldedBlocks.Count} blocks,");
                    NonplacedReport.AppendLine($"out of resources:");
                    List <IGrouping <MyObjectBuilderType, IMySlimBlock> > unplacedByType = UnweldedBlocks.GroupBy(x => x.BlockDefinition.Id.TypeId).ToList();
                    foreach (IGrouping <MyObjectBuilderType, IMySlimBlock> grouping in unplacedByType)
                    {
                        NonplacedReport.AppendLine($"{grouping.Key.ToString().Replace("MyObjectBuilder_", "")} ({grouping.Count()})");
                    }

                    MyKernel.ResponderModule.UpdateStatusReport(NonplacedReport, append: true);
                }
                //MyKernel.SessionBase.Log.DebugLog.WriteToLog($"WeldAndPlaceBlocks", $"Placed projected blocks");
            }
            else if (MyAPIGateway.Session.CreativeMode)
            {
                foreach (IMySlimBlock Block in RealBlocks)
                {
                    if (MyKernel.Session.Settings.AllowAsyncWelding)
                    {
                        if (CanWeldInAsyncMode(Block))
                        {
                            MyAPIGateway.Parallel.StartBackground(() => Weld(Block, SpeedRatio, BoneFixSpeed));
                        }
                        else
                        {
                            Weld(Block, SpeedRatio, BoneFixSpeed);
                        }
                    }
                    else
                    {
                        Weld(Block, SpeedRatio, BoneFixSpeed);
                    }
                }

                foreach (IMySlimBlock Block in ProjectedBlocks)
                {
                    Projector.Build(Block, MyKernel.Tool.OwnerId, MyKernel.Tool.EntityId, false);
                }
            }

            //MyKernel.SessionBase.Log.DebugLog.WriteToLog($"WeldAndPlaceBlocks", $"Exit Point");
            yield return(false);
        }
示例#34
0
 public static long SlimId(this IMySlimBlock block)
 {
     return(block.CubeGrid.EntityId.GetHashCode() + block.Position.GetHashCode());
 }
        void Grind(IMySlimBlock Block, float SpeedRatio, bool Raze = true)
        {
            if (Block == null)
            {
                return;
            }
            try
            {
                Stopwatch watch = Stopwatch.StartNew();
                Block.DecreaseMountLevel(SpeedRatio, ToolCargo);
                watch.Stop();
                //WriteToLog($"GrindBlocks[{MyKernel.Block.CustomName}]", $"Decreasing mount level took {Math.Round(watch.Elapsed.TotalMilliseconds, 3)}ms", EemRdx.SessionModules.LoggingLevelEnum.ProfilingLog);
                watch.Restart();
                Block.MoveItemsFromConstructionStockpile(ToolCargo);
                watch.Stop();
                //WriteToLog($"GrindBlocks[{MyKernel.Block.CustomName}]", $"Moving items took {Math.Round(watch.Elapsed.TotalMilliseconds, 3)}ms", EemRdx.SessionModules.LoggingLevelEnum.ProfilingLog);
                watch.Restart();
                // This is necessary for compatibility with EEM and other mods which react to damage to their grids
                Block.DoDamage(0, MyStringHash.GetOrCompute("Grind"), true, null, MyKernel.Block.EntityId);
                watch.Stop();
                //WriteToLog($"GrindBlocks[{MyKernel.Block.CustomName}]", $"Doing damage took {Math.Round(watch.Elapsed.TotalMilliseconds, 3)}ms", EemRdx.SessionModules.LoggingLevelEnum.ProfilingLog);
                watch.Restart();

                if (Block.FatBlock?.IsFunctional == false && Block.FatBlock?.HasInventory == true)
                {
                    foreach (IMyInventory Inventory in Block.FatBlock.GetInventories())
                    {
                        if (Inventory.CurrentVolume == VRage.MyFixedPoint.Zero)
                        {
                            continue;
                        }
                        List <MyInventoryItem> Items = new List <MyInventoryItem>();
                        Inventory.GetItems(Items);

                        foreach (MyInventoryItem Item in Items)
                        {
                            VRage.MyFixedPoint Amount = (VRage.MyFixedPoint)Math.Min((float)(Inventory as Sandbox.Game.MyInventory).ComputeAmountThatFits(Item.Type), (float)Item.Amount);
                            if ((float)Amount > 0)
                            {
                                ToolCargo.TransferItemFrom(Inventory, (int)Item.ItemId, null, null, Amount, false);
                            }
                        }
                    }
                    watch.Stop();
                    //WriteToLog($"GrindBlocks[{MyKernel.Block.CustomName}]", $"Block has an inventory; cleaning took {Math.Round(watch.Elapsed.TotalMilliseconds, 3)}ms", EemRdx.SessionModules.LoggingLevelEnum.ProfilingLog);
                    watch.Reset();
                }

                if (Raze && Block.IsFullyDismounted)
                {
                    watch.Restart();
                    Block.CubeGrid.RazeBlock(Block.Position);
                    watch.Stop();
                    //WriteToLog($"GrindBlocks[{MyKernel.Block.CustomName}]", $"Razing the block took {Math.Round(watch.Elapsed.TotalMilliseconds, 3)}ms", EemRdx.SessionModules.LoggingLevelEnum.ProfilingLog);
                }
            }
            catch (Exception Scrap)
            {
                LogError($"GrindBlocks[{MyKernel.Block.CustomName}]", $"Grinding of the block {Extensions.GeneralExtensions.GetTypeName(Block)} failed", Scrap);
            }
        }
示例#36
0
 public static bool Closed(this IMySlimBlock block)
 {
     return(block.CubeGrid?.GetCubeBlock(block.Position) == null);
 }
示例#37
0
        private bool helpsClassifyUnclassified(IMySlimBlock block)
        {
            if (m_EffectiveClass != DEFAULT_CLASS) {
                return false;
            }

            if (m_ReservedClass == DEFAULT_CLASS) {
                return HullClassifier.isClassifierBlock(block);
            }
            else {
                IMyReactor reactor = block.FatBlock as IMyReactor;
                return (reactor != null);
            }
        }
示例#38
0
 public static float BuildPercent(this IMySlimBlock block)
 {
     return(block.Integrity / block.MaxIntegrity);
 }
示例#39
0
        /// <summary>
        /// Increments the BlockType counts for a given new block
        /// Returns the violated limits if any
        /// </summary>
        private List<BlockType> updateBlockTypeCountsWith(IMySlimBlock block)
        {
            log("", "updateBlockTypeCountsWith");
            List<BlockType> violated_types = new List<BlockType>();

            BlockType[] types = s_Settings.BlockTypes;
            for (int typeID = 0; typeID < types.Length; typeID++) {
                BlockType type = types[typeID];

                if (type.appliesToBlock(block)) {
                    //log("incrementing type count " + m_BlockTypeCounts[typeID], "updateBlockCountsWith");
                    m_BlockTypeCounts[typeID] = m_BlockTypeCounts[typeID] + 1;
                    int count = m_BlockTypeCounts[typeID];
                    int limit = m_EffectiveRules.BlockTypeLimits[typeID];
                    log(type.DisplayName + " count now: " + count, "updateBlockCountsWith");

                    if (count > limit && limit >= 0)
                        violated_types.Add(type);
                }
            }

            return violated_types;
        }
        VRageMath.Vector3D?IMyCubeGrid.GetLineIntersectionExactAll(ref VRageMath.LineD line, out double distance, out IMySlimBlock intersectedBlock)
        {
            MySlimBlock block;
            var         retVal = GetLineIntersectionExactAll(ref line, out distance, out block);

            intersectedBlock = block;
            return(retVal);
        }
示例#41
0
        /// <summary>
        /// Removes the classifier and reserved class if block is a Classifier
        /// </summary>
        private void updateClassificationWithout(IMySlimBlock block)
        {
            // classifier?
            if (!HullClassifier.isClassifierBlock(block))
                return;

            log("removing classifier", "updateClassificationWithout");
            removeClassifier(block.FatBlock.EntityId);
        }
示例#42
0
        /// <summary>
        /// Returns True if tool has painted.
        /// </summary>
        void HandleTool(bool trigger)
        {
            AimedPlayer            = null;
            AimedBlock             = null;
            AimedState             = SelectionState.Invalid;
            SymmetryInputAvailable = false;

            IMyCharacter character = MyAPIGateway.Session.Player.Character;
            IMyCubeGrid  targetGrid;
            IMySlimBlock targetBlock;
            IMyPlayer    targetPlayer;
            Vector3D     aimPoint;

            GetTarget(character, out targetGrid, out targetBlock, out targetPlayer, out aimPoint);

            if (targetPlayer != null && Main.Palette.ColorPickMode)
            {
                HandleTool_ColorPickFromPlayer(trigger, targetPlayer);
                return;
            }

            if (targetBlock == null)
            {
                if (Main.Palette.ColorPickMode)
                {
                    Main.Notifications.Show(0, "Aim at a block or player and click to pick color.", MyFontEnum.Blue);
                }
                else if (!Utils.SafeZoneCanPaint(aimPoint, MyAPIGateway.Multiplayer.MyId))
                {
                    // sound likely already played by the shoot restriction in the safe zone
                    //HUDSounds.PlayUnable();

                    if (trigger)
                    {
                        Main.Notifications.Show(0, "Can't paint in this safe zone.", MyFontEnum.Red);
                    }
                }
                else if (Main.Palette.ReplaceMode)
                {
                    Main.Notifications.Show(0, $"Aim at a block to replace its color on {(Main.Palette.ReplaceShipWide ? "the entire ship" : "this grid")}.", MyFontEnum.Blue);
                }
                else if (trigger)
                {
                    //Main.HUDSounds.PlayUnable();

                    if (!Main.IgnoreAmmoConsumption && LocalTool.Ammo == 0)
                    {
                        Main.Notifications.Show(0, "No ammo and no target.", MyFontEnum.Red);
                    }
                    else
                    {
                        Main.Notifications.Show(0, "Aim at a block to paint it.", MyFontEnum.Red);
                    }
                }

                return;
            }

            Main.SelectionGUI.UpdateSymmetryStatus(targetBlock);

            PaintMaterial paintMaterial = Main.Palette.GetLocalPaintMaterial();
            BlockMaterial blockMaterial = new BlockMaterial(targetBlock);

            AimedBlock = targetBlock;

            if (Main.Palette.ColorPickMode)
            {
                HandleTool_ColorPickModeFromBlock(paintMaterial, blockMaterial, trigger);
                return;
            }

            if (!ValidateMainBlock(targetBlock, paintMaterial, blockMaterial, trigger))
            {
                return;
            }

            string blockName = Utils.GetBlockName(targetBlock);

            if (!Main.IgnoreAmmoConsumption && LocalTool.Ammo == 0)
            {
                if (trigger)
                {
                    //Main.HUDSounds.PlayUnable();
                    Main.Notifications.Show(1, "No ammo.", MyFontEnum.Red);
                }

                Main.SelectionGUI.SetGUIStatus(0, "No ammo!", "red");
                return;
            }

            AimedState = SelectionState.Valid;

            if (trigger)
            {
                float         paintSpeed    = (1.0f / Utils.GetBlockSurface(targetBlock));
                PaintMaterial finalMaterial = HandleTool_PaintProcess(paintMaterial, blockMaterial, paintSpeed, blockName);

                if (Main.Palette.ReplaceMode && Main.ReplaceColorAccess)
                {
                    Main.Painting.ToolReplacePaint(targetGrid, blockMaterial, finalMaterial, Main.Palette.ReplaceShipWide);
                }
                else
                {
                    bool useMirroring = (Main.SymmetryAccess && MyAPIGateway.CubeBuilder.UseSymmetry);
                    Main.Painting.ToolPaintBlock(targetGrid, targetBlock.Position, finalMaterial, useMirroring);
                }
            }
        }
示例#43
0
        private void updateProjectorsWith(IMySlimBlock block)
        {
            log("", "updateProjectorsWith");

            InGame.IMyProjector projector = block.FatBlock as InGame.IMyProjector;
            if (projector != null) {
                log("Added a projector", "blockAdded");
                m_Projectors.Add(projector.EntityId, projector);
            }
        }
示例#44
0
        void GetTarget(IMyCharacter character, out IMyCubeGrid targetGrid, out IMySlimBlock targetBlock, out IMyPlayer targetPlayer, out Vector3D aimPoint)
        {
            targetGrid   = null;
            targetBlock  = null;
            targetPlayer = null;

            bool     aiming  = Utils.IsAimingDownSights(character);
            MatrixD  head    = character.GetHeadMatrix(false, true);
            Vector3D rayDir  = head.Forward;
            Vector3D rayFrom = head.Translation;

            if (aiming)
            {
                rayFrom += rayDir * PAINT_AIM_START_OFFSET;
            }

            Vector3D rayTo = head.Translation + rayDir * PAINT_DISTANCE;

            aimPoint = rayTo;

            targetGrid = MyAPIGateway.CubeBuilder.FindClosestGrid();

            if (targetGrid == null || targetGrid.Physics == null || !targetGrid.Physics.Enabled)
            {
                targetGrid = null;
                return;
            }

            // older selection behavior when aiming down sights
            if (aiming)
            {
                Vector3I?blockPos = targetGrid.RayCastBlocks(rayFrom, rayTo);

                if (blockPos.HasValue)
                {
                    targetBlock = targetGrid.GetCubeBlock(blockPos.Value);
                }

                return;
            }

            // HACK copied and converted from MyDrillSensorRayCast.ReadEntitiesInRange() + MyCasterComponent.OnWorldPosChanged()
            // last cloned in SE v201
            #region Welder-like block selection
            hits.Clear();
            detections.Clear();
            rayOverlapResults.Clear();

            MyAPIGateway.Physics.CastRay(rayFrom, rayTo, hits, 24);

            foreach (IHitInfo hit in hits)
            {
                IMyEntity parent = hit.HitEntity?.GetTopMostParent();
                if (parent == null || parent.Physics == null || !parent.Physics.Enabled)
                {
                    continue;
                }

                Vector3D    hitPos = hit.Position;
                IMyCubeGrid grid   = parent as IMyCubeGrid;
                if (grid != null)
                {
                    // just how it's set in game code /shrug
                    hitPos += hit.Normal * -0.005f;
                }

                DetectionInfo detected;
                if (detections.TryGetValue(parent.EntityId, out detected))
                {
                    double dist1 = Vector3D.DistanceSquared(rayFrom, detected.DetectionPoint);
                    double dist2 = Vector3D.DistanceSquared(rayFrom, hitPos);
                    if (dist1 > dist2)
                    {
                        detections[parent.EntityId] = new DetectionInfo(parent, hitPos);
                    }
                }
                else
                {
                    detections[parent.EntityId] = new DetectionInfo(parent, hitPos);
                }
            }

            hits.Clear();

            LineD line = new LineD(rayFrom, rayTo);
            MyGamePruningStructure.GetAllEntitiesInRay(ref line, rayOverlapResults);

            foreach (MyLineSegmentOverlapResult <MyEntity> result in rayOverlapResults)
            {
                if (result.Element == null)
                {
                    continue;
                }

                IMyCubeBlock block = result.Element as IMyCubeBlock;
                if (block == null)
                {
                    continue;
                }

                MyCubeBlockDefinition def = (MyCubeBlockDefinition)block.SlimBlock.BlockDefinition;
                if (def.HasPhysics)
                {
                    continue; // this section is only for things that are not caught by the raycast
                }
                MyEntity parent = result.Element.GetTopMostParent();
                if (parent.Physics == null || !parent.Physics.Enabled)
                {
                    continue;
                }

                MatrixD invMatrix = block.PositionComp.WorldMatrixNormalizedInv;
                Vector3 localFrom = Vector3D.Transform(rayFrom, ref invMatrix);
                Vector3 localTo   = Vector3D.Transform(rayTo, ref invMatrix);

                float?intersectDistance = new Ray(localFrom, Vector3.Normalize(localTo - localFrom)).Intersects(block.PositionComp.LocalAABB) + 0.01f;
                if (intersectDistance.HasValue && intersectDistance <= PAINT_DISTANCE)
                {
                    Vector3D      hitPos = rayFrom + rayDir * intersectDistance.Value;
                    DetectionInfo detected;
                    if (detections.TryGetValue(parent.EntityId, out detected))
                    {
                        double dist1 = Vector3D.DistanceSquared(rayFrom, detected.DetectionPoint);
                        double dist2 = Vector3D.DistanceSquared(rayFrom, hitPos);
                        if (dist1 > dist2)
                        {
                            detections[parent.EntityId] = new DetectionInfo(parent, hitPos);
                        }
                    }
                    else
                    {
                        detections[parent.EntityId] = new DetectionInfo(parent, hitPos);
                    }
                }
            }

            rayOverlapResults.Clear();

            if (detections.Count == 0)
            {
                return;
            }

            double        closetDist = double.MaxValue;
            DetectionInfo closestObj = new DetectionInfo(null, Vector3D.Zero);

            foreach (DetectionInfo detected in detections.Values)
            {
                double dist = Vector3D.DistanceSquared(detected.DetectionPoint, rayFrom);
                if (dist < closetDist)
                {
                    closestObj = detected;
                    closetDist = dist;
                }
            }

            detections.Clear();

            targetGrid = closestObj.Entity as IMyCubeGrid;
            if (targetGrid == null)
            {
                return;
            }

            Vector3D localPos = Vector3D.Transform(closestObj.DetectionPoint, targetGrid.WorldMatrixNormalizedInv);
            Vector3I cube;
            targetGrid.FixTargetCube(out cube, localPos / targetGrid.GridSize);
            targetBlock = targetGrid.GetCubeBlock(cube);
            #endregion Welder-like block selection
        }
示例#45
0
        /// <summary>
        /// Called when a block is added to the grid.
        /// Decides whether or not to allow the block to be placed.
        /// Increments counts, checks for classification, and sets
        /// a flag to refresh cleanup status
        /// </summary>
        /// <param name="added">block that was added to the grid</param>
        private void blockAdded(IMySlimBlock added)
        {
            //log(added.ToString() + " added to grid " + m_Grid.DisplayName, "blockAdded");

            try {
                // Counts and Caches must be updated whether we're removing the block or not,
                // because blockRemoved has no way of knowing if we touched counts for it
                log("Update block lists and counts", "blockAdded");
                VIOLATION_TYPE classifierViolation = updateClassifiersWith(added);
                VIOLATION_TYPE totalBlocksViolation = incrementBlockCount();
                List<BlockType> violatedTypes = updateBlockTypeCountsWith(added);
                updateProjectorsWith(added);

                // we skip violation checks:
                // for blocks that aren't actually placed by a user, i.e. during World Load or a Merge
                log("checking enforcement skip conditions", "blockAdded");

                if (m_Merging || !m_BeyondFirst100) {
                    log("Currently merging or initing, don't do placement enforcment",
                        "blockAdded");
                    goto Allowed;
                }
                // if we're projecting
                if (Projecting) {
                    log("We are projecting, don't do placement enforcment",
                        "blockAdded");
                    goto Allowed;
                }

                // If there are violations, disallow placement
                // Everything will eventually be cleaned up over time, but we do this
                // enforcment on placement to help keep people in line
                log("check placement violations", "blockAdded");

                // classifier violations come first
                if (classifierViolation != VIOLATION_TYPE.NONE) {

                    // people find it really annoying that they have to have an
                    // owned block before placing a classifier.
                    if (classifierViolation == VIOLATION_TYPE.TOO_MANY_OF_CLASS &&
                        isUnowned()) {
                        log("Too many of class but unowned, don't do placement enforcment",
                            "checkClassAllowed");
                        goto Allowed;
                    }

                    log("classifierViolation enforce", "blockAdded");
                    notifyPlacementViolation(classifierViolation);
                    goto Denied;
                }

                // then total blocks
                else if (totalBlocksViolation != VIOLATION_TYPE.NONE) {

                    // people also find it annoying to have to delete all the blocks
                    // on a ship that just became unclassified before they can build
                    // another classifier or reactor to bring it in line
                    if (helpsClassifyUnclassified(added)) {
                        log("provides needed classification, don't do placement enforcment",
                            "blockAdded");
                        goto Allowed;
                    }

                    log("totalBlocksViolation enforce", "blockAdded");
                    notifyPlacementViolation(totalBlocksViolation);
                    goto Denied;
                }
                else if (violatedTypes.Count > 0) {
                    notifyPlacementViolation(VIOLATION_TYPE.BLOCK_TYPE);
                    log("block type violation enforced", "blockAdded");
                    goto Denied;
                }
            }
            catch (Exception e) {
                log("Error: " + e, "blockAdded");
            }

            Allowed:
            log(added.ToString() + " added to grid '" + m_Grid.DisplayName +
                "'. Total Count now: " + m_BlockCount, "blockAdded");
            m_CheckOwnerNextUpdate = true;
            m_CheckCleanupNextUpdate = true;
            return;

            Denied:
            log(added.ToString() + " denied for grid '" + m_Grid.DisplayName +
                "'. Total Count now: " + m_BlockCount, "blockAdded");

            removeBlock(added);
        }
示例#46
0
        bool ValidateMainBlock(IMySlimBlock block, PaintMaterial paintMaterial, BlockMaterial blockMaterial, bool trigger)
        {
            if (!paintMaterial.ColorMask.HasValue && !paintMaterial.Skin.HasValue)
            {
                string assigned = InputHandler.GetFriendlyStringForControl(MyAPIGateway.Input.GetGameControl(MyControlsSpace.CUBE_COLOR_CHANGE));

                Main.Notifications.Show(0, "No paint or skin enabled.", MyFontEnum.Red);
                Main.Notifications.Show(1, $"Press [{assigned}] to toggle color or combined with [Shift] to toggle skin.", MyFontEnum.Debug);

                Main.SelectionGUI.SetGUIStatus(0, "No paint or skin enabled.", "red");
                Main.SelectionGUI.SetGUIStatus(1, null);
                return(false);
            }

            if (!Utils.AllowedToPaintGrid(block.CubeGrid, MyAPIGateway.Session.Player.IdentityId))
            {
                if (trigger)
                {
                    Main.HUDSounds.PlayUnable();
                    Main.Notifications.Show(0, "Can't paint enemy ships.", MyFontEnum.Red, 2000);
                }

                Main.SelectionGUI.SetGUIStatus(0, "Not allied ship.", "red");
                Main.SelectionGUI.SetGUIStatus(1, null);
                return(false);
            }

            if (!Utils.SafeZoneCanPaint(block, MyAPIGateway.Multiplayer.MyId))
            {
                if (trigger)
                {
                    Main.HUDSounds.PlayUnable();
                    Main.Notifications.Show(0, "Can't paint in this safe zone.", MyFontEnum.Red, 2000);
                }

                Main.SelectionGUI.SetGUIStatus(0, "Protected by safe zone", "red");
                Main.SelectionGUI.SetGUIStatus(1, null);
                return(false);
            }

            bool materialEquals = paintMaterial.PaintEquals(blockMaterial);

            if (Main.Palette.ReplaceMode)
            {
                AimedState = (materialEquals ? SelectionState.Invalid : SelectionState.Valid);

                string assigned = InputHandler.GetFriendlyStringForControl(MyAPIGateway.Input.GetGameControl(MyControlsSpace.USE_SYMMETRY));

                if (AimedState == SelectionState.Invalid)
                {
                    Main.SelectionGUI.SetGUIStatus(0, "Already this material.", "red");
                }
                else
                {
                    Main.SelectionGUI.SetGUIStatus(0, "Click to replace material.", "lime");
                }

                Main.SelectionGUI.SetGUIStatus(1, $"[{assigned}] {(Main.Palette.ReplaceShipWide ? "<color=yellow>" : "")}Replace mode: {(Main.Palette.ReplaceShipWide ? "Ship-wide" : "Grid")}");

                return(AimedState == SelectionState.Valid);
            }

            if (!Main.InstantPaintAccess)
            {
                MyCubeBlockDefinition def = (MyCubeBlockDefinition)block.BlockDefinition;
                bool built = (block.BuildLevelRatio >= def.CriticalIntegrityRatio);

                if (!built || block.CurrentDamage > (block.MaxIntegrity / 10.0f))
                {
                    AimedState = SelectionState.Invalid;

                    if (trigger)
                    {
                        Main.HUDSounds.PlayUnable();
                        Main.Notifications.Show(0, "Unfinished blocks can't be painted!", MyFontEnum.Red);
                    }

                    Main.SelectionGUI.SetGUIStatus(0, (!built ? "Block not built" : "Block damaged"), "red");
                    Main.SelectionGUI.SetGUIStatus(1, null);
                    return(false);
                }
            }

            MyCubeGrid grid              = (MyCubeGrid)block.CubeGrid;
            bool       symmetry          = Main.SymmetryAccess && MyCubeBuilder.Static.UseSymmetry && (grid.XSymmetryPlane.HasValue || grid.YSymmetryPlane.HasValue || grid.ZSymmetryPlane.HasValue);
            bool       symmetrySameColor = true;

            if (materialEquals)
            {
                AimedState = SelectionState.Invalid;

                if (symmetry)
                {
                    Vector3I?mirrorX  = null;
                    Vector3I?mirrorY  = null;
                    Vector3I?mirrorZ  = null;
                    Vector3I?mirrorYZ = null;

                    // NOTE: do not optimize, all methods must be called
                    if (!MirrorCheckSameColor(grid, 0, block.Position, paintMaterial, out mirrorX))
                    {
                        symmetrySameColor = false;
                    }

                    if (!MirrorCheckSameColor(grid, 1, block.Position, paintMaterial, out mirrorY))
                    {
                        symmetrySameColor = false;
                    }

                    if (!MirrorCheckSameColor(grid, 2, block.Position, paintMaterial, out mirrorZ))
                    {
                        symmetrySameColor = false;
                    }

                    if (mirrorX.HasValue && grid.YSymmetryPlane.HasValue) // XY
                    {
                        if (!MirrorCheckSameColor(grid, 1, mirrorX.Value, paintMaterial, out mirrorX))
                        {
                            symmetrySameColor = false;
                        }
                    }

                    if (mirrorX.HasValue && grid.ZSymmetryPlane.HasValue) // XZ
                    {
                        if (!MirrorCheckSameColor(grid, 2, mirrorX.Value, paintMaterial, out mirrorX))
                        {
                            symmetrySameColor = false;
                        }
                    }

                    if (mirrorY.HasValue && grid.ZSymmetryPlane.HasValue) // YZ
                    {
                        if (!MirrorCheckSameColor(grid, 2, mirrorY.Value, paintMaterial, out mirrorYZ))
                        {
                            symmetrySameColor = false;
                        }
                    }

                    if (grid.XSymmetryPlane.HasValue && mirrorYZ.HasValue) // XYZ
                    {
                        if (!MirrorCheckSameColor(grid, 0, mirrorYZ.Value, paintMaterial, out mirrorX))
                        {
                            symmetrySameColor = false;
                        }
                    }

                    if (!symmetrySameColor)
                    {
                        AimedState = SelectionState.InvalidButMirrorValid;
                    }
                }

                if (!symmetry || symmetrySameColor)
                {
                    AimedState = SelectionState.Invalid;

                    if (symmetry)
                    {
                        Main.SelectionGUI.SetGUIStatus(0, "All materials match.", "lime");
                    }
                    else
                    {
                        Main.SelectionGUI.SetGUIStatus(0, "Materials match.", "lime");
                    }

                    Main.SelectionGUI.SetGUIStatus(1, Main.SelectionGUI.SymmetryStatusText);
                    return(false);
                }
            }

            if (!trigger)
            {
                if (symmetry && !symmetrySameColor)
                {
                    Main.SelectionGUI.SetGUIStatus(0, "Click to update symmetry paint.");
                }
                else if (Main.InstantPaintAccess)
                {
                    Main.SelectionGUI.SetGUIStatus(0, "Click to paint.");
                }
                else
                {
                    Main.SelectionGUI.SetGUIStatus(0, "Hold click to paint.");
                }

                Main.SelectionGUI.SetGUIStatus(1, Main.SelectionGUI.SymmetryStatusText);
            }

            return(true);
        }
示例#47
0
        private void MoveToTarget()
        {
            m_logger.debugLog(m_stage != Stage.Approach && m_stage != Stage.Weld, "moving to target in wrong stage", Logger.severity.FATAL);

            if ((Globals.UpdateCount - m_lastWeld) > 1200ul)
            {
                m_logger.debugLog("failed to repair block");
                EnableWelders(false);
                m_stage = Stage.Retreat;
                return;
            }

            if (m_weldProjection)
            {
                // check for slim being placed
                IMySlimBlock placed = m_realGrid.GetCubeBlock(m_targetCell);
                if (placed != null)
                {
                    m_logger.debugLog("projected target placed", Logger.severity.DEBUG);
                    m_weldProjection = false;
                    m_targetSlim = placed;
                }
            }

            // check for weld

            float damage = m_targetSlim.Damage();
            foreach (Vector3I cell in m_neighbours)
            {
                IMySlimBlock slim = m_realGrid.GetCubeBlock(cell);
                if (slim != null)
                    damage += slim.Damage();
            }

            if (damage < m_damage)
                m_lastWeld = Globals.UpdateCount;

            m_damage = damage;

            if (!m_weldProjection && m_targetSlim.Damage() == 0f && (Globals.UpdateCount - m_lastWeld) > 120ul)
            {
                m_logger.debugLog("target block repaired: " + m_targetSlim.getBestName(), Logger.severity.DEBUG);
                EnableWelders(false);
                m_stage = Stage.Retreat;
                return;
            }
            else
            {
                float offset = m_stage == Stage.Weld ? m_offset : m_offset + OffsetAdd;
                Vector3D welderFromTarget = m_controlBlock.CubeBlock.GetPosition() - m_targetWorld;
                welderFromTarget.Normalize();
                m_mover.CalcMove(m_welder, m_targetWorld + welderFromTarget * offset, m_realGrid.Physics.LinearVelocity, true);
            }
        }
示例#48
0
        private bool AddPotentialBlock(IMySlimBlock block, bool remote = false, NaniteAreaBeacon beacon = null)
        {
            if (PotentialTargetList.Contains(block))
            {
                return(false);
            }

            if (EntityHelper.GetDistanceBetweenBlockAndSlimblock((IMyCubeBlock)m_constructionBlock.ConstructionBlock, block) > m_maxDistance)
            {
                return(false);
            }

            if (!remote && block.FatBlock != null && block.FatBlock is IMyTerminalBlock && block.FatBlock.OwnerId != 0)
            {
                IMyTerminalBlock terminal = (IMyTerminalBlock)block.FatBlock;
                MyRelationsBetweenPlayerAndBlock relation = terminal.GetUserRelationToOwner(m_constructionBlock.ConstructionBlock.OwnerId);

                if (relation == MyRelationsBetweenPlayerAndBlock.Neutral ||
                    relation == MyRelationsBetweenPlayerAndBlock.Enemies)
                {
                    return(false);
                }
            }
            else if (remote)
            {
                //if (block.CubeGrid.BigOwners.Count < 1)
                //    return false;

                foreach (var item in block.CubeGrid.BigOwners)
                {
                    MyRelationsBetweenPlayerAndBlock relation = m_constructionBlock.ConstructionBlock.GetUserRelationToOwner(item);

                    if (relation == MyRelationsBetweenPlayerAndBlock.Neutral ||
                        relation == MyRelationsBetweenPlayerAndBlock.Enemies)
                    {
                        return(false);
                    }
                }
            }

            if (!block.IsFullIntegrity || block.HasDeformation)
            {
                using (Lock.AcquireExclusiveUsing())
                {
                    if (beacon != null)
                    {
                        if (!m_areaTargetBlocks.ContainsKey(block))
                        {
                            m_areaTargetBlocks.Add(block, beacon);
                        }
                        else
                        {
                            m_areaTargetBlocks[block] = beacon;
                        }
                    }

                    PotentialTargetList.Add(block);
                    return(true);
                }
            }

            return(false);
        }
示例#49
0
        /// <summary>
        /// if removed is a thruster, remove it from thrustersInDirection
        /// </summary>
        /// <remarks>
        /// if a working block is destroyed, block_IsWorkingChange() is called first
        /// </remarks>
        /// <param name="removed">block that was removed</param>
        private void grid_OnBlockRemoved(IMySlimBlock removed)
        {
            try
            {
                if (removed.FatBlock == null)
                    return;

                MyThrust asThrust = removed.FatBlock as MyThrust;
                if (asThrust == null)
                    return;

                using (lock_thrustersInDirection.AcquireExclusiveUsing())
                    thrustersInDirection[Base6Directions.GetFlippedDirection(asThrust.Orientation.Forward)].Remove(asThrust);
                myLogger.debugLog("removed thruster = " + removed.FatBlock.DefinitionDisplayNameText + "/" + asThrust.DisplayNameText, Logger.severity.DEBUG);
                m_primaryDirty = true;
                return;
            }
            catch (Exception e)
            { myLogger.alwaysLog("Exception: " + e, Logger.severity.ERROR); }
        }
示例#50
0
        internal void AddShieldHit(long attackerId, float amount, MyStringHash damageType, IMySlimBlock block, bool reset, Vector3D?hitPos = null)
        {
            lock (ShieldHit)
            {
                ShieldHit.Amount    += amount;
                ShieldHit.DamageType = damageType.String;

                if (block != null && !hitPos.HasValue && ShieldHit.HitPos == Vector3D.Zero)
                {
                    if (block.FatBlock != null)
                    {
                        ShieldHit.HitPos = block.FatBlock.PositionComp.WorldAABB.Center;
                    }
                    else
                    {
                        block.ComputeWorldCenter(out ShieldHit.HitPos);
                    }
                }
                else if (hitPos.HasValue)
                {
                    ShieldHit.HitPos = hitPos.Value;
                }

                if (attackerId != 0)
                {
                    ShieldHit.AttackerId = attackerId;
                }
                if (amount > 0)
                {
                    _lastSendDamageTick = _tick;
                }
                if (reset)
                {
                    ShieldHitReset(true);
                }
            }
        }
示例#51
0
        /// <summary>
        /// Colours a block according to its integrity.
        /// </summary>
        private static void ColourBlock(IMySlimBlock realBlock, IMyCubeGrid holoGrid)
        {
            Static.logger.debugLog(realBlock == null, "realBlock == null", Logger.severity.FATAL);

            float integrityRatio = (realBlock.BuildIntegrity - realBlock.CurrentDamage) / realBlock.MaxIntegrity;
            float criticalRatio = ((MyCubeBlockDefinition)realBlock.BlockDefinition).CriticalIntegrityRatio;

            float scaledRatio;
            Color blockColour;
            Static.logger.debugLog(integrityRatio != 1f, "integrityRatio: " + integrityRatio + ", criticalRatio: " + criticalRatio + ", fatblock: " + realBlock.FatBlock.getBestName() + ", functional: " + (realBlock.FatBlock != null && realBlock.FatBlock.IsFunctional));
            if (integrityRatio > criticalRatio && (realBlock.FatBlock == null || realBlock.FatBlock.IsFunctional))
            {
                scaledRatio = (integrityRatio - criticalRatio) / (1f - criticalRatio);
                blockColour = IntegrityFull * scaledRatio + IntegrityFunctional * (1f - scaledRatio);
            }
            else
            {
                scaledRatio = integrityRatio / criticalRatio;
                blockColour = IntegrityDamaged * scaledRatio + IntegrityZero * (1f - scaledRatio);
            }
            holoGrid.ColorBlocks(realBlock.Position, realBlock.Position, blockColour.ColorToHSVDX11());
        }
示例#52
0
        private void Actual_OnBlockRemoved(IMySlimBlock obj)
        {
            SeenHolo sh;
            if (!m_holoEntities.TryGetValue(obj.CubeGrid.EntityId, out sh))
            {
                m_logger.debugLog("failed lookup of grid: " + obj.CubeGrid.DisplayName, Logger.severity.ERROR);
                obj.CubeGrid.OnBlockAdded -= Actual_OnBlockAdded;
                obj.CubeGrid.OnBlockRemoved -= Actual_OnBlockRemoved;
                return;
            }

            Vector3I position = obj.Position;
            IMyCubeGrid holo = (IMyCubeGrid)sh.Holo;
            holo.RemoveBlock(holo.GetCubeBlock(position));
        }
示例#53
0
        private void Actual_OnBlockAdded(IMySlimBlock obj)
        {
            SeenHolo sh;
            if (!m_holoEntities.TryGetValue(obj.CubeGrid.EntityId, out sh))
            {
                m_logger.debugLog("failed lookup of grid: " + obj.CubeGrid.DisplayName, Logger.severity.ERROR);
                obj.CubeGrid.OnBlockAdded -= Actual_OnBlockAdded;
                obj.CubeGrid.OnBlockRemoved -= Actual_OnBlockRemoved;
                return;
            }

            IMyCubeGrid holo = (IMyCubeGrid)sh.Holo;
            MyObjectBuilder_CubeBlock objBuilder = obj.GetObjectBuilder();
            objBuilder.EntityId = 0L;
            holo.AddBlock(objBuilder, false);

            IMyCubeBlock cubeBlock = holo.GetCubeBlock(obj.Position).FatBlock;
            if (cubeBlock != null)
                SetupProjection(cubeBlock);
        }
示例#54
0
        /// <summary>
        /// if necessary, builds script for a block
        /// </summary>
        private void AddBlock(IMySlimBlock block)
        {
            IMyCubeBlock fatblock = block.FatBlock;
            if (fatblock != null)
            {
                if (!CubeBlocks.Add(fatblock.EntityId))
                    return;
                fatblock.OnClosing += alsoFatblock => {
                    if (CubeBlocks != null)
                        CubeBlocks.Remove(alsoFatblock.EntityId);
                };

                MyObjectBuilderType typeId = fatblock.BlockDefinition.TypeId;

                //myLogger.debugLog("block definition: " + fatblock.DefinitionDisplayNameText + ", typeId: " + typeId, "AddBlock()"); // used to find which builder is associated with a block

                if (AllBlockScriptConstructors.ContainsKey(typeId))
                    foreach (Action<IMyCubeBlock> constructor in BlockScriptConstructor(typeId))
                        try { constructor.Invoke(fatblock); }
                        catch (Exception ex)
                        {
                            myLogger.alwaysLog("Exception in " + typeId + " constructor: " + ex, Logger.severity.ERROR);
                            Logger.debugNotify("Exception in " + typeId + " constructor", 10000, Logger.severity.ERROR);
                        }

                if (EveryBlockScriptConstructors.Count > 0)
                    foreach (Action<IMyCubeBlock> constructor in EveryBlockScriptConstructors)
                        try { constructor.Invoke(fatblock); }
                        catch (Exception ex)
                        {
                            myLogger.alwaysLog("Exception in every block constructor: " + ex, Logger.severity.ERROR);
                            Logger.debugNotify("Exception in every block constructor", 10000, Logger.severity.ERROR);
                        }

                return;
            }
        }
示例#55
0
 private void OnBlockIntegrityChanged(IMySlimBlock block)
 {
     SeenHolo sh;
     if (!m_holoEntities.TryGetValue(block.CubeGrid.EntityId, out sh))
     {
         m_logger.debugLog("grid entity id lookup failed", Logger.severity.ERROR);
         ((MyCubeGrid)block.CubeGrid).OnBlockIntegrityChanged -= OnBlockIntegrityChanged;
         return;
     }
     IMyCubeGrid grid = (IMyCubeGrid)sh.Holo;
     if (sh.ColouredByIntegrity)
         ColourBlock(block, grid);
     UpdateBlockModel(block, grid);
 }
示例#56
0
        private void Handler(object target, ref MyDamageInformation info)
        {
            IMySlimBlock block = target as IMySlimBlock;

            if (block == null)
            {
                return;                // End: Only reduce damage to blocks
            }
            IMyEntity ent = MyAPIGateway.Entities.GetEntityById(info.AttackerId);

            if (ent == null)
            {
                return;              // End: Must be a player character
            }
            IMyHandheldGunObject <MyToolBase> tool = null;
            IMyHandheldGunObject <MyGunBase>  gun  = null;

            if (info.Type == MyDamageType.Grind)
            {
                tool = ent as IMyAngleGrinder;
            }
            else if (info.Type == MyDamageType.Drill)
            {
                tool = ent as IMyHandDrill;
            }
            else
            {
                gun = ent as IMyAutomaticRifleGun;
            }

            if (tool == null && gun == null)
            {
                return;                              // End: damage must be done by tool or hand weapon
            }
            bool isTool   = tool != null;
            long identity = (isTool) ? tool.OwnerIdentityId : gun.OwnerIdentityId;

            List <IMyPlayer> players = new List <IMyPlayer>();

            MyAPIGateway.Players.GetPlayers(players, p => p.IdentityId == identity);
            if (players.Count == 0 || // End: Player not found. this can happen if the character is an NPC
                block.CubeGrid.BigOwners.Count == 0)
            {
                return;                                       // End: Unowned structures take full damage
            }
            MyRelationsBetweenPlayerAndBlock relation = players[0].GetRelationTo(block.CubeGrid.BigOwners[0]);

            if (!(relation == MyRelationsBetweenPlayerAndBlock.Enemies ||
                  relation == MyRelationsBetweenPlayerAndBlock.Neutral))
            {
                return;                                                        // End: Friendly and unowned structures take full damage
            }
            if (block.FatBlock != null && block.FatBlock is IMyTerminalBlock)
            {
                if (block.FatBlock.OwnerId != 0)
                {
                    info.Amount = info.Amount * (1 + (1 - MyAPIGateway.Session.HackSpeedMultiplier)) * GetTerminalBlockHackSpeedAboveFunctional(isTool);
                }
                else
                {
                    info.Amount = info.Amount * GetTerminalBlockHackSpeedBelowFunctional(isTool);
                }
            }
            else
            {
                info.Amount = info.Amount * GetNonTerminalBlockHackSpeed(isTool);
            }
        }
示例#57
0
 private void Grid_OnBlockAdded(IMySlimBlock block)
 {
     AddRemoveActions.Enqueue(() => { AddBlock(block); });
 }
        private int GetMissingComponentCount(NaniteConstructionInventory inventoryManager, IMySlimBlock block)
        {
            Dictionary <string, int> missing = new Dictionary <string, int>();

            block.GetMissingComponents(missing);
            if (missing.Count == 0)
            {
                return(0);
            }

            Dictionary <string, int> available = new Dictionary <string, int>();

            inventoryManager.GetAvailableComponents(ref available);
            for (int r = missing.Count - 1; r >= 0; r--)
            {
                var item = missing.ElementAt(r);
                if (available.ContainsKey(item.Key))
                {
                    int amount = Math.Min(item.Value, available[item.Key]);
                    available[item.Key] -= amount;
                    missing[item.Key]   -= amount;
                }
            }

            return(missing.Sum(x => x.Value));
        }
示例#59
0
 public static void EnqueueRemoveBlock(IMySlimBlock block)
 {
     queueRemoveBlocks.Add(block);
 }
        private void ProcessConstructionItem(IMySlimBlock target)
        {
            if (Sync.IsServer)
            {
                if (!IsEnabled())
                {
                    Logging.Instance.WriteLine("CANCELLING Construction/Repair Target due to being disabled");
                    CancelTarget(target);
                    return;
                }

                if (!NaniteConstructionPower.HasRequiredPowerForCurrentTarget((IMyFunctionalBlock)m_constructionBlock.ConstructionBlock))
                {
                    Logging.Instance.WriteLine("CANCELLING Construction/Repair Target due to power shortage");
                    CancelTarget(target);
                    return;
                }

                if (m_constructionBlock.FactoryState != NaniteConstructionBlock.FactoryStates.Active)
                {
                    return;
                }

                if (!m_targetBlocks.ContainsKey(target))
                {
                    m_targetBlocks.Add(target, 0);
                }

                NaniteWelder welder = (NaniteWelder)m_constructionBlock.ToolManager.Tools.FirstOrDefault(x => x.TargetBlock == target && x is NaniteWelder);
                if (welder == null)
                {
                    double distance = EntityHelper.GetDistanceBetweenBlockAndSlimblock((IMyCubeBlock)m_constructionBlock.ConstructionBlock, target);
                    int    time     = (int)Math.Max(GetMinTravelTime() * 1000f, (distance / GetSpeed()) * 1000f);
                    welder = new NaniteWelder(m_constructionBlock, target, (int)(time / 2.5f), false);
                    m_constructionBlock.ToolManager.Tools.Add(welder);
                    m_constructionBlock.SendAddTarget(target, TargetTypes.Construction);
                }

                if (target.IsFullIntegrity && !target.HasDeformation)
                {
                    CompleteTarget(target);
                    return;
                }

                if (m_areaTargetBlocks.ContainsKey(target))
                {
                    BoundingBoxD bb;
                    target.GetWorldBoundingBox(out bb, true);
                    if (!m_areaTargetBlocks[target].IsInsideBox(bb))
                    {
                        CancelTarget(target);
                        return;
                    }
                }

                if (target.IsDestroyed || target.IsFullyDismounted || (target.FatBlock != null && target.FatBlock.Closed))
                {
                    Logging.Instance.WriteLine("CANCELLING Construction/Repair Target due to target being destroyed");
                    CancelTarget(target);
                    return;
                }

                if (welder != null && MyAPIGateway.Session.ElapsedPlayTime.TotalMilliseconds - welder.StartTime >= welder.WaitTime)
                {
                    target.MoveItemsToConstructionStockpile(((MyEntity)m_constructionBlock.ConstructionBlock).GetInventory());
                    Dictionary <string, int> missing = new Dictionary <string, int>();
                    target.GetMissingComponents(missing);

                    if (!target.HasDeformation && !target.CanContinueBuild(((MyEntity)m_constructionBlock.ConstructionBlock).GetInventory()))
                    {
                        if (!MyAPIGateway.Session.CreativeMode)
                        {
                            Logging.Instance.WriteLine("CANCELLING Construction/Repair Target due to missing components");
                            foreach (var item in missing)
                            {
                                Logging.Instance.WriteLine(string.Format("Missing component: {0} - {1}", item.Value, item.Key));
                            }
                            CancelTarget(target);
                        }
                    }

                    return;
                }

                bool isRemote = false;
                using (m_remoteLock.AcquireExclusiveUsing())
                {
                    isRemote = m_remoteTargets.Contains(target);
                }

                if (isRemote && EntityHelper.GetDistanceBetweenBlockAndSlimblock((IMyCubeBlock)m_constructionBlock.ConstructionBlock, target) > m_maxDistance)
                {
                    Logging.Instance.WriteLine("CANCELLING Repair Target due to target being out of range");
                    CancelTarget(target);
                    return;
                }
            }

            CreateConstructionParticle(target);
        }