/// <param name="accessor"></param> /// <param name="item">The item to transfer</param> /// <param name="source">The source inventory</param> /// <param name="destination">The destination inventory</param> /// <param name="stacks">How many stacks to move. Use -1 to specify 'all' stacks</param> /// <param name="destinationCapacity">The capacity of the destination inventory</param> private static ItemTransactionResult ExecuteItemTransaction_Internal(ISimGameWorldReadWriteAccessor accessor, ref ItemTransationData data) { if (data.Stacks == 0) { return(new ItemTransactionResult(stackTransfered: 0)); } if (data.Stacks < 0) // invert source and destination ? { var temp1 = data.SourceBuffer; var temp2 = data.SourceCapacity; data.SourceBuffer = data.DestinationBuffer; data.SourceCapacity = data.DestinationCapacity; data.DestinationBuffer = temp1; data.DestinationCapacity = temp2; data.Stacks = -data.Stacks; } if (!accessor.Exists(data.Item)) { return(new ItemTransactionResult(ItemTransactionResultType.Failed_BadTransationRequest)); } if (data.SourceBuffer != null && !data.SourceBuffer.Value.IsCreated) { return(new ItemTransactionResult(ItemTransactionResultType.Failed_SourceInvalid)); } if (data.DestinationBuffer != null && !data.DestinationBuffer.Value.IsCreated) { return(new ItemTransactionResult(ItemTransactionResultType.Failed_DestinationInvalid)); } if (!accessor.HasComponent <SimAssetId>(data.Item)) { return(new ItemTransactionResult(ItemTransactionResultType.Failed_ItemHasNoSimAssetId)); } var itemAssetId = accessor.GetComponent <SimAssetId>(data.Item); var sourceIndex = -1; var destinationIndex = -1; var itemStackable = accessor.GetComponent <StackableFlag>(data.Item); var sourceBuffer = data.SourceBuffer.GetValueOrDefault(); var destinationBuffer = data.DestinationBuffer.GetValueOrDefault(); if (sourceBuffer.IsCreated) // Find item in source { for (int i = 0; i < sourceBuffer.Length; i++) { if (accessor.TryGetComponent(sourceBuffer[i].ItemEntity, out SimAssetId assetId) && assetId == itemAssetId) { sourceIndex = i; break; } } } if (destinationBuffer.IsCreated) // Find item in destination { for (int i = 0; i < destinationBuffer.Length; i++) { if (accessor.TryGetComponent(destinationBuffer[i].ItemEntity, out SimAssetId assetId) && assetId == itemAssetId) { destinationIndex = i; break; } } } if (sourceBuffer.IsCreated && sourceIndex == -1) { return(new ItemTransactionResult(ItemTransactionResultType.Failed_ItemNotFoundInSource)); } if (destinationBuffer.IsCreated && destinationIndex == -1 && destinationBuffer.Length >= data.DestinationCapacity) { return(new ItemTransactionResult(ItemTransactionResultType.Failed_DestinationFull)); } // cap stacks if (sourceIndex >= 0) { data.Stacks = min(data.Stacks, sourceBuffer[sourceIndex].Stacks); if (data.Stacks == 0) { return(new ItemTransactionResult(ItemTransactionResultType.Failed_SourceStack0)); } } if (!itemStackable) { data.Stacks = 1; } // check unique item is not about to be added twice if (!itemStackable && destinationIndex != -1 && destinationBuffer[destinationIndex].Stacks > 0) { return(new ItemTransactionResult(ItemTransactionResultType.Failed_UniqueItemAlreadyInDestination)); } //////////////////////////////////////////////////////////////////////////////////////// // Perform Transaction //////////////////////////////////////////////////////////////////////////////////////// // Remove from source if (sourceIndex != -1) { // decrease stacks var sourceEntry = sourceBuffer[sourceIndex]; sourceEntry.Stacks -= data.Stacks; sourceBuffer[sourceIndex] = sourceEntry; if (sourceEntry.Stacks <= 0) // remove from source if 0 left { // remove from source sourceBuffer.RemoveAt(sourceIndex); // Destroy item accessor.DestroyEntity(sourceEntry.ItemEntity); UpdateBuffersAfterStructuraleChange(ref data); } } if (destinationBuffer.IsCreated) { // not found ? add new reference if (destinationIndex == -1) { // Instantiate item copy var itemCopy = accessor.Instantiate(data.Item); UpdateBuffersAfterStructuraleChange(ref data); accessor.SetComponent(itemCopy, new FirstInstigator() { Value = data.Destination.Value }); destinationBuffer.Add(new InventoryItemReference() { ItemEntity = itemCopy, Stacks = 0 }); destinationIndex = destinationBuffer.Length - 1; } // increase stacks var destinationEntry = destinationBuffer[destinationIndex]; destinationEntry.Stacks += data.Stacks; destinationBuffer[destinationIndex] = destinationEntry; } return(new ItemTransactionResult(data.Stacks)); void UpdateBuffersAfterStructuraleChange(ref ItemTransationData data) { GetBuffer(accessor, data.Source, out data.SourceBuffer); GetBuffer(accessor, data.Destination, out data.DestinationBuffer); sourceBuffer = data.SourceBuffer.GetValueOrDefault(); destinationBuffer = data.DestinationBuffer.GetValueOrDefault(); } }