public static void MoveAllContentsTo(this MyInventory fromInventory, MyInventoryBase toInventory) { foreach (var item in fromInventory.GetItems()) { toInventory.AddItems(item.Amount, item.Content); } fromInventory.Clear(); }
private static void AddItemsFuzzy(MyInventoryBase inventory, MyDefinitionId itemDefinition, int amount) { if (itemDefinition.TypeId == typeof(MyObjectBuilder_ItemTagDefinition)) { inventory.AddItemsWithTag(itemDefinition.SubtypeId, amount, true); return; } inventory.AddItems(itemDefinition, amount); }
// ReSharper disable once MemberCanBeMadeStatic.Local private void UninstallToInventory(MyInventoryBase inv, MyDefinitionId id, ref int amount) { var toAdd = Math.Min(amount, inv.ComputeAmountThatFits(id)); // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression if (inv.AddItems(id, toAdd)) { amount = toAdd; } else { amount = 0; } }
/// <summary> /// Add items of the definition id specified. /// /// If Id is an item, simply add the items. /// If Id is a tag, add a random item with that tag. /// If Id is loot table, add results of that loot table. /// </summary> /// <param name="inventory"></param> /// <param name="id"></param> /// <param name="amount"></param> /// <returns>True if item added, false if item didn't fit</returns> public static bool AddItemsFuzzyOrLoot(this MyInventoryBase inventory, MyDefinitionId id, int amount = 1) { var result = true; if (id.TypeId == typeof(MyObjectBuilder_LootTableDefinition)) { var lootTableDefinition = MyDefinitionManager.Get <MyLootTableDefinition>(id); for (var i = 0; i < amount; i++) { inventory.GenerateContent(lootTableDefinition); } } else if (id.TypeId == typeof(MyObjectBuilder_ItemTagDefinition)) { result = inventory.AddItemsWithTag(id.SubtypeId, amount, true); } else { result = inventory.AddItems(id, amount); } return(result); }
public void MoveUnneededItemsFromConstructionStockpile(MyInventoryBase toInventory) { if (m_stockpile == null) return; Debug.Assert(toInventory != null); if (toInventory == null) return; m_tmpItemList.Clear(); AcquireUnneededStockpileItems(m_tmpItemList); m_stockpile.ClearSyncList(); foreach (var item in m_tmpItemList) { var amount = (int)toInventory.ComputeAmountThatFits(item.Content.GetId()); amount = Math.Min(amount, item.Amount); toInventory.AddItems(amount, item.Content); m_stockpile.RemoveItems(amount, item.Content); } CubeGrid.SyncObject.SendStockpileChanged(this, m_stockpile.GetSyncList()); m_stockpile.ClearSyncList(); }
/// <summary> /// Moves items with the given flags from the construction inventory to the character. /// If the flags are None, all items are moved. /// </summary> public void MoveItemsFromConstructionStockpile(MyInventoryBase toInventory, MyItemFlags flags = MyItemFlags.None) { if (m_stockpile == null) return; Debug.Assert(toInventory != null); if (toInventory == null) return; m_tmpItemList.Clear(); foreach (var item in m_stockpile.GetItems()) { if (flags == MyItemFlags.None || (item.Content.Flags & flags) != 0) m_tmpItemList.Add(item); } m_stockpile.ClearSyncList(); foreach (var item in m_tmpItemList) { var amount = (int)toInventory.ComputeAmountThatFits(item.Content.GetId()); amount = Math.Min(amount, item.Amount); toInventory.AddItems(amount, item.Content); m_stockpile.RemoveItems(amount, item.Content); } CubeGrid.SyncObject.SendStockpileChanged(this, m_stockpile.GetSyncList()); m_stockpile.ClearSyncList(); }
private void updateFoodLogic() { float elapsedMinutes = (float)(mTimer.Elapsed.Seconds / 60); //float CurPlayerHealth = -1f; bool ChangedStance = false; MyObjectBuilder_Character character; MyCharacterMovementEnum curmove = MyCharacterMovementEnum.Sitting; foreach (var player in _players) { if (String.IsNullOrWhiteSpace(player.Controller?.ControlledEntity?.Entity?.DisplayName)) { PlayerData playerData = _playerDataStorage.Retrieve(player); Logging.Instance.WriteLine(playerData.ToString() + "Loaded to Server"); IMyEntity entity = player.Controller.ControlledEntity.Entity; entity = GetCharacterEntity(entity); // //MyAPIGateway.Utilities.ShowMessage("DEBUG", "Character: " + entity.DisplayName); // gets me player name float currentModifier = 1f; float fatigueRate = 0f; bool dead = false; bool forceEating = false; float recycleBonus = 1f; bool fatigueBonus = false; bool hungerBonus = false; bool thirstBonus = false; // if we were under the effects of a bonus, keep it until we no longer are fatigueBonus = playerData.fatigue > Config.MaxValue; thirstBonus = playerData.thirst > Config.MaxValue; hungerBonus = playerData.hunger > Config.MaxValue; if (entity is IMyCharacter) { character = entity.GetObjectBuilder() as MyObjectBuilder_Character; //MyAPIGateway.Utilities.ShowMessage("DEBUG", "State: " + character.MovementState); if (playerData.Entity == null || playerData.Entity.Closed || playerData.Entity.EntityId != entity.EntityId) { bool bReset = false; if (!playerData.loaded) { bReset = true; playerData.loaded = true; } else if ((playerData.Entity != null) && (playerData.Entity != entity)) { bReset = true; } if (bReset) { playerData.hunger = Config.StartingHunger; playerData.thirst = Config.StartingThirst; playerData.fatigue = Config.StartingFatigue; } playerData.Entity = entity; } //MyAPIGateway.Utilities.ShowMessage("DEBUG", "State: " + character.MovementState + ":" + playerData.LastMovement); ChangedStance = playerData.LastMovement != character.MovementState; curmove = character.MovementState; switch (character.MovementState) // this should be all of them.... { case MyCharacterMovementEnum.Sitting: IMyCubeBlock cb = player.Controller.ControlledEntity.Entity as IMyCubeBlock; //cb.DisplayNameText is name of individual block, cb.DefinitionDisplayNameText is name of block type currentModifier = Config.DefaultModifier; fatigueRate = Config.FatigueSitting; // special case: we may be interacting with a bed, a lunchroom seat or treadmill, so let's String seatmodel = cb.DefinitionDisplayNameText.ToLower(); String seatname = cb.DisplayNameText.ToLower(); if (seatmodel.Contains("cryo")) // you're in a cryopd not an oxygen bed { currentModifier = 0.0000125f; fatigueRate = 0.0000125f; } else if (seatmodel.Contains("treadmill")) { currentModifier = RUNNING_MODIFIER; // jog... fatigueRate = FATIGUE_RUNNING / 2.5f; // but pace yourself } else if (seatmodel.Contains("bed") || seatmodel.Contains("bunk")) { currentModifier = DEFAULT_MODIFIER / 2f; // nap time! Needs are reduced. fatigueRate = FATIGUE_SITTING * 3f; // nap time! Rest is greatly sped up. fatigueBonus |= !ChangedStance; // longer nap? OK, allow for extra resting } else if (seatmodel.Contains("toilet") && ChangedStance) { forceEating = true; // also forces defecation, so this makes sense. but use changedstance to do it only once. recycleBonus = 1.5f; } else if (seatname.Contains("noms")) { forceEating = true; // also forces crapping, fortunately the suit takes care of it. Eat continuously while sitting. hungerBonus |= playerData.hunger > Config.MaxValue * 0.99; // get to 100% first, then apply bonus. thirstBonus |= playerData.thirst > Config.MaxValue * 0.99; // get to 100% first, then apply bonus. } break; case MyCharacterMovementEnum.Flying: currentModifier = FLYING_MODIFIER; fatigueRate = FATIGUE_FLYING; // operating a jetpack is surprisingly hard break; case MyCharacterMovementEnum.Falling: currentModifier = FLYING_MODIFIER; fatigueRate = FATIGUE_WALKING; // change nothing for the first iteration (prevents jump exploit) if (!ChangedStance) { fatigueRate = FATIGUE_STANDING; // freefall is actually relaxing when you are used to it. A professional space engineer would be. } break; case MyCharacterMovementEnum.Crouching: case MyCharacterMovementEnum.CrouchRotatingLeft: case MyCharacterMovementEnum.CrouchRotatingRight: currentModifier = DEFAULT_MODIFIER; fatigueRate = FATIGUE_CROUCHING; break; case MyCharacterMovementEnum.Standing: case MyCharacterMovementEnum.RotatingLeft: case MyCharacterMovementEnum.RotatingRight: currentModifier = DEFAULT_MODIFIER; fatigueRate = FATIGUE_STANDING; break; case MyCharacterMovementEnum.CrouchWalking: case MyCharacterMovementEnum.CrouchBackWalking: case MyCharacterMovementEnum.CrouchStrafingLeft: case MyCharacterMovementEnum.CrouchStrafingRight: case MyCharacterMovementEnum.CrouchWalkingRightFront: case MyCharacterMovementEnum.CrouchWalkingRightBack: case MyCharacterMovementEnum.CrouchWalkingLeftFront: case MyCharacterMovementEnum.CrouchWalkingLeftBack: currentModifier = RUNNING_MODIFIER; fatigueRate = FATIGUE_RUNNING; // doing the duckwalk is more tiring than walking: try it if you don't believe me break; case MyCharacterMovementEnum.Walking: case MyCharacterMovementEnum.BackWalking: case MyCharacterMovementEnum.WalkStrafingLeft: case MyCharacterMovementEnum.WalkStrafingRight: case MyCharacterMovementEnum.WalkingRightFront: case MyCharacterMovementEnum.WalkingRightBack: case MyCharacterMovementEnum.WalkingLeftFront: case MyCharacterMovementEnum.WalkingLeftBack: currentModifier = DEFAULT_MODIFIER; fatigueRate = FATIGUE_WALKING; break; case MyCharacterMovementEnum.LadderUp: currentModifier = RUNNING_MODIFIER; fatigueRate = FATIGUE_RUNNING; break; case MyCharacterMovementEnum.LadderDown: currentModifier = DEFAULT_MODIFIER; fatigueRate = FATIGUE_WALKING; break; case MyCharacterMovementEnum.Running: case MyCharacterMovementEnum.Backrunning: case MyCharacterMovementEnum.RunStrafingLeft: case MyCharacterMovementEnum.RunStrafingRight: case MyCharacterMovementEnum.RunningRightFront: case MyCharacterMovementEnum.RunningRightBack: case MyCharacterMovementEnum.RunningLeftBack: case MyCharacterMovementEnum.RunningLeftFront: currentModifier = RUNNING_MODIFIER; fatigueRate = FATIGUE_RUNNING; break; case MyCharacterMovementEnum.Sprinting: case MyCharacterMovementEnum.Jump: currentModifier = SPRINTING_MODIFIER; fatigueRate = FATIGUE_SPRINTING; break; case MyCharacterMovementEnum.Died: currentModifier = DEFAULT_MODIFIER; // unused, but let's have them fatigueRate = FATIGUE_STANDING; // unused, but let's have them dead = true; // for death recovery logic break; } playerData.LastMovement = character.MovementState; // track delta } else if (playerData.Entity != null || !playerData.Entity.Closed) { entity = playerData.Entity; } // Sanity checks if (hungerBonus) { if (playerData.hunger > Config.MaxValue * FOOD_BONUS) { playerData.hunger = Config.MaxValue * FOOD_BONUS; } } else { if (playerData.hunger > Config.MaxValue) { playerData.hunger = Config.MaxValue; } } if (thirstBonus) { if (playerData.thirst > Config.MaxValue * DRINK_BONUS) { playerData.thirst = Config.MaxValue * DRINK_BONUS; } } else { if (playerData.thirst > Config.MaxValue) { playerData.thirst = Config.MaxValue; } } // Cause needs if (FATIGUE_ENABLED) { playerData.fatigue += (fatigueRate * FOOD_LOGIC_SKIP_TICKS / 60 * 20); // / 15); playerData.fatigue = Math.Max(playerData.fatigue, MIN_VALUE); if (fatigueBonus) { playerData.fatigue = Math.Min(playerData.fatigue, Config.MaxValue * REST_BONUS); } else { playerData.fatigue = Math.Min(playerData.fatigue, Config.MaxValue); } } else { playerData.fatigue = 9001f; } if (playerData.fatigue <= 0) { // fatigue consequences // at 0, start causing extra thirst // at specified, force walk instead of run (unless overriding by sprinting) // at specified, force crouch, and do damage flashes // at specified, breathing reflex / mess with helmet, and do a bit of actual damage (just in case thirst isn't already causing it) // at specified, cause heart attack if (playerData.fatigue <= (0.00f * MIN_VALUE)) { if (EXTRA_THIRST_FROM_FATIGUE > 0) { // positive: pile on to thirst, per second playerData.thirst -= (EXTRA_THIRST_FROM_FATIGUE * FOOD_LOGIC_SKIP_TICKS / 60); } else // negative: multiply modifier { currentModifier *= -EXTRA_THIRST_FROM_FATIGUE; } } if (playerData.fatigue <= (FATIGUE_LEVEL_FORCEWALK * MIN_VALUE)) { // force player to walk if they were running switch (curmove) { case MyCharacterMovementEnum.Sprinting: case MyCharacterMovementEnum.Running: case MyCharacterMovementEnum.Backrunning: case MyCharacterMovementEnum.RunStrafingLeft: case MyCharacterMovementEnum.RunStrafingRight: case MyCharacterMovementEnum.RunningRightFront: case MyCharacterMovementEnum.RunningRightBack: case MyCharacterMovementEnum.RunningLeftBack: case MyCharacterMovementEnum.RunningLeftFront: VRage.Game.ModAPI.Interfaces.IMyControllableEntity ce = player.Controller.ControlledEntity.Entity as VRage.Game.ModAPI.Interfaces.IMyControllableEntity; ce.SwitchWalk(); break; } } if (playerData.fatigue <= (FATIGUE_LEVEL_FORCECROUCH * MIN_VALUE)) { bool iscrouching = false; switch (curmove) { case MyCharacterMovementEnum.Crouching: case MyCharacterMovementEnum.CrouchWalking: case MyCharacterMovementEnum.CrouchBackWalking: case MyCharacterMovementEnum.CrouchStrafingLeft: case MyCharacterMovementEnum.CrouchStrafingRight: case MyCharacterMovementEnum.CrouchWalkingRightFront: case MyCharacterMovementEnum.CrouchWalkingRightBack: case MyCharacterMovementEnum.CrouchWalkingLeftFront: case MyCharacterMovementEnum.CrouchWalkingLeftBack: iscrouching = true; break; } if (!iscrouching) { VRage.Game.ModAPI.Interfaces.IMyControllableEntity ce = player.Controller.ControlledEntity.Entity as VRage.Game.ModAPI.Interfaces.IMyControllableEntity; ce.Crouch(); // force player to crouch } } if (playerData.fatigue <= (FATIGUE_LEVEL_HELMET * MIN_VALUE)) { VRage.Game.ModAPI.Interfaces.IMyControllableEntity ce = player.Controller.ControlledEntity.Entity as VRage.Game.ModAPI.Interfaces.IMyControllableEntity; ce.SwitchHelmet(); // force player to switch helmet, panic reaction from trying to catch breath var destroyable = entity as IMyDestroyableObject; destroyable.DoDamage(0.001f, MyStringHash.GetOrCompute("Fatigue"), true); // starting to hurt } if (playerData.fatigue <= (FATIGUE_LEVEL_NOHEALING * MIN_VALUE)) { var destroyable = entity as IMyDestroyableObject; destroyable.DoDamage(0.001f, MyStringHash.GetOrCompute("Fatigue"), true); // starting to hurt if (IsAutohealingOn) // fatigued? no autohealing, either. { const float HealthTick = 100f / 240f * FOOD_LOGIC_SKIP_TICKS / 60f; destroyable.DoDamage(HealthTick, MyStringHash.GetOrCompute("Testing"), false); } } if (playerData.fatigue <= (FATIGUE_LEVEL_HEARTATTACK * MIN_VALUE)) { var destroyable = entity as IMyDestroyableObject; destroyable.DoDamage(1000f, MyStringHash.GetOrCompute("Fatigue"), true); // sudden, but very avoidable, heart attack ;) } } if (playerData.thirst > MIN_VALUE) { playerData.thirst -= elapsedMinutes * mThirstPerMinute * currentModifier; playerData.thirst = Math.Max(playerData.thirst, MIN_VALUE); } if (playerData.hunger > MIN_VALUE) { playerData.hunger -= elapsedMinutes * mHungerPerMinute * currentModifier; playerData.hunger = Math.Max(playerData.hunger, MIN_VALUE); } // Try to meet needs if (playerData.hunger < (Config.MaxValue * HUNGRY_WHEN) || forceEating) { playerEatSomething(entity, playerData, hungerBonus?Config.MaxValue * 1.25f:Config.MaxValue, recycleBonus); } if (playerData.thirst < (Config.MaxValue * THIRSTY_WHEN) || forceEating) { playerDrinkSomething(entity, playerData, thirstBonus?Config.MaxValue * 1.25f:Config.MaxValue, recycleBonus); } // Cause damage if needs are unmet if (playerData.thirst <= 0) { var destroyable = entity as IMyDestroyableObject; if (DAMAGE_SPEED_THIRST > 0) { destroyable.DoDamage((IsAutohealingOn ? (DAMAGE_SPEED_THIRST + 1f) : DAMAGE_SPEED_THIRST), MyStringHash.GetOrCompute("Thirst"), true); } else { destroyable.DoDamage(((IsAutohealingOn ? (-DAMAGE_SPEED_THIRST + 1f) : -DAMAGE_SPEED_THIRST) + DAMAGE_SPEED_THIRST * playerData.thirst), MyStringHash.GetOrCompute("Thirst"), true); } } if (playerData.hunger <= 0) { var destroyable = entity as IMyDestroyableObject; if (DAMAGE_SPEED_HUNGER > 0) { destroyable.DoDamage((IsAutohealingOn ? (DAMAGE_SPEED_HUNGER + 1f) : DAMAGE_SPEED_HUNGER), MyStringHash.GetOrCompute("Hunger"), true); } else { destroyable.DoDamage(((IsAutohealingOn ? (-DAMAGE_SPEED_HUNGER + 1f) : -DAMAGE_SPEED_HUNGER) + DAMAGE_SPEED_HUNGER * playerData.hunger), MyStringHash.GetOrCompute("Hunger"), true); } } /* * * * character = entity.GetObjectBuilder(false) as MyObjectBuilder_Character; * if (character.Health == null) // ok, so the variable exists, but it's always null for some reason? * CurPlayerHealth = 101f; * else * CurPlayerHealth = (float) (character.Health); * * if (IsAutohealingOn && CurPlayerHealth < 70f) * { * const float HealthTick = 100f / 240f * FOOD_LOGIC_SKIP_TICKS / 60f; * var destroyable = entity as IMyDestroyableObject; * destroyable.DoDamage(HealthTick, MyStringHash.GetOrCompute("Testing"), false); * } */ if (dead && DEATH_RECOVERY > 0.0) { MyInventoryBase inventory = ((MyEntity)entity).GetInventoryBase(); if (playerData.hunger > 0) { inventory.AddItems((MyFixedPoint)((1f / Config.MaxValue) * DEATH_RECOVERY * (playerData.hunger)), new MyObjectBuilder_Ore() { SubtypeName = "Organic" }); } if (playerData.thirst > 0) { inventory.AddItems((MyFixedPoint)((1f / Config.MaxValue) * DEATH_RECOVERY * (playerData.thirst)), new MyObjectBuilder_Ingot() { SubtypeName = "GreyWater" }); } } //Sends data from Server.cs to Client.cs string message = MyAPIGateway.Utilities.SerializeToXML <PlayerData>(playerData); Logging.Instance.WriteLine(("Message sent from Server.cs to Client.cs: " + message)); MyAPIGateway.Multiplayer.SendMessageTo( 1337, Encoding.Unicode.GetBytes(message), player.SteamUserId ); } } // Reinitialize the timer mTimer = new MyGameTimer(); }
private static bool playerDrinkSomething(IMyEntity entity, PlayerData playerData, float maxval_cap, float crapbonus) { MyInventoryBase inventory = ((MyEntity)entity).GetInventoryBase(); var items = inventory.GetItems(); foreach (IMyInventoryItem item in items) { float result; // Getting the item type string szItemContent = item.Content.ToString(); //MyAPIGateway.Utilities.ShowMessage("DEBUG", "szItemContent: " + item.Content.SubtypeName); string szTypeName = szItemContent.Substring(szItemContent.IndexOf(OBJECT_BUILDER_PREFIX) + OBJECT_BUILDER_PREFIX.Length); // Type verification if (!szTypeName.Equals("Ingot")) { continue; } if (mBeverageTypes.TryGetValue(item.Content.SubtypeName, out result)) { float canConsumeNum = Math.Min(((maxval_cap - playerData.thirst) / result), (float)item.Amount); //MyAPIGateway.Utilities.ShowMessage("DEBUG", "canDrink: " + canConsumeNum); if (canConsumeNum > 0) { inventory.Remove(item, (MyFixedPoint)canConsumeNum); playerData.thirst += result * (float)canConsumeNum; if (item.Content.SubtypeName.Contains("offee")) // TODO parametrize this { playerData.fatigue = Config.MaxValue; // TODO parametrize this } if (item.Content.SubtypeName.Contains("ouillon")) // TODO parametrize this { playerData.hunger += Math.Max(0f, Math.Min(result * (float)canConsumeNum, maxval_cap - playerData.hunger)); // TODO parametrize this } // waste management line if (CRAP_AMOUNT > 0.0) { inventory.AddItems((MyFixedPoint)(canConsumeNum * CRAP_AMOUNT * crapbonus), new MyObjectBuilder_Ingot() { SubtypeName = "GreyWater" }); if (CROSS_CRAP_AMOUNT > 0.0) { inventory.AddItems((MyFixedPoint)(canConsumeNum * (1 - CRAP_AMOUNT) * CROSS_CRAP_AMOUNT), new MyObjectBuilder_Ore() { SubtypeName = "Organic" }); } } return(true); } } } return(false); }
public static bool Apply <TInstance>(MyInventoryBase items, ListReader <ImmutableInventoryAction> actions, LuckyLoot.LootContext?luckContext = null, ActionWithArg <TInstance, ImmutableInventoryAction>?errorReporter = null) { var luck = luckContext ?? LuckyLoot.DefaultLoot; var success = true; foreach (var action in actions) { switch (action.Mode) { case ImmutableInventoryAction.InventoryActionMode.GiveTakeItem: { if (action.Amount > 0) { success = action.TargetId.TypeId == typeof(MyObjectBuilder_ItemTagDefinition) ? items.AddItemsWithTag(action.TargetId.SubtypeId, action.Amount) : items.AddItems(action.TargetId, action.Amount); } else { success = action.TargetId.TypeId == typeof(MyObjectBuilder_ItemTagDefinition) ? items.RemoveItemsWithTag(action.TargetId.SubtypeId, -action.Amount) : items.RemoveItems(action.TargetId, -action.Amount); } break; } case ImmutableInventoryAction.InventoryActionMode.RepairDamageItem: { var remaining = action.Amount; if (action.TargetId.TypeId == typeof(MyObjectBuilder_ItemTagDefinition)) { foreach (var item in items.Items) { if (item is MyDurableItem durable && item.HasTag(action.TargetId.SubtypeId)) { ApplyDurability(durable, ref remaining); if (durable.Durability == 0) { var broken = durable.GetDefinition().BrokenItem; var amount = item.Amount; if (!items.Remove(item)) { break; } if (broken.HasValue && !items.AddItems(broken.Value, amount)) { break; } } if (remaining == 0) { break; } } } } else { foreach (var item in items.Items) { if (item is MyDurableItem durable && item.DefinitionId == action.TargetId) { ApplyDurability(durable, ref remaining); if (durable.Durability == 0) { var broken = durable.GetDefinition().BrokenItem; var amount = item.Amount; if (!items.Remove(item)) { break; } if (broken.HasValue && !items.AddItems(broken.Value, amount)) { break; } } if (remaining == 0) { break; } } } } success = remaining == 0; break; } case ImmutableInventoryAction.InventoryActionMode.GiveTakeLootTable: { using (ItemCollection.Borrow(out var tmp)) { using (PoolManager.Get(out HashSet <MyStringHash> tmpSet)) { var table = MyDefinitionManager.Get <MyLootTableDefinition>(action.TargetId); for (var pass = 0; pass < Math.Abs(action.Amount); pass++) { tmpSet.Clear(); tmp.GenerateLuckyContent(table, luck, tmpSet); } } if (action.Amount > 0) { foreach (var item in tmp.Items) { success &= items.Add(item); } } else { foreach (var item in tmp.Items) { success &= items.RemoveItems(item.DefinitionId, item.Amount); } } } break; } default: throw new Exception("Bad mode"); } if (!success) { errorReporter?.Invoke(action); return(false); } } return(success); }
/// <summary> /// Moves items with the given flags from the construction inventory to the character. /// If the flags are None, all items are moved. /// </summary> public void MoveItemsFromConstructionStockpile(MyInventoryBase toInventory, MyItemFlags flags = MyItemFlags.None) { if (m_stockpile == null) return; Debug.Assert(toInventory != null); if (toInventory == null) return; m_tmpItemList.Clear(); foreach (var item in m_stockpile.GetItems()) { if (flags == MyItemFlags.None || (item.Content.Flags & flags) != 0) m_tmpItemList.Add(item); } m_stockpile.ClearSyncList(); foreach (var item in m_tmpItemList) { // If the item is just some component that is represented by another components, use the first // ME Example: ScrapWoodComponent has representation as ScrapWood or ScrapWoodBranches MyComponentSubstitutionDefinition substitution; if (MyDefinitionManager.Static.TryGetComponentSubstitutionDefinition(item.Content.GetId(), out substitution)) { Debug.Assert(substitution.ProvidingComponents.Count > 0, "Invalid component substitution definition for: " + item.Content.GetId().ToString()); MyDefinitionId componentId = item.Content.GetId(); int componentAmount = (int)item.Amount; MyObjectBuilder_Base itemBuilder = item.Content; if (substitution.ProvidingComponents.Count > 0) { componentId = substitution.ProvidingComponents.First().Key; componentAmount = componentAmount * substitution.ProvidingComponents.First().Value; itemBuilder = MyObjectBuilderSerializer.CreateNewObject(componentId); } var amount = (int)toInventory.ComputeAmountThatFits(componentId); amount = Math.Min(amount, componentAmount); toInventory.AddItems(amount, itemBuilder); var removedAmount = amount; if (substitution.ProvidingComponents.Count > 0) { removedAmount = removedAmount / substitution.ProvidingComponents.First().Value; } m_stockpile.RemoveItems(amount, item.Content); } else { var amount = (int)toInventory.ComputeAmountThatFits(item.Content.GetId()); amount = Math.Min(amount, item.Amount); toInventory.AddItems(amount, item.Content); m_stockpile.RemoveItems(amount, item.Content); } } CubeGrid.SyncObject.SendStockpileChanged(this, m_stockpile.GetSyncList()); m_stockpile.ClearSyncList(); }