コード例 #1
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;
            }
        }
コード例 #2
0
 private void UpdatePresentItems(MyComponentGroupDefinition group, Dictionary <MyDefinitionId, MyFixedPoint> componentCounts)
 {
     this.m_presentItems.Clear();
     for (int i = 1; i <= group.GetComponentNumber(); i++)
     {
         MyComponentDefinition componentDefinition = group.GetComponentDefinition(i);
         MyFixedPoint          point = 0;
         componentCounts.TryGetValue(componentDefinition.Id, out point);
         this.m_presentItems[i] = (int)point;
     }
 }
コード例 #3
0
        public static MyObjectBuilder_FloatingObject ChangeObjectBuilder(MyComponentDefinition componentDef, MyObjectBuilder_EntityBase entityOb)
        {
            MyObjectBuilder_PhysicalObject content = MyObjectBuilderSerializer.CreateNewObject(componentDef.Id.TypeId, componentDef.Id.SubtypeName) as MyObjectBuilder_PhysicalObject;
            Vector3D position = (Vector3D)entityOb.PositionAndOrientation.Value.Position;
            MyPhysicalInventoryItem        item = new MyPhysicalInventoryItem(1, content, 1f);
            MyObjectBuilder_FloatingObject obj1 = PrepareBuilder(ref item);

            obj1.PositionAndOrientation = new MyPositionAndOrientation(position, (Vector3)entityOb.PositionAndOrientation.Value.Forward, (Vector3)entityOb.PositionAndOrientation.Value.Up);
            obj1.EntityId = entityOb.EntityId;
            return(obj1);
        }
コード例 #4
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);
 }
コード例 #5
0
        /// <summary>
        /// This is used mainly for compactibility issues, it takes the builder of an entity of old object representation and creates a floating object builder for it
        /// </summary>
        public static MyObjectBuilder_FloatingObject ChangeObjectBuilder(MyComponentDefinition componentDef, MyObjectBuilder_EntityBase entityOb)
        {
            var componentBuilder = MyObjectBuilderSerializer.CreateNewObject(componentDef.Id.TypeId, componentDef.Id.SubtypeName) as MyObjectBuilder_PhysicalObject;

            Vector3  up       = entityOb.PositionAndOrientation.Value.Up;
            Vector3  forward  = entityOb.PositionAndOrientation.Value.Forward;
            Vector3D position = entityOb.PositionAndOrientation.Value.Position;

            var item            = new MyPhysicalInventoryItem((MyFixedPoint)1, componentBuilder);
            var floatingBuilder = PrepareBuilder(ref item);

            floatingBuilder.PositionAndOrientation = new MyPositionAndOrientation(position, forward, up);
            floatingBuilder.EntityId = entityOb.EntityId;

            return(floatingBuilder);
        }
コード例 #6
0
        public InventoryItemDialog()
        {
            //Populate the static list with the ids from the items
            if (_idList == null)
            {
                _idList = new List <MyDefinitionId>();

                DictionaryValuesReader <MyDefinitionId, MyDefinitionBase> allDefinitions = MyDefinitionManager.Static.GetAllDefinitions();
                foreach (MyDefinitionBase definition in allDefinitions)
                {
                    MyPhysicalItemDefinition def = definition as MyPhysicalItemDefinition;
                    if (def != null)
                    {
                        _idList.Add(def.Id);
                    }
                }
                foreach (MyDefinitionBase definition in allDefinitions)
                {
                    MyComponentDefinition def = definition as MyComponentDefinition;
                    if (def != null)
                    {
                        _idList.Add(def.Id);
                    }
                }
                foreach (MyDefinitionBase definition in allDefinitions)
                {
                    MyAmmoMagazineDefinition def = definition as MyAmmoMagazineDefinition;
                    if (def != null)
                    {
                        _idList.Add(def.Id);
                    }
                }
            }

            InitializeComponent();

            CMB_ItemType.BeginUpdate();
            foreach (var entry in _idList)
            {
                CMB_ItemType.Items.Add(entry);
            }
            CMB_ItemType.EndUpdate();

            TXT_ItemAmount.Text = "0.0";
        }
