Beispiel #1
0
        public void DecreaseMountLevel(float unmountAmount, MyConstructionStockpile outputStockpile = null, bool useDefaultDeconstructEfficiency = false)
        {
            float ratio = this.BuildIntegrity / this.Integrity;

            this.UnmountInternal(unmountAmount, outputStockpile, false, useDefaultDeconstructEfficiency);
            this.UpdateBuildIntegrityDown(ratio);
        }
Beispiel #2
0
        public void GetMissingComponents(Dictionary <string, int> addToDictionary, MyConstructionStockpile availableItems = null)
        {
            Dictionary <string, int> dictionary;
            string str2;
            int    topGroupIndex = this.m_topGroupIndex;

            MyCubeBlockDefinition.Component component = this.m_blockDefinition.Components[topGroupIndex];
            int num2 = this.m_topComponentIndex + 1;

            if (this.IsFullyDismounted)
            {
                num2--;
            }
            if (num2 < component.Count)
            {
                string subtypeName = component.Definition.Id.SubtypeName;
                if (!addToDictionary.ContainsKey(subtypeName))
                {
                    addToDictionary[subtypeName] = component.Count - num2;
                }
                else
                {
                    dictionary        = addToDictionary;
                    str2              = subtypeName;
                    dictionary[str2] += component.Count - num2;
                }
            }
            topGroupIndex++;
            while (topGroupIndex < this.m_blockDefinition.Components.Length)
            {
                component = this.m_blockDefinition.Components[topGroupIndex];
                string subtypeName = component.Definition.Id.SubtypeName;
                if (!addToDictionary.ContainsKey(subtypeName))
                {
                    addToDictionary[subtypeName] = component.Count;
                }
                else
                {
                    dictionary        = addToDictionary;
                    str2              = subtypeName;
                    dictionary[str2] += component.Count;
                }
                topGroupIndex++;
            }
            if (availableItems != null)
            {
                for (topGroupIndex = 0; topGroupIndex < addToDictionary.Keys.Count; topGroupIndex++)
                {
                    string subtypeName = addToDictionary.Keys.ElementAt <string>(topGroupIndex);
                    dictionary        = addToDictionary;
                    str2              = subtypeName;
                    dictionary[str2] -= availableItems.GetItemAmount(new MyDefinitionId(typeof(MyObjectBuilder_Component), subtypeName), MyItemFlags.None);
                    if (addToDictionary[subtypeName] <= 0)
                    {
                        addToDictionary.Remove(subtypeName);
                        topGroupIndex--;
                    }
                }
            }
        }
        public bool CanContinueBuild(MyInventory inventory, MyConstructionStockpile stockpile)
        {
            if (IsFullIntegrity)
            {
                return(false);
            }
            float topIntegrity = GetTopComponentIntegrity();

            if (topIntegrity < m_blockDefinition.Components[m_topGroupIndex].Definition.MaxIntegrity)
            {
                return(true);
            }

            int nextCompoGroup = m_topGroupIndex;

            if (m_topComponentIndex == m_blockDefinition.Components[nextCompoGroup].Count - 1)
            {
                nextCompoGroup++;
            }

            var componentDefinition = m_blockDefinition.Components[nextCompoGroup].Definition;

            if (stockpile != null && stockpile.GetItemAmount(componentDefinition.Id) > 0)
            {
                return(true);
            }

            if (inventory != null && inventory.GetItemAmount(componentDefinition.Id) > 0)
            {
                return(true);
            }
            return(false);
        }
Beispiel #4
0
        public void ApplyDamage(float damage, MyConstructionStockpile outputStockpile = null)
        {
            this.UnmountInternal(damage, outputStockpile, true, false);
            float ratio = this.BuildIntegrity / this.Integrity;

            this.UpdateBuildIntegrityDown(ratio);
        }
Beispiel #5
0
        /// <summary>
        /// Applies damage to the component stack. The method works almost the same as dismounting, it just leaves the
        /// build level at the original value and also the parts that are put into the outputStockpile are damaged.
        /// </summary>
        public void ApplyDamage(float damage, MyConstructionStockpile outputStockpile = null)
        {
            Debug.Assert(!IsDestroyed, "Applying damage to an already destroyed stack. Block should have been removed.");

            bool oldWorkingState = IsFunctional;

            UnmountInternal(damage, outputStockpile, true);
            CheckFunctionalState(oldWorkingState);
        }
