private void MoveItemHere(ItemEntity item, Flags newFlag) { // get the old location stored as it'll be used in the notifications int oldLocation = item.LocationID; Flags oldFlag = item.Flag; // rig slots cannot be moved if (item.IsInRigSlot() == true) { throw new CannotRemoveUpgradeManually(); } // special situation, if the old location is a module slot ensure the item is first offlined if (item.IsInModuleSlot() == true) { if (item is ShipModule module) { if (module.Attributes[Attributes.isOnline] == 1) { module.StopApplyingEffect("online", Client); } // disable passive effects too module.StopApplyingPassiveEffects(Client); } } // extra special situation, is the new flag an autofit one? if (newFlag == Flags.AutoFit) { // capsules cannot fit anything if (this.mInventory.Type.ID == (int)Types.Capsule) { throw new CantFitToCapsule(); } if (this.mInventory is Ship ship) { // determine where to put the item if (item is ShipModule module) { if (module.IsHighSlot() == true) { newFlag = this.GetFreeHighSlot(ship); } else if (module.IsMediumSlot() == true) { newFlag = this.GetFreeMediumSlot(ship); } else if (module.IsLowSlot() == true) { newFlag = this.GetFreeLowSlot(ship); } else if (module.IsRigSlot() == true) { newFlag = this.GetFreeRigSlot(ship); } else { // this item cannot be fitted, move it to cargo, maybe throw a exception about not being able to fit it? newFlag = Flags.Cargo; } } // TODO: HANDLE CHARGES! else { newFlag = Flags.Cargo; } } else { newFlag = Flags.Hangar; } } // special situation, if the new location is a module slot ensure the item is a singleton (TODO: HANDLE CHARGES TOO) if (newFlag.IsModule() == true) { ShipModule module = null; if (item is ShipModule shipModule) { module = shipModule; } if (item.Quantity == 1) { // remove item off the old inventory if required if (this.ItemFactory.TryGetItem(item.LocationID, out ItemInventory inventory) == true) { inventory.RemoveItem(item); } OnItemChange changes = new OnItemChange(item); if (item.Singleton == false) { changes.AddChange(ItemChange.Singleton, item.Singleton); } item.LocationID = this.mInventory.ID; item.Flag = newFlag; item.Singleton = true; changes .AddChange(ItemChange.LocationID, oldLocation) .AddChange(ItemChange.Flag, (int)oldFlag); // notify the character about the change Client.NotifyMultiEvent(changes); // update meta inventories too this.ItemFactory.MetaInventoryManager.OnItemMoved(item, oldLocation, this.mInventory.ID); // finally persist the item changes item.Persist(); } else { // item is not a singleton, create a new item, decrease quantity and send notifications ItemEntity newItem = this.ItemFactory.CreateSimpleItem(item.Type, item.OwnerID, this.mInventory.ID, newFlag, 1, false, true); item.Quantity -= 1; // notify the quantity change and the new item Client.NotifyMultiEvent(OnItemChange.BuildQuantityChange(item, item.Quantity + 1)); Client.NotifyMultiEvent(OnItemChange.BuildLocationChange(newItem, Flags.None, 0)); item.Persist(); // replace reference so the following code handle things properly item = newItem; if (item is ShipModule shipModule2) { module = shipModule2; } } try { // apply all the passive effects (this also blocks the item fitting if the initialization fails) module?.ApplyPassiveEffects(Client); // extra check, ensure that the character has the required skills } catch (UserError) { // ensure that the passive effects that got applied already are removed from the item module?.StopApplyingPassiveEffects(Client); int newOldLocation = item.LocationID; Flags newOldFlag = item.Flag; // now undo the whole thing item.LocationID = oldLocation; item.Flag = oldFlag; Client.NotifyMultiEvent(OnItemChange.BuildLocationChange(item, newOldFlag, newOldLocation)); throw; } // ensure the new inventory knows this.mInventory.AddItem(item); module?.Persist(); // put the module online after fitting it as long as it's a normal module if (module?.IsRigSlot() == false) { module?.ApplyEffect("online", Client); } } else { // remove item off the old inventory if required if (this.ItemFactory.TryGetItem(item.LocationID, out ItemInventory inventory) == true) { inventory.RemoveItem(item); } // set the new location for the item item.LocationID = this.mInventory.ID; item.Flag = newFlag; // notify the character about the change Client.NotifyMultiEvent(OnItemChange.BuildLocationChange(item, oldFlag, oldLocation)); // update meta inventories too this.ItemFactory.MetaInventoryManager.OnItemMoved(item, oldLocation, this.mInventory.ID); // ensure the new inventory knows this.mInventory.AddItem(item); // finally persist the item changes item.Persist(); } }