using System.Collections.Generic; using UnityEngine; using GameDevTV.Saving; using UnityEngine.SceneManagement; namespace GameDevTV.Inventories { /// /// To be placed on anything that wishes to drop pickups into the world. /// Tracks the drops for saving and restoring. /// public class ItemDropper : MonoBehaviour, ISaveable { // STATE private List droppedItems = new List(); private List otherSceneDroppedItems = new List(); // PUBLIC /// /// Create a pickup at the current position. /// /// The item type for the pickup. /// /// The number of items contained in the pickup. Only used if the item /// is stackable. /// public void DropItem(InventoryItem item, int number) { SpawnPickup(item, GetDropLocation(), number); } /// /// Create a pickup at the current position. /// /// The item type for the pickup. public void DropItem(InventoryItem item) { SpawnPickup(item, GetDropLocation(), 1); } // PROTECTED /// /// Override to set a custom method for locating a drop. /// /// The location the drop should be spawned. protected virtual Vector3 GetDropLocation() { return transform.position; } // PRIVATE public void SpawnPickup(InventoryItem item, Vector3 spawnLocation, int number) { var pickup = item.SpawnPickup(spawnLocation, number); droppedItems.Add(pickup); } [System.Serializable] private struct DropRecord { public string itemID; public SerializableVector3 position; public int number; public int sceneBuildIndex; } object ISaveable.CaptureState() { RemoveDestroyedDrops(); var droppedItemsList = new List(); int buildIndex = SceneManager.GetActiveScene().buildIndex; foreach (Pickup pickup in droppedItems) { var droppedItem = new DropRecord(); droppedItem.itemID = pickup.GetItem().GetItemID(); droppedItem.position = new SerializableVector3(pickup.transform.position); droppedItem.number = pickup.GetNumber(); droppedItem.sceneBuildIndex = buildIndex; droppedItemsList.Add(droppedItem); } droppedItemsList.AddRange(otherSceneDroppedItems); return droppedItemsList; } void ISaveable.RestoreState(object state) { var droppedItemsList = (List)state; int buildIndex = SceneManager.GetActiveScene().buildIndex; otherSceneDroppedItems.Clear(); foreach (var item in droppedItemsList) { if (item.sceneBuildIndex != buildIndex) { otherSceneDroppedItems.Add(item); continue; } var pickupItem = InventoryItem.GetFromID(item.itemID); Vector3 position = item.position.ToVector(); int number = item.number; SpawnPickup(pickupItem, position, number); } } /// /// Remove any drops in the world that have subsequently been picked up. /// private void RemoveDestroyedDrops() { var newList = new List(); foreach (var item in droppedItems) { if (item != null) { newList.Add(item); } } droppedItems = newList; } } }