Beispiel #6
0
        private void UnmountInternal(float unmountAmount, MyConstructionStockpile outputStockpile = null, bool damageItems = false, bool useDefaultDeconstructEfficiency = false)
        {
            float topComponentIntegrity = this.GetTopComponentIntegrity();
            int   topGroupIndex         = this.m_topGroupIndex;
            int   topComponentIndex     = this.m_topComponentIndex;
            MyObjectBuilder_PhysicalObject physicalObject = null;
            MyObjectBuilder_Ore            scrapBuilder   = MyFloatingObject.ScrapBuilder;

            while ((unmountAmount * this.GetDeconstructionEfficiency(topGroupIndex, damageItems | useDefaultDeconstructEfficiency)) >= topComponentIntegrity)
            {
                this.Integrity -= topComponentIntegrity;
                unmountAmount  -= topComponentIntegrity;
                if ((outputStockpile != null) && MySession.Static.SurvivalMode)
                {
                    bool flag = damageItems && MyFakes.ENABLE_DAMAGED_COMPONENTS;
                    if (!damageItems || (flag && (MyRandom.Instance.NextFloat() <= this.m_blockDefinition.Components[topGroupIndex].Definition.DropProbability)))
                    {
                        physicalObject = (MyObjectBuilder_PhysicalObject)MyObjectBuilderSerializer.CreateNewObject((SerializableDefinitionId)this.m_blockDefinition.Components[topGroupIndex].DeconstructItem.Id);
                        if (flag)
                        {
                            physicalObject.Flags |= MyItemFlags.Damaged;
                        }
                        if ((this.Integrity > 0f) || this.m_yieldLastComponent)
                        {
                            outputStockpile.AddItems(1, physicalObject);
                        }
                    }
                    MyComponentDefinition definition = this.m_blockDefinition.Components[topGroupIndex].Definition;
                    if (((MyFakes.ENABLE_SCRAP & damageItems) && (MyRandom.Instance.NextFloat() < definition.DropProbability)) && ((this.Integrity > 0f) || this.m_yieldLastComponent))
                    {
                        outputStockpile.AddItems((int)(0.8f * definition.Mass), scrapBuilder);
                    }
                }
                topComponentIndex--;
                if (topComponentIndex < 0)
                {
                    topGroupIndex--;
                    if (topGroupIndex < 0)
                    {
                        this.SetTopIndex(0, 0);
                        this.Integrity = 0f;
                        return;
                    }
                    topComponentIndex = this.m_blockDefinition.Components[topGroupIndex].Count - 1;
                }
                topComponentIntegrity = this.m_blockDefinition.Components[topGroupIndex].Definition.MaxIntegrity;
                this.SetTopIndex(topGroupIndex, topComponentIndex);
            }
            this.Integrity        -= unmountAmount * this.GetDeconstructionEfficiency(topGroupIndex, damageItems | useDefaultDeconstructEfficiency);
            topComponentIntegrity -= unmountAmount * this.GetDeconstructionEfficiency(topGroupIndex, damageItems | useDefaultDeconstructEfficiency);
            if (topComponentIntegrity < 1.525902E-05f)
            {
                this.Integrity       += 1.525902E-05f - topComponentIntegrity;
                topComponentIntegrity = 1.525902E-05f;
            }
        }
