protected override void SharedOnActionCompletedInternal(BottleRefillAction state, ICharacter character) { var itemBottle = state.ItemEmptyBottle; var requiredWaterProtoTile = state.WaterProtoTileToRefill; if (requiredWaterProtoTile == null) { throw new Exception("Impossible"); } if (IsClient) { return; } var isNeedToReduceItemCount = true; if (itemBottle.Count == 1) { // destroy last item isNeedToReduceItemCount = false; Server.Items.SetCount(itemBottle, count: 0, byCharacter: character); } // spawn filled bottle item var result = requiredWaterProtoTile is TileWaterSea ? Server.Items.CreateItem <ItemBottleWaterSalty>(character) : Server.Items.CreateItem <ItemBottleWaterStale>(character); if (!result.IsEverythingCreated) { result.Rollback(); NotificationSystem.ServerSendNotificationNoSpaceInInventory(character); return; } if (isNeedToReduceItemCount) { // reduce item count Server.Items.SetCount(itemBottle, itemBottle.Count - 1, byCharacter: character); } var itemsChangedCount = NotificationSystem.SharedGetItemsChangedCount(result); this.CallClient(character, _ => _.ClientRemote_ActionCompleted(itemsChangedCount)); }
protected override void SharedOnActionCompletedInternal(BottleRefillAction state, ICharacter character) { var itemBottle = state.ItemEmptyBottle; var requiredWaterProtoTile = state.WaterProtoTileToRefill; if (requiredWaterProtoTile is null) { throw new Exception("Impossible"); } if (IsClient) { return; } // destroy the empty bottle item stack var itemsContainer = itemBottle.Container; var countToSpawn = itemBottle.Count; var containerSlotId = itemBottle.ContainerSlotId; Server.Items.SetCount(itemBottle, count: 0, byCharacter: character); // spawn a filled bottle item stack in place of the destroyed empty bottle item stack var protoItemFilledBottle = SharedGetFilledBottlePrototype(requiredWaterProtoTile); if (protoItemFilledBottle is null) { throw new Exception("Should be impossible"); } var result = Server.Items.CreateItem(protoItemFilledBottle, itemsContainer, countToSpawn, containerSlotId); var itemsChangedCount = NotificationSystem.SharedGetItemsChangedCount(result); this.CallClient(character, _ => _.ClientRemote_ActionCompleted(itemsChangedCount)); }
private void ServerGatheringSystemGatherHandler(ICharacter character, IStaticWorldObject worldObject) { if (!(worldObject.ProtoStaticWorldObject is ObjectCorpse)) { return; } // corpse looted // find the device and vial var itemDevice = character.SharedGetPlayerContainerEquipment() .GetItemsOfProto(this) .FirstOrDefault(); if (itemDevice is null) { // don't have an equipped device return; } var protoItemVialEmpty = GetProtoEntity <ItemVialEmpty>(); // require at least one vial if (!character.ContainsItemsOfType(protoItemVialEmpty, requiredCount: 1)) { // don't have an empty vial this.CallClient(character, _ => _.ClientRemote_NotEnoughEmptyVials()); return; } var protoMob = worldObject.GetPublicState <ObjectCorpse.PublicState>() .ProtoCharacterMob; var healthMax = protoMob.StatDefaultHealthMax; var maxVialsToUse = (ushort)MathHelper.Clamp( Math.Floor(protoMob.BiomaterialValueMultiplier * healthMax / 100.0), min: 1, max: 10); // destroy empty vial Server.Items.DestroyItemsOfType( character, protoItemVialEmpty, maxVialsToUse, out var destroyedEmptyVialsCount); if (destroyedEmptyVialsCount == 0) { // cannot destroy any empty vial (should be impossible) return; } // spawn biomaterial vials var protoItemVialBiomaterial = Api.GetProtoEntity <ItemVialBiomaterial>(); var createItemResult = Server.Items.CreateItem(protoItemVialBiomaterial, character, count: destroyedEmptyVialsCount); if (!createItemResult.IsEverythingCreated) { createItemResult.Rollback(); var groundItemsContainer = ObjectGroundItemsContainer.ServerTryGetOrCreateGroundContainerAtTileOrNeighbors(character, character.Tile); if (groundItemsContainer is null) { Logger.Error("Not enough space around the player to drop a full vial"); // restore items Server.Items.CreateItem(protoItemVialEmpty, character, destroyedEmptyVialsCount); return; } createItemResult = Server.Items.CreateItem(protoItemVialBiomaterial, groundItemsContainer, count: destroyedEmptyVialsCount); if (!createItemResult.IsEverythingCreated) { createItemResult.Rollback(); Logger.Error("Not enough space around the player to drop a full vial"); // restore items Server.Items.CreateItem(protoItemVialEmpty, character, destroyedEmptyVialsCount); return; } NotificationSystem.ServerSendNotificationNoSpaceInInventoryItemsDroppedToGround(character, protoItemVialBiomaterial); } var itemChangedCount = NotificationSystem.SharedGetItemsChangedCount(createItemResult); itemChangedCount.Add(protoItemVialEmpty, -(int)destroyedEmptyVialsCount); NotificationSystem.ServerSendItemsNotification(character, itemChangedCount); ItemDurabilitySystem.ServerModifyDurability(itemDevice, -DurabilityDecreasePerUse); Logger.Info("Biomaterial collected successfully with Biomaterial collector", character); }
private void ServerGatheringSystemGatherHandler(ICharacter character, IStaticWorldObject worldObject) { if (!(worldObject.ProtoStaticWorldObject is ObjectCorpse)) { return; } // corpse gathered! // find the device and vial var itemDevice = character.SharedGetPlayerContainerEquipment() .GetItemsOfProto(this) .FirstOrDefault(); if (itemDevice == null) { // don't have an equipped device return; } var protoItemVialEmpty = GetProtoEntity <ItemVialEmpty>(); // require at least one vial if (!character.ContainsItemsOfType(protoItemVialEmpty, requiredCount: 1)) { // don't have an empty vial this.CallClient(character, _ => _.ClientRemote_NotEnoughEmptyVials()); return; } var protoMob = (IProtoCharacterCore)worldObject.GetPublicState <ObjectCorpse.PublicState>() .ProtoCharacterMob; var healthMax = protoMob.StatDefaultHealthMax; var maxVialsToUse = (ushort)MathHelper.Clamp(Math.Floor(healthMax / 100.0), min: 1, max: 10); // destroy empty vial Server.Items.DestroyItemsOfType( character, protoItemVialEmpty, maxVialsToUse, out var destroyedEmptyVialsCount); if (destroyedEmptyVialsCount == 0) { // cannot destroy any empty vial (should be impossible) return; } // spawn biomaterial vials var createItemResult = Server.Items.CreateItem <ItemVialBiomaterial>(character, count: destroyedEmptyVialsCount); var itemChangedCount = NotificationSystem.SharedGetItemsChangedCount(createItemResult); itemChangedCount.Add(protoItemVialEmpty, -(int)destroyedEmptyVialsCount); NotificationSystem.ServerSendItemsNotification(character, itemChangedCount); ItemDurabilitySystem.ServerModifyDurability(itemDevice, -DurabilityDecreasePerUse); Logger.Info("Biomaterial collected successfully with Biomaterial collector", character); }