private void ServerRemote_Install(IItem itemToInstall, byte slotId) { var character = ServerRemoteContext.Character; var worldObject = InteractionCheckerSystem.GetCurrentInteraction(character); this.VerifyGameObject((IStaticWorldObject)worldObject); var containerEquipment = character.SharedGetPlayerContainerEquipment(); var currentInstalledItem = containerEquipment.GetItemAtSlot(slotId); if (currentInstalledItem != null) { if (currentInstalledItem == itemToInstall) { Logger.Info("The implant is already installed"); return; } throw new Exception("Please uninstall installed implant"); } if (itemToInstall.Container.OwnerAsCharacter != character || itemToInstall.Container == containerEquipment) { throw new Exception("The item to install must be in character containers (except equipment)"); } if (!containerEquipment.ProtoItemsContainer.CanAddItem( new CanAddItemContext(containerEquipment, itemToInstall, slotId, byCharacter: null, isExploratoryCheck: false))) { throw new Exception("Cannot install implant item there"); } var itemToInstallProto = (IProtoItemEquipmentImplant)itemToInstall.ProtoItem; if (itemToInstallProto is ItemImplantBroken) { throw new Exception("Cannot install broken implant"); } foreach (var equippedItem in containerEquipment.Items) { if (equippedItem.ProtoItem == itemToInstallProto) { throw new Exception("Another implant of this type is already installed: " + itemToInstallProto); } } var biomaterialRequiredAmount = CreativeModeSystem.SharedIsInCreativeMode(character) ? (ushort)0 : itemToInstallProto.BiomaterialAmountRequiredToInstall; if (!character.ContainsItemsOfType(ProtoItemBiomaterialVial.Value, requiredCount: biomaterialRequiredAmount)) { throw new Exception("Not enough biomaterial vials"); } if (!Server.Items.MoveOrSwapItem(itemToInstall, containerEquipment, out _, slotId: slotId)) { throw new Exception("Unknown error - cannot move implant item to the player equipment"); } if (biomaterialRequiredAmount > 0) { // destroy vials Server.Items.DestroyItemsOfType(character, ProtoItemBiomaterialVial.Value, countToDestroy: biomaterialRequiredAmount, out _); NotificationSystem.ServerSendItemsNotification( character, ProtoItemBiomaterialVial.Value, -biomaterialRequiredAmount); } Logger.Info("Implant installed: " + itemToInstall); }
private void ServerRemote_Uninstall(byte slotId) { var character = ServerRemoteContext.Character; var worldObject = InteractionCheckerSystem.GetCurrentInteraction(character); this.VerifyGameObject((IStaticWorldObject)worldObject); var itemToUninstall = character.SharedGetPlayerContainerEquipment() .GetItemAtSlot(slotId); if (itemToUninstall == null) { throw new Exception("No implant installed"); } var itemToUninstallProto = (IProtoItemEquipmentImplant)itemToUninstall.ProtoItem; var biomaterialRequiredAmount = CreativeModeSystem.SharedIsInCreativeMode(character) ? (ushort)0 : itemToUninstallProto.BiomaterialAmountRequiredToUninstall; if (!character.ContainsItemsOfType(ProtoItemBiomaterialVial.Value, requiredCount: biomaterialRequiredAmount) && !CreativeModeSystem.SharedIsInCreativeMode(character)) { throw new Exception("Not enough biomaterial vials"); } // move to inventory if (!Server.Items.MoveOrSwapItem(itemToUninstall, character.SharedGetPlayerContainerInventory(), out _)) { NotificationSystem.ServerSendNotificationNoSpaceInInventory(character); return; } if (biomaterialRequiredAmount > 0) { // destroy vials Server.Items.DestroyItemsOfType(character, ProtoItemBiomaterialVial.Value, countToDestroy: biomaterialRequiredAmount, out _); NotificationSystem.ServerSendItemsNotification( character, ProtoItemBiomaterialVial.Value, -biomaterialRequiredAmount); } if (itemToUninstallProto is ItemImplantBroken) { // broken implant destroys on uninstall Server.Items.DestroyItem(itemToUninstall); NotificationSystem.ServerSendItemsNotification( character, itemToUninstallProto, -1); } Logger.Info("Implant uninstalled: " + itemToUninstall); }
private async void ClientInteractStartAsync(IStaticWorldObject worldObject) { if (this.isAwaitingServerInteraction) { return; } var character = Client.Characters.CurrentPlayerCharacter; if (InteractionCheckerSystem.GetCurrentInteraction(character) == worldObject) { // already interacting with this object return; } this.isAwaitingServerInteraction = true; try { var requestId = ++lastRequestId; var isOpened = await this.CallServer(_ => _.ServerRemote_OnClientInteractStart(worldObject)); if (!isOpened || requestId != lastRequestId) { return; } } finally { this.isAwaitingServerInteraction = false; } var menuWindow = SharedGetProto(worldObject).ClientOpenUI(worldObject); if (menuWindow == null) { Logger.Important("Cannot open menu for object interaction with " + worldObject); this.CallServer(_ => _.ServerRemote_OnClientInteractFinish(worldObject)); return; } ClientCurrentInteractionMenu.RegisterMenuWindow(menuWindow); InteractionCheckerSystem.Register( character, worldObject, finishAction: _ => menuWindow.CloseWindow()); ClientInteractionUISystem.Register( worldObject, menuWindow, onMenuClosedByClient: () => { InteractionCheckerSystem.Unregister(character, worldObject, isAbort: false); if (!worldObject.IsDestroyed) { ++lastRequestId; this.CallServer(_ => _.ServerRemote_OnClientInteractFinish(worldObject)); } }); Logger.Important("Started object interaction with " + worldObject); ClientCurrentInteractionMenu.Open(); }