Beispiel #7
0
        /// <summary>
        /// Applies damage to the component stack. The method works almost the same as dismounting, it just leaves the
        /// build level at the original value and also the parts that are put into the outputStockpile are damaged.
        /// </summary>
        public void ApplyDamage(float damage, MyConstructionStockpile outputStockpile = null)
        {
            Debug.Assert(!IsDestroyed, "Applying damage to an already destroyed stack. Block should have been removed.");

            UnmountInternal(damage, outputStockpile, true);

            float buildIntegrityRatio = BuildIntegrity / Integrity; // Save the original build integrity ratio

            // Following function calls CheckFunctionalState itself
            UpdateBuildIntegrityDown(buildIntegrityRatio);
        }
        /// <summary>
        /// Dismounts component stack, dismounted items are put into output stockpile
        /// </summary>
        public void DecreaseMountLevel(float unmountAmount, MyConstructionStockpile outputStockpile = null)
        {
            Debug.Assert(!IsFullyDismounted, "Dismounting a fully dismounted block. Either it was not razed or it was not created correctly.");

            float buildIntegrityRatio = BuildIntegrity / Integrity; // Save the original build integrity ratio

            UnmountInternal(unmountAmount, outputStockpile);

            // Following function calls CheckFunctionalState itself
            UpdateBuildIntegrityDown(buildIntegrityRatio);
        }
        public void GetMissingComponents(Dictionary <string, int> addToDictionary, MyConstructionStockpile availableItems = null)
        {
            int index      = m_topGroupIndex;
            var component  = m_blockDefinition.Components[index];
            int mountCount = m_topComponentIndex + 1;

            if (IsFullyDismounted)
            {
                mountCount--;
            }
            if (mountCount < component.Count)
            {
                string subTypeId = component.Definition.Id.SubtypeName;
                if (addToDictionary.ContainsKey(subTypeId))
                {
                    addToDictionary[subTypeId] += component.Count - mountCount;
                }
                else
                {
                    addToDictionary[subTypeId] = component.Count - mountCount;
                }
            }
            index++;
            for (; index < m_blockDefinition.Components.Length; index++)
            {
                component = m_blockDefinition.Components[index];
                string subTypeId = component.Definition.Id.SubtypeName;
                if (addToDictionary.ContainsKey(subTypeId))
                {
                    addToDictionary[subTypeId] += component.Count;
                }
                else
                {
                    addToDictionary[subTypeId] = component.Count;
                }
            }
            if (availableItems != null)
            {
                for (index = 0; index < addToDictionary.Keys.Count; index++)
                {
                    string key = addToDictionary.Keys.ElementAt(index);
                    addToDictionary[key] -= availableItems.GetItemAmount(new MyDefinitionId(typeof(MyObjectBuilder_Component), key));
                    if (addToDictionary[key] <= 0)
                    {
                        addToDictionary.Remove(key);
                        index--;
                    }
                }
            }
        }
Beispiel #10
0
 private bool CheckOrMountFirstComponent(MyConstructionStockpile stockpile = null)
 {
     if (this.Integrity <= 7.629511E-06f)
     {
         MyComponentDefinition definition = this.m_blockDefinition.Components[0].Definition;
         if ((stockpile != null) && !stockpile.RemoveItems(1, definition.Id, MyItemFlags.None))
         {
             return(false);
         }
         this.Integrity = 1.525902E-05f;
         this.UpdateBuildIntegrityUp();
     }
     return(true);
 }
        private bool CheckOrMountFirstComponent(MyConstructionStockpile stockpile = null)
        {
            if (Integrity > MOUNT_THRESHOLD / 2)
            {
                return(true);
            }
            var firstComponent = m_blockDefinition.Components[0].Definition;

            if (stockpile == null || stockpile.RemoveItems(1, firstComponent.Id))
            {
                Integrity = MOUNT_THRESHOLD;
                UpdateBuildIntegrityUp();
                return(true);
            }
            return(false);
        }
Beispiel #12
0
 private void IncreaseMountLevelInternal(float mountAmount, MyConstructionStockpile stockpile = null)
 {
     if (this.CheckOrMountFirstComponent(stockpile))
     {
         float topComponentIntegrity = this.GetTopComponentIntegrity();
         float maxIntegrity          = this.m_blockDefinition.Components[this.m_topGroupIndex].Definition.MaxIntegrity;
         int   topGroupIndex         = this.m_topGroupIndex;
         int   topComponentIndex     = this.m_topComponentIndex;
         while (mountAmount > 0f)
         {
             float num5 = maxIntegrity - topComponentIntegrity;
             if (mountAmount < num5)
             {
                 this.Integrity += mountAmount;
                 this.UpdateBuildIntegrityUp();
                 return;
             }
             this.Integrity += num5 + 1.525902E-05f;
             mountAmount    -= num5 + 1.525902E-05f;
             if ((topComponentIndex + 1) >= this.m_blockDefinition.Components[this.m_topGroupIndex].Count)
             {
                 topGroupIndex++;
                 topComponentIndex = 0;
             }
             if (topGroupIndex == this.m_blockDefinition.Components.Length)
             {
                 this.Integrity = this.MaxIntegrity;
                 this.UpdateBuildIntegrityUp();
                 return;
             }
             MyComponentDefinition definition = this.m_blockDefinition.Components[topGroupIndex].Definition;
             if ((stockpile != null) && !stockpile.RemoveItems(1, definition.Id, MyItemFlags.None))
             {
                 this.Integrity -= 1.525902E-05f;
                 this.UpdateBuildIntegrityUp();
                 return;
             }
             this.UpdateBuildIntegrityUp();
             this.SetTopIndex(topGroupIndex, topComponentIndex);
             topComponentIntegrity = 1.525902E-05f;
             maxIntegrity          = this.m_blockDefinition.Components[topGroupIndex].Definition.MaxIntegrity;
         }
     }
 }
