private static void AddItemToLootBag(MyEntity itemOwner, MyPhysicalInventoryItem item, ref MyEntity lootBagEntity) { MyLootBagDefinition lootBagDefinition = MyDefinitionManager.Static.GetLootBagDefinition(); if (lootBagDefinition != null) { MyDefinitionBase itemDefinition = item.GetItemDefinition(); if (itemDefinition != null) { if ((lootBagEntity == null) && (lootBagDefinition.SearchRadius > 0f)) { Vector3D position = itemOwner.PositionComp.GetPosition(); BoundingSphereD boundingSphere = new BoundingSphereD(position, (double)lootBagDefinition.SearchRadius); List <MyEntity> entitiesInSphere = MyEntities.GetEntitiesInSphere(ref boundingSphere); double maxValue = double.MaxValue; foreach (MyEntity entity in entitiesInSphere) { if (entity.MarkedForClose) { continue; } if ((entity.GetType() == typeof(MyEntity)) && ((entity.DefinitionId != null) && (entity.DefinitionId.Value == lootBagDefinition.ContainerDefinition))) { double num2 = (entity.PositionComp.GetPosition() - position).LengthSquared(); if (num2 < maxValue) { lootBagEntity = entity; maxValue = num2; } } } entitiesInSphere.Clear(); } if ((lootBagEntity == null) || (lootBagEntity.Components.Has <MyInventoryBase>() && !(lootBagEntity.Components.Get <MyInventoryBase>() as MyInventory).CanItemsBeAdded(item.Amount, itemDefinition.Id))) { MyContainerDefinition definition2; lootBagEntity = null; if (MyComponentContainerExtension.TryGetContainerDefinition(lootBagDefinition.ContainerDefinition.TypeId, lootBagDefinition.ContainerDefinition.SubtypeId, out definition2)) { lootBagEntity = SpawnBagAround(itemOwner, definition2, 3, 2, 5, 1f); } } if (lootBagEntity != null) { MyInventory inventory = lootBagEntity.Components.Get <MyInventoryBase>() as MyInventory; if (inventory != null) { if (itemDefinition is MyCubeBlockDefinition) { inventory.AddBlocks(itemDefinition as MyCubeBlockDefinition, item.Amount); } else { inventory.AddItems(item.Amount, item.Content); } } } } } }
public void AddChangedPhysicalInventoryItem(MyPhysicalInventoryItem intentoryItem, MyFixedPoint changedAmount, bool added) { Debug.Assert(changedAmount > 0 || (!added && changedAmount < 0)); var definition = intentoryItem.GetItemDefinition(); if (definition == null) { return; } if (changedAmount < 0) { changedAmount = -changedAmount; } Debug.Assert(changedAmount > 0); var item = new MyItemInfo() { DefinitionId = definition.Id, Icons = definition.Icons, TotalAmount = intentoryItem.Amount, ChangedAmount = changedAmount, Added = added }; AddItem(item); }
public void AddPhysicalInventoryItem(MyPhysicalInventoryItem intentoryItem, MyFixedPoint addedAmount) { var definition = intentoryItem.GetItemDefinition(); if (definition == null) { return; } var item = new MyItemInfo() { DefinitionId = definition.Id, Icon = definition.Icon, TotalAmount = intentoryItem.Amount, AddedAmount = addedAmount }; AddItem(item); }
/// <summary> /// Add the given inventory item to loot bag. If loot bag does not exist then it will be created. /// </summary> private static void AddItemToLootBag(MyEntity itemOwner, MyPhysicalInventoryItem item, ref MyEntity lootBagEntity) { Debug.Assert(Sandbox.Game.Multiplayer.Sync.IsServer); var lootBagDefinition = MyDefinitionManager.Static.GetLootBagDefinition(); Debug.Assert(lootBagDefinition != null, "Loot bag not definined"); if (lootBagDefinition == null) { return; } // Block MyDefinitionBase itemDefinition = item.GetItemDefinition(); Debug.Assert(itemDefinition != null, "Unknown inventory item"); if (itemDefinition == null) { return; } // Find lootbag nearby. if (lootBagEntity == null && lootBagDefinition.SearchRadius > 0) { Vector3D itemOwnerPosition = itemOwner.PositionComp.GetPosition(); BoundingSphereD sphere = new BoundingSphereD(itemOwnerPosition, lootBagDefinition.SearchRadius); var entitiesInSphere = MyEntities.GetEntitiesInSphere(ref sphere); double minDistanceSq = double.MaxValue; foreach (var entity in entitiesInSphere) { if (!entity.MarkedForClose && (entity.GetType() == typeof(MyEntity))) { if (entity.DefinitionId != null && entity.DefinitionId.Value == lootBagDefinition.ContainerDefinition) { var distanceSq = (entity.PositionComp.GetPosition() - itemOwnerPosition).LengthSquared(); if (distanceSq < minDistanceSq) { lootBagEntity = entity; minDistanceSq = distanceSq; } } } } entitiesInSphere.Clear(); } // Create lootbag if (lootBagEntity == null || (lootBagEntity.Components.Has <MyInventoryBase>() && !(lootBagEntity.Components.Get <MyInventoryBase>() as MyInventory).CanItemsBeAdded(item.Amount, itemDefinition.Id))) { lootBagEntity = null; MyContainerDefinition lootBagDef; if (MyComponentContainerExtension.TryGetContainerDefinition(lootBagDefinition.ContainerDefinition.TypeId, lootBagDefinition.ContainerDefinition.SubtypeId, out lootBagDef)) { lootBagEntity = SpawnBagAround(itemOwner, lootBagDef); } } Debug.Assert(lootBagEntity != null, "Loot bag not created"); // Fill lootbag inventory if (lootBagEntity != null) { MyInventory inventory = lootBagEntity.Components.Get <MyInventoryBase>() as MyInventory; Debug.Assert(inventory != null); if (inventory != null) { if (itemDefinition is MyCubeBlockDefinition) { inventory.AddBlocks(itemDefinition as MyCubeBlockDefinition, item.Amount); } else { inventory.AddItems(item.Amount, item.Content); } } } }
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); }