Files
2024-11-20 15:21:28 +01:00

204 lines
6.7 KiB
C#

// Copyright (c) Pixel Crushers. All rights reserved.
using UnityEngine;
using System;
namespace PixelCrushers.QuestMachine.Demo
{
/// <summary>
/// Simple inventory script for the Quest Machine demo. This script is
/// very specific to the demo. Don't use it as a basis for a generalized
/// inventory system. However, you can examine how it implements Saver
/// to save the inventory in saved games, and how it uses the Message
/// System to handle adding and removing items.
/// </summary>
public class DemoInventory : Saver, IMessageHandler
{
public enum ItemType { Carrot = 0, Wand = 1, Coin = 2 }
public static int CarrotSlot { get { return (int)ItemType.Carrot; } }
public static int WandSlot { get { return (int)ItemType.Wand; } }
public static int CoinSlot { get { return (int)ItemType.Coin; } }
[Serializable]
public class Slot
{
public UnityEngine.UI.Button itemButton;
public UnityEngine.UI.Text countText;
public UnityEngine.UI.Text useText;
public int count;
public int maxCount = 1;
public bool usable;
}
public Slot[] slots;
public GameObject wandBarrel; // Handles barrel containing magic polymorph wand.
public EntityType wandEntityType; // Used for quest generator.
public DomainType playerInventoryDomainType; // Used for quest generator.
public int usingIndex { get; private set; }
public override void Awake()
{
base.Awake();
usingIndex = -1;
}
public override void Start()
{
base.Start();
// Tell quest generators about our inventory:
foreach (var generator in FindObjectsOfType<QuestGeneratorEntity>())
{
generator.updateWorldModel += OnUpdateWorldModel;
}
}
public override void OnEnable()
{
base.OnEnable();
ListenForMessages();
}
public override void OnDisable()
{
base.OnDisable();
MessageSystem.RemoveListener(this);
}
public void AddItem(int index)
{
ModifyItemCount(index, 1);
}
public void RemoveItem(int index)
{
ModifyItemCount(index, -1);
}
public void ModifyItemCount(int index, int delta)
{
SetItemCount(index, GetItemCount(index) + delta);
}
public void SetItemCount(int index, int count)
{
var slot = GetSlot(index);
if (slot == null) return;
slot.count = Mathf.Clamp(count, 0, slot.maxCount);
slot.itemButton.GetComponent<UnityEngine.UI.Image>().enabled = slot.count > 0;
slot.itemButton.interactable = slot.usable && slot.count > 0;
slot.countText.enabled = slot.count > 1;
slot.countText.text = slot.count.ToString();
}
public int GetItemCount(int index)
{
var slot = GetSlot(index);
return (slot != null) ? slot.count : 0;
}
public void UseItem(int index)
{
var slot = GetSlot(index);
if (slot == null) return;
var turnOn = usingIndex != index;
slot.useText.enabled = turnOn;
usingIndex = turnOn ? index : -1;
}
private Slot GetSlot(int index)
{
return (0 <= index && index < slots.Length) ? slots[index] : null;
}
private void OnUpdateWorldModel(WorldModel worldModel)
{
var hasWand = GetItemCount(WandSlot) >= 1;
if (hasWand)
{
// Player has wand, so add that fact to the world model:
worldModel.AddFact(new Fact(playerInventoryDomainType, wandEntityType, 1));
}
}
private void ListenForMessages()
{
// Listen for messages for getting and dropping items:
MessageSystem.AddListener(this, "Get", "Carrot");
MessageSystem.AddListener(this, "Get", "Wand");
MessageSystem.AddListener(this, "Get", "Coin");
MessageSystem.AddListener(this, "Drop", "Carrot");
MessageSystem.AddListener(this, "Drop", "Wand");
MessageSystem.AddListener(this, "Drop", "Coin");
MessageSystem.AddListener(this, "Activate Wand Barrel", string.Empty); // and to activate wand barrel.
}
public void OnMessage(MessageArgs messageArgs)
{
if (wandBarrel == null) return;
if (messageArgs.message == "Activate Wand Barrel")
{
// Make the wand barrel appear:
wandBarrel.GetComponent<SpriteRenderer>().enabled = true;
}
else
{
// Modify the item count:
var count = (messageArgs.firstValue != null) && (messageArgs.firstValue.GetType() == typeof(int)) ? (int)messageArgs.firstValue : 1;
if (messageArgs.message == "Drop") count = -count;
var slotIndex = GetSlotIndex(messageArgs.parameter);
ModifyItemCount(slotIndex, count);
}
}
private int GetSlotIndex(string slotType)
{
switch (slotType)
{
case "Carrot":
return CarrotSlot;
case "Wand":
return WandSlot;
case "Coin":
return CoinSlot;
default:
return -1;
}
}
[Serializable]
public class SaveData
{
public int carrots;
public int wands;
public int coins;
}
// Called by the Save System when saving a game. Returns a string
// containing data we want to include in saved games.
public override string RecordData()
{
var data = new SaveData();
data.carrots = GetItemCount(CarrotSlot);
data.wands = GetItemCount(WandSlot);
data.coins = GetItemCount(CoinSlot);
return SaveSystem.Serialize(data);
}
// Called by the Save System when loading a game. Applies the
// saved game data to the current state of this script.
public override void ApplyData(string data)
{
if (string.IsNullOrEmpty(data)) return;
var saveData = SaveSystem.Deserialize<SaveData>(data);
if (saveData == null) return;
SetItemCount(CarrotSlot, saveData.carrots);
SetItemCount(WandSlot, saveData.wands);
SetItemCount(CoinSlot, saveData.coins);
}
}
}