Beispiel #13
0
 public bool CanContinueBuild(MyInventoryBase inventory, MyConstructionStockpile stockpile)
 {
     if (this.IsFullIntegrity)
     {
         return(false);
     }
     if (this.GetTopComponentIntegrity() >= this.m_blockDefinition.Components[this.m_topGroupIndex].Definition.MaxIntegrity)
     {
         int topGroupIndex = this.m_topGroupIndex;
         if (this.m_topComponentIndex == (this.m_blockDefinition.Components[topGroupIndex].Count - 1))
         {
             topGroupIndex++;
         }
         MyComponentDefinition definition = this.m_blockDefinition.Components[topGroupIndex].Definition;
         if ((stockpile == null) || (stockpile.GetItemAmount(definition.Id, MyItemFlags.None) <= 0))
         {
             return((inventory != null) && (MyCubeBuilder.BuildComponent.GetItemAmountCombined(inventory, definition.Id) > 0));
         }
     }
     return(true);
 }
Beispiel #14
0
        public void IncreaseMountLevel(float mountAmount, MyConstructionStockpile stockpile = null)
        {
            bool isFunctional = this.IsFunctional;

            this.IncreaseMountLevelInternal(mountAmount, stockpile);
        }
 private bool CheckOrMountFirstComponent(MyConstructionStockpile stockpile = null)
 {
     if (Integrity > MOUNT_THRESHOLD / 2)
     {
         return true;
     }
     var firstComponent = m_blockDefinition.Components[0].Definition;
     if (stockpile == null || stockpile.RemoveItems(1, firstComponent.Id))
     {
         Integrity = MOUNT_THRESHOLD;
         UpdateBuildIntegrityUp();
         return true;
     }
     return false;
 }
 public void GetMissingComponents(Dictionary<string, int> addToDictionary, MyConstructionStockpile availableItems = null)
 {
     int index = m_topGroupIndex;
     var component = m_blockDefinition.Components[index];
     int mountCount = m_topComponentIndex + 1;
     if (IsFullyDismounted)
         mountCount--;
     if (mountCount < component.Count)
     {
         string subTypeId = component.Definition.Id.SubtypeName;
         if (addToDictionary.ContainsKey(subTypeId))
             addToDictionary[subTypeId] += component.Count - mountCount;
         else
             addToDictionary[subTypeId] = component.Count - mountCount;
     }
     index++;
     for (; index < m_blockDefinition.Components.Length; index++)
     {
         component = m_blockDefinition.Components[index];
         string subTypeId = component.Definition.Id.SubtypeName;
         if (addToDictionary.ContainsKey(subTypeId))
             addToDictionary[subTypeId] += component.Count;
         else
             addToDictionary[subTypeId] = component.Count;
     }
     if (availableItems != null)
         for (index = 0; index < addToDictionary.Keys.Count; index++ )
         {
             string key = addToDictionary.Keys.ElementAt(index);
             addToDictionary[key] -= availableItems.GetItemAmount(new MyDefinitionId(typeof(MyObjectBuilder_Component), key));
             if (addToDictionary[key] <= 0)
             {
                 addToDictionary.Remove(key);
                 index--;
             }
         }
 }
        private void UnmountInternal(float unmountAmount, MyConstructionStockpile outputStockpile = null, bool damageItems = false)
        {
            // We don't have to update functional state in this function, because it is done in the caller functions.
            // If you start using this function anywhere else, don't forget to update functional state yourself!

            float topIntegrity = GetTopComponentIntegrity();
            int groupIndex = (int)m_topGroupIndex;
            int compIndex = (int)m_topComponentIndex;

            // Continue removing components, until the to be removed component's health is larger than unmountAmount
            MyObjectBuilder_Component componentBuilder = null;
            var scrapBuilder = MyFloatingObject.ScrapBuilder;
			while (unmountAmount * GetDeconstructionEfficiency(groupIndex, damageItems) >= topIntegrity)
            {
                Integrity -= topIntegrity;
                unmountAmount -= topIntegrity;

                // In creative mode, the outputInventory should normally be null.
                // However, if we load the game from the realistic mode, it would not be necessarilly null.
                if (outputStockpile != null && MySession.Static.SurvivalMode)
                {
                    bool doDamage = damageItems && MyFakes.ENABLE_DAMAGED_COMPONENTS;
                    if (!damageItems || (doDamage && MyRandom.Instance.NextFloat() <= m_blockDefinition.Components[groupIndex].Definition.DropProbability))
                    {
                        componentBuilder = MyObjectBuilderSerializer.CreateNewObject<MyObjectBuilder_Component>();
                        componentBuilder.SubtypeName = m_blockDefinition.Components[groupIndex].Definition.Id.SubtypeName;
                        if (doDamage)
                        {
                            componentBuilder.Flags |= MyItemFlags.Damaged;
                        }
                        if (!outputStockpile.AddItems(1, componentBuilder))
                        {
                            // TODO: Throw the items into space (although this branch should probably not happen)
                        }
                    }

                    MyComponentDefinition destroyedComponentDefinition = m_blockDefinition.Components[groupIndex].Definition;
                    if (MyFakes.ENABLE_SCRAP && damageItems && (MyRandom.Instance.NextFloat() < destroyedComponentDefinition.DropProbability))
                    {
                        outputStockpile.AddItems((int)(0.8f * destroyedComponentDefinition.Mass), scrapBuilder);
                    }
                }      
               
                compIndex--;
                if (compIndex < 0)
                {
                    groupIndex--;
                    if (groupIndex < 0)
                    {
                        SetTopIndex(0, 0);
                        Integrity = 0.0f;
                        return;
                    }
                    else
                    {
                        compIndex = m_blockDefinition.Components[groupIndex].Count - 1;
                    }
                }


                topIntegrity = m_blockDefinition.Components[groupIndex].Definition.MaxIntegrity;
                SetTopIndex(groupIndex, compIndex);
            }

            // Damage the remaining component
			Integrity -= unmountAmount * GetDeconstructionEfficiency(groupIndex, damageItems);
			topIntegrity -= unmountAmount * GetDeconstructionEfficiency(groupIndex, damageItems);

            if (topIntegrity < MOUNT_THRESHOLD)
            {
                Integrity += MOUNT_THRESHOLD - topIntegrity;
                topIntegrity = MOUNT_THRESHOLD;
            }

            Debug.Assert(Integrity >= MOUNT_THRESHOLD, "Integrity inconsistent after a dismount of component stack");
        }
        /// <summary>
        /// Dismounts component stack, dismounted items are put into output stockpile
        /// </summary>
        public void DecreaseMountLevel(float unmountAmount, MyConstructionStockpile outputStockpile = null)
        {
            Debug.Assert(!IsFullyDismounted, "Dismounting a fully dismounted block. Either it was not razed or it was not created correctly.");

            float buildIntegrityRatio = BuildIntegrity / Integrity; // Save the original build integrity ratio

            UnmountInternal(unmountAmount, outputStockpile);

            // Following function calls CheckFunctionalState itself
            UpdateBuildIntegrityDown(buildIntegrityRatio);
        }
        private void IncreaseMountLevelInternal(float mountAmount, MyConstructionStockpile stockpile = null)
        {
            Debug.Assert(BuildIntegrity >= Integrity, "Integrity of component stack is larger than build integrity");

            if (!CheckOrMountFirstComponent(stockpile))
            {
                return;
            }

            float topIntegrity     = GetTopComponentIntegrity();
            float maxCompIntegrity = m_blockDefinition.Components[m_topGroupIndex].Definition.MaxIntegrity;
            int   groupIndex       = (int)m_topGroupIndex;
            int   compIndex        = (int)m_topComponentIndex;

            while (mountAmount > 0)
            {
                float toBuild = maxCompIntegrity - topIntegrity;

                if (mountAmount < toBuild)
                {
                    Integrity += mountAmount;
                    UpdateBuildIntegrityUp();
                    break;
                }

                Integrity   += toBuild + MOUNT_THRESHOLD;
                mountAmount -= toBuild + MOUNT_THRESHOLD;

                ++compIndex;
                if (compIndex >= m_blockDefinition.Components[m_topGroupIndex].Count)
                {
                    ++groupIndex;
                    compIndex = 0;
                }
                // Fully built
                if (groupIndex == m_blockDefinition.Components.Length)
                {
                    Integrity = MaxIntegrity;
                    UpdateBuildIntegrityUp();
                    break;
                }
                // We don't have the next item
                var nextComponent = m_blockDefinition.Components[groupIndex].Definition;
                if (stockpile != null && !stockpile.RemoveItems(1, nextComponent.Id))
                {
                    Integrity -= MOUNT_THRESHOLD;
                    UpdateBuildIntegrityUp();
                    break;
                }
                else
                {
                    UpdateBuildIntegrityUp();
                }

                SetTopIndex(groupIndex, compIndex);
                topIntegrity     = MOUNT_THRESHOLD;
                maxCompIntegrity = m_blockDefinition.Components[groupIndex].Definition.MaxIntegrity;
            }

            return;
        }
        public void IncreaseMountLevel(float mountAmount, MyConstructionStockpile stockpile = null)
        {
            bool oldWorkingState = IsFunctional;

            IncreaseMountLevelInternal(mountAmount, stockpile);
        }
        /// <summary>
        /// Applies damage to the component stack. The method works almost the same as dismounting, it just leaves the
        /// build level at the original value and also the parts that are put into the outputStockpile are damaged.
        /// </summary>
        public void ApplyDamage(float damage, MyConstructionStockpile outputStockpile = null)
        {
            Debug.Assert(!IsDestroyed, "Applying damage to an already destroyed stack. Block should have been removed.");

            UnmountInternal(damage, outputStockpile, true);

            float buildIntegrityRatio = BuildIntegrity / Integrity; // Save the original build integrity ratio
            // Following function calls CheckFunctionalState itself
            UpdateBuildIntegrityDown(buildIntegrityRatio);
        }
 public void IncreaseMountLevel(float mountAmount, MyConstructionStockpile stockpile = null)
 {
     bool oldWorkingState = IsFunctional;
     IncreaseMountLevelInternal(mountAmount, stockpile);
 }
        public bool CanContinueBuild(MyInventory inventory, MyConstructionStockpile stockpile)
        {
            if (IsFullIntegrity)
                return false;
            float topIntegrity = GetTopComponentIntegrity();
            if (topIntegrity < m_blockDefinition.Components[m_topGroupIndex].Definition.MaxIntegrity)
                return true;

            int nextCompoGroup = m_topGroupIndex;
            if (m_topComponentIndex == m_blockDefinition.Components[nextCompoGroup].Count - 1)
            {
                nextCompoGroup++;
            }

            var componentDefinition = m_blockDefinition.Components[nextCompoGroup].Definition;
            if (stockpile != null && stockpile.GetItemAmount(componentDefinition.Id) > 0)
            {
                return true;
            }

            if (inventory != null && inventory.GetItemAmount(componentDefinition.Id) > 0)
            {
                return true;
            }
            return false;
        }
        private void UnmountInternal(float unmountAmount, MyConstructionStockpile outputStockpile = null, bool damageItems = false)
        {
            // We don't have to update functional state in this function, because it is done in the caller functions.
            // If you start using this function anywhere else, don't forget to update functional state yourself!

            float topIntegrity = GetTopComponentIntegrity();
            int   groupIndex   = (int)m_topGroupIndex;
            int   compIndex    = (int)m_topComponentIndex;

            // Continue removing components, until the to be removed component's health is larger than unmountAmount
            MyObjectBuilder_Component componentBuilder = null;
            var scrapBuilder = MyFloatingObject.ScrapBuilder;

            while (unmountAmount * GetDeconstructionEfficiency(groupIndex, damageItems) >= topIntegrity)
            {
                Integrity     -= topIntegrity;
                unmountAmount -= topIntegrity;

                // In creative mode, the outputInventory should normally be null.
                // However, if we load the game from the realistic mode, it would not be necessarilly null.
                if (outputStockpile != null && MySession.Static.SurvivalMode)
                {
                    bool doDamage = damageItems && MyFakes.ENABLE_DAMAGED_COMPONENTS;
                    if (!damageItems || (doDamage && MyRandom.Instance.NextFloat() <= m_blockDefinition.Components[groupIndex].Definition.DropProbability))
                    {
                        componentBuilder             = MyObjectBuilderSerializer.CreateNewObject <MyObjectBuilder_Component>();
                        componentBuilder.SubtypeName = m_blockDefinition.Components[groupIndex].Definition.Id.SubtypeName;
                        if (doDamage)
                        {
                            componentBuilder.Flags |= MyItemFlags.Damaged;
                        }
                        if (!outputStockpile.AddItems(1, componentBuilder))
                        {
                            // TODO: Throw the items into space (although this branch should probably not happen)
                        }
                    }

                    MyComponentDefinition destroyedComponentDefinition = m_blockDefinition.Components[groupIndex].Definition;
                    if (MyFakes.ENABLE_SCRAP && damageItems && (MyRandom.Instance.NextFloat() < destroyedComponentDefinition.DropProbability))
                    {
                        outputStockpile.AddItems((int)(0.8f * destroyedComponentDefinition.Mass), scrapBuilder);
                    }
                }

                compIndex--;
                if (compIndex < 0)
                {
                    groupIndex--;
                    if (groupIndex < 0)
                    {
                        SetTopIndex(0, 0);
                        Integrity = 0.0f;
                        return;
                    }
                    else
                    {
                        compIndex = m_blockDefinition.Components[groupIndex].Count - 1;
                    }
                }


                topIntegrity = m_blockDefinition.Components[groupIndex].Definition.MaxIntegrity;
                SetTopIndex(groupIndex, compIndex);
            }

            // Damage the remaining component
            Integrity    -= unmountAmount * GetDeconstructionEfficiency(groupIndex, damageItems);
            topIntegrity -= unmountAmount * GetDeconstructionEfficiency(groupIndex, damageItems);

            if (topIntegrity < MOUNT_THRESHOLD)
            {
                Integrity   += MOUNT_THRESHOLD - topIntegrity;
                topIntegrity = MOUNT_THRESHOLD;
            }

            Debug.Assert(Integrity >= MOUNT_THRESHOLD, "Integrity inconsistent after a dismount of component stack");
        }
        private void IncreaseMountLevelInternal(float mountAmount, MyConstructionStockpile stockpile = null)
        {
            Debug.Assert(BuildIntegrity >= Integrity, "Integrity of component stack is larger than build integrity");

            if (!CheckOrMountFirstComponent(stockpile))
            {
                return;
            }

            float topIntegrity = GetTopComponentIntegrity();
            float maxCompIntegrity = m_blockDefinition.Components[m_topGroupIndex].Definition.MaxIntegrity;
            int groupIndex = (int)m_topGroupIndex;
            int compIndex = (int)m_topComponentIndex;

            while (mountAmount > 0) {
                float toBuild = maxCompIntegrity - topIntegrity;

                if (mountAmount < toBuild)
                {
                    Integrity += mountAmount;
                    UpdateBuildIntegrityUp();
                    break;
                }

                Integrity += toBuild + MOUNT_THRESHOLD;
                mountAmount -= toBuild + MOUNT_THRESHOLD;

                ++compIndex;
                if (compIndex >= m_blockDefinition.Components[m_topGroupIndex].Count)
                {
                    ++groupIndex;
                    compIndex = 0;
                }
                // Fully built
                if (groupIndex == m_blockDefinition.Components.Length)
                {
                    Integrity = MaxIntegrity;
                    UpdateBuildIntegrityUp();
                    break;
                }
                // We don't have the next item
                var nextComponent = m_blockDefinition.Components[groupIndex].Definition;
                if (stockpile != null && !stockpile.RemoveItems(1, nextComponent.Id))
                {
                    Integrity -= MOUNT_THRESHOLD;
                    UpdateBuildIntegrityUp();
                    break;
                }
                else
                {
                    UpdateBuildIntegrityUp();
                }

                SetTopIndex(groupIndex, compIndex);
                topIntegrity = MOUNT_THRESHOLD;
                maxCompIntegrity = m_blockDefinition.Components[groupIndex].Definition.MaxIntegrity;
            }

            return;
        }
        /// <summary>
        /// Applies damage to the component stack. The method works almost the same as dismounting, it just leaves the
        /// build level at the original value and also the parts that are put into the outputStockpile are damaged.
        /// </summary>
        public void ApplyDamage(float damage, MyConstructionStockpile outputStockpile = null)
        {
            Debug.Assert(!IsDestroyed, "Applying damage to an already destroyed stack. Block should have been removed.");

            UnmountInternal(damage, outputStockpile, true);
        }