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;
}
}
}