コード例 #7
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;
         }
     }
 }
コード例 #8
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);
 }
コード例 #9
0
        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");
        }
コード例 #10
0
        public bool DoDamage(float damage, MyStringHash damageType, bool sync, long attackerId)
        {
            if (base.MarkedForClose)
            {
                return(false);
            }
            if (sync)
            {
                if (!Sync.IsServer)
                {
                    return(false);
                }
                MySyncDamage.DoDamageSynced(this, damage, damageType, attackerId);
                return(true);
            }
            MyDamageInformation information = new MyDamageInformation(false, damage, damageType, attackerId);

            if (this.UseDamageSystem)
            {
                MyDamageSystem.Static.RaiseBeforeDamageApplied(this, ref information);
            }
            MyObjectBuilderType typeId = this.Item.Content.TypeId;

            if ((typeId == typeof(MyObjectBuilder_Ore)) || (typeId == typeof(MyObjectBuilder_Ingot)))
            {
                if (this.Item.Amount >= 1)
                {
                    if (Sync.IsServer)
                    {
                        MyFloatingObjects.RemoveFloatingObject(this, (MyFixedPoint)information.Amount);
                    }
                }
                else
                {
                    MyParticleEffect effect;
                    if (MyParticlesManager.TryCreateParticleEffect("Smoke_Construction", base.WorldMatrix, out effect))
                    {
                        effect.UserScale = 0.4f;
                    }
                    if (Sync.IsServer)
                    {
                        MyFloatingObjects.RemoveFloatingObject(this);
                    }
                }
            }
            else
            {
                this.m_health -= 10f * information.Amount;
                if (this.UseDamageSystem)
                {
                    MyDamageSystem.Static.RaiseAfterDamageApplied(this, information);
                }
                if (this.m_health < 0f)
                {
                    MyParticleEffect         effect2;
                    MyPhysicalItemDefinition definition2;
                    if (MyParticlesManager.TryCreateParticleEffect("Smoke_Construction", base.WorldMatrix, out effect2))
                    {
                        effect2.UserScale = 0.4f;
                    }
                    if (Sync.IsServer)
                    {
                        MyFloatingObjects.RemoveFloatingObject(this);
                    }
                    if ((this.Item.Content.SubtypeId == m_explosives) && Sync.IsServer)
                    {
                        BoundingSphere  sphere        = new BoundingSphere((Vector3)base.WorldMatrix.Translation, (((float)this.Item.Amount) * 0.01f) + 0.5f);
                        MyExplosionInfo explosionInfo = new MyExplosionInfo {
                            PlayerDamage                    = 0f,
                            Damage                          = 800f,
                            ExplosionType                   = MyExplosionTypeEnum.WARHEAD_EXPLOSION_15,
                            ExplosionSphere                 = sphere,
                            LifespanMiliseconds             = 700,
                            HitEntity                       = this,
                            ParticleScale                   = 1f,
                            OwnerEntity                     = this,
                            Direction                       = new Vector3?((Vector3)base.WorldMatrix.Forward),
                            VoxelExplosionCenter            = sphere.Center,
                            ExplosionFlags                  = MyExplosionFlags.APPLY_DEFORMATION | MyExplosionFlags.CREATE_SHRAPNELS | MyExplosionFlags.CREATE_PARTICLE_EFFECT | MyExplosionFlags.CREATE_DECALS | MyExplosionFlags.APPLY_FORCE_AND_DAMAGE | MyExplosionFlags.AFFECT_VOXELS | MyExplosionFlags.CREATE_DEBRIS,
                            VoxelCutoutScale                = 0.5f,
                            PlaySound                       = true,
                            ApplyForceAndDamage             = true,
                            ObjectsRemoveDelayInMiliseconds = 40
                        };
                        if (this.Physics != null)
                        {
                            explosionInfo.Velocity = this.Physics.LinearVelocity;
                        }
                        MyExplosions.AddExplosion(ref explosionInfo, true);
                    }
                    if (MyFakes.ENABLE_SCRAP && Sync.IsServer)
                    {
                        if (this.Item.Content.SubtypeId == ScrapBuilder.SubtypeId)
                        {
                            return(true);
                        }
                        if (this.Item.Content.GetId().TypeId == typeof(MyObjectBuilder_Component))
                        {
                            MyComponentDefinition componentDefinition = MyDefinitionManager.Static.GetComponentDefinition((this.Item.Content as MyObjectBuilder_Component).GetId());
                            if (MyRandom.Instance.NextFloat() < componentDefinition.DropProbability)
                            {
                                MyFloatingObjects.Spawn(new MyPhysicalInventoryItem(this.Item.Amount * 0.8f, ScrapBuilder, 1f), base.PositionComp.GetPosition(), base.WorldMatrix.Forward, base.WorldMatrix.Up, null, null);
                            }
                        }
                    }
                    if (((this.ItemDefinition != null) && ((this.ItemDefinition.DestroyedPieceId != null) && Sync.IsServer)) && MyDefinitionManager.Static.TryGetPhysicalItemDefinition(this.ItemDefinition.DestroyedPieceId.Value, out definition2))
                    {
                        MyFloatingObjects.Spawn(definition2, base.WorldMatrix.Translation, base.WorldMatrix.Forward, base.WorldMatrix.Up, this.ItemDefinition.DestroyedPieces, 1f);
                    }
                    if (this.UseDamageSystem)
                    {
                        MyDamageSystem.Static.RaiseDestroyed(this, information);
                    }
                }
            }
            return(true);
        }
コード例 #11
0
        public static MyEntity SpawnInWorldOrLootBag(this MyPhysicalInventoryItem thisItem, MyEntity owner, ref MyEntity lootBagEntity)
        {
            Debug.Assert(Sandbox.Game.Multiplayer.Sync.IsServer);

            MyDefinitionBase itemDefinition = thisItem.GetItemDefinition();

            Debug.Assert(itemDefinition != null);
            if (itemDefinition == null)
            {
                return(null);
            }

            MyEntity spawnedItem = null;

            Vector3 upDir = -MyGravityProviderSystem.CalculateNaturalGravityInPoint(owner.PositionComp.WorldMatrix.Translation);

            if (upDir == Vector3.Zero)
            {
                upDir = Vector3.Up;
            }
            else
            {
                upDir.Normalize();
            }

            if (itemDefinition is MyCubeBlockDefinition)
            {
                MyCubeBlockDefinition blockDef = itemDefinition as MyCubeBlockDefinition;

                if (MyDefinitionManager.Static.GetLootBagDefinition() != null)
                {
                    // New code which tries to spawn item with "MyEntities.FindFreePlace" and if there is no such position then loot bag is spawn and item is moved into it.
                    MyModel     blockModel = MyModels.GetModelOnlyData(blockDef.Model);
                    BoundingBox box        = blockModel.BoundingBox;
                    box.Inflate(0.15f); // Inflate with value that is higher than half size of small grid so it will eliminate problems with block center offsets.
                    float radius            = box.HalfExtents.Max();
                    var   baseSpawnPosition = owner.PositionComp.WorldMatrix.Translation;
                    if (owner is MyCharacter)
                    {
                        baseSpawnPosition += owner.PositionComp.WorldMatrix.Up + owner.PositionComp.WorldMatrix.Forward;
                    }
                    else
                    {
                        baseSpawnPosition += upDir;
                    }

                    for (int gridIndex = 0; gridIndex < thisItem.Amount; ++gridIndex)
                    {
                        Vector3D?spawnPos = null;
                        if (lootBagEntity == null && (spawnPos = MyEntities.FindFreePlace(baseSpawnPosition, radius, maxTestCount: 50, testsPerDistance: 5, stepSize: 0.25f)) != null)
                        {
                            MatrixD transform = owner.PositionComp.WorldMatrix;
                            transform.Translation = spawnPos.Value;

                            var blockBuilder = MyObjectBuilderSerializer.CreateNewObject(blockDef.Id) as MyObjectBuilder_CubeBlock;
                            blockBuilder.Min      = blockDef.Size / 2 - blockDef.Size + Vector3I.One;
                            blockBuilder.EntityId = MyEntityIdentifier.AllocateId();

                            var newGrid = MyObjectBuilderSerializer.CreateNewObject <MyObjectBuilder_CubeGrid>();
                            newGrid.PositionAndOrientation = new MyPositionAndOrientation(transform);
                            newGrid.GridSizeEnum           = blockDef.CubeSize;
                            newGrid.PersistentFlags       |= MyPersistentEntityFlags2.InScene;
                            newGrid.EntityId = MyEntityIdentifier.AllocateId();
                            newGrid.CubeBlocks.Add(blockBuilder);

                            var entity = MyEntities.CreateFromObjectBuilderAndAdd(newGrid);
                            spawnedItem = spawnedItem ?? entity;
                        }
                        else
                        {
                            AddItemToLootBag(owner, new MyPhysicalInventoryItem(1, thisItem.Content), ref lootBagEntity);
                        }
                    }
                }
                else
                {
                    // Old code used in SE (when no loot bag definition is defined).
                    float    spawnRadius = MyUtils.GetRandomFloat(Math.Max(0.25f, ITEM_SPAWN_RADIUS), ITEM_SPAWN_RADIUS);
                    Vector3D randomizer  = MyUtils.GetRandomVector3CircleNormalized() * spawnRadius + Vector3D.Up * 0.25f;

                    int         yOffset = 0;
                    MyModel     m       = MyModels.GetModelOnlyData(blockDef.Model);
                    float       sizeY   = m.BoundingBoxSize.Y + 0.05f;
                    BoundingBox box     = m.BoundingBox;

                    for (int gridIndex = 0; gridIndex < thisItem.Amount; ++gridIndex)
                    {
                        var newGrid = MyObjectBuilderSerializer.CreateNewObject <MyObjectBuilder_CubeGrid>();

                        MatrixD transform = owner.PositionComp.WorldMatrix * MatrixD.CreateTranslation(randomizer + new Vector3D(0, yOffset * sizeY, 0));
                        if (!GetNonPenetratingTransformPosition(ref box, ref transform))
                        {
                            randomizer = MyUtils.GetRandomVector3CircleNormalized() * 0.25f + Vector3D.Up * 0.25f;
                            transform  = owner.PositionComp.WorldMatrix * MatrixD.CreateTranslation(randomizer + new Vector3D(0, yOffset * sizeY, 0));
                        }

                        newGrid.PositionAndOrientation = new MyPositionAndOrientation(transform);
                        newGrid.GridSizeEnum           = blockDef.CubeSize;
                        newGrid.PersistentFlags       |= MyPersistentEntityFlags2.InScene;
                        newGrid.EntityId = MyEntityIdentifier.AllocateId();

                        var newBlock = MyObjectBuilderSerializer.CreateNewObject(blockDef.Id) as MyObjectBuilder_CubeBlock;
                        newBlock.EntityId = MyEntityIdentifier.AllocateId();
                        newGrid.CubeBlocks.Add(newBlock);

                        var entity = MyEntities.CreateFromObjectBuilderAndAdd(newGrid);
                        spawnedItem = spawnedItem ?? entity;

                        if ((gridIndex + 1) % 10 == 0)
                        {
                            spawnRadius = MyUtils.GetRandomFloat(Math.Max(0.25f, ITEM_SPAWN_RADIUS), ITEM_SPAWN_RADIUS);
                            randomizer  = MyUtils.GetRandomVector3CircleNormalized() * spawnRadius + Vector3D.Up * 0.25f;
                            yOffset     = 0;
                        }
                        else
                        {
                            yOffset++;
                        }
                    }
                }
            }
            else if (itemDefinition is MyPhysicalItemDefinition)
            {
                MyPhysicalItemDefinition floatingObjectDefinition = itemDefinition as MyPhysicalItemDefinition;

                MyFixedPoint          amount         = thisItem.Amount;
                bool                  canStack       = thisItem.Content.CanStack(thisItem.Content);
                MyFixedPoint          stackSize      = canStack ? amount : 1;
                MyFixedPoint          maxStackAmount = MyFixedPoint.MaxValue;
                MyComponentDefinition compDef        = null;
                if (MyDefinitionManager.Static.TryGetComponentDefinition(thisItem.Content.GetId(), out compDef))
                {
                    maxStackAmount = compDef.MaxStackAmount;
                    stackSize      = MyFixedPoint.Min(stackSize, maxStackAmount);
                }

                if (MyDefinitionManager.Static.GetLootBagDefinition() != null)
                {
                    // New code which tries to spawn item with "MyEntities.FindFreePlace" and if there is no such position then loot bag is spawn and item is moved into it.
                    MyModel     model             = MyModels.GetModelOnlyData(floatingObjectDefinition.Model);
                    BoundingBox box               = model.BoundingBox;
                    float       radius            = box.HalfExtents.Max();
                    var         baseSpawnPosition = owner.PositionComp.WorldMatrix.Translation;
                    if (owner is MyCharacter)
                    {
                        baseSpawnPosition += owner.PositionComp.WorldMatrix.Up + owner.PositionComp.WorldMatrix.Forward;
                    }
                    else
                    {
                        baseSpawnPosition += upDir;
                    }

                    while (amount > 0)
                    {
                        MyFixedPoint spawnAmount = stackSize;
                        amount -= stackSize;
                        if (amount < 0)
                        {
                            spawnAmount = amount + stackSize;
                        }

                        Vector3D?spawnPos = null;
                        if (lootBagEntity == null && (spawnPos = MyEntities.FindFreePlace(baseSpawnPosition, radius, maxTestCount: 50, testsPerDistance: 5, stepSize: 0.25f)) != null)
                        {
                            MatrixD worldMat = owner.PositionComp.WorldMatrix;
                            worldMat.Translation = spawnPos.Value;
                            var entity = MyFloatingObjects.Spawn(new MyPhysicalInventoryItem(spawnAmount, thisItem.Content), worldMat);
                            spawnedItem = spawnedItem ?? entity;
                        }
                        else
                        {
                            AddItemToLootBag(owner, new MyPhysicalInventoryItem(spawnAmount, thisItem.Content), ref lootBagEntity);
                        }
                    }
                }
                else
                {
                    // Old code used in SE (when no loot bag definition is defined).
                    while (amount > 0)
                    {
                        MyFixedPoint spawnAmount = stackSize;
                        amount -= stackSize;
                        if (amount < 0)
                        {
                            spawnAmount = amount + stackSize;
                        }

                        float    spawnRadius = MyUtils.GetRandomFloat(Math.Max(0.25f, ITEM_SPAWN_RADIUS), ITEM_SPAWN_RADIUS);
                        Vector3D randomizer  = MyUtils.GetRandomVector3CircleNormalized() * spawnRadius + Vector3D.Up * 0.25f;
                        var      worldMat    = owner.PositionComp.WorldMatrix * MatrixD.CreateTranslation(randomizer);

                        var entity = MyFloatingObjects.Spawn(new MyPhysicalInventoryItem(spawnAmount, thisItem.Content), worldMat);
                        spawnedItem = spawnedItem ?? entity;
                    }
                }
            }

            return(spawnedItem);
        }