You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
198 lines
9.5 KiB
198 lines
9.5 KiB
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Drawing;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
using TMPro;
|
|
|
|
/// <summary>
|
|
/// This class connects a grid view for buy state of the shop to a controller to manipulate the BuyModel via a ShopController
|
|
/// interface, it contains specific methods to setup and update a grid view, with the data from a BuyModel. If you want to display
|
|
/// informationoutside of the BuyModel, for example, the money amount from the player's inventory, then you need to either keep a
|
|
/// reference to all the related models, or make this class an observer/event subscriber of the related models.
|
|
/// </summary>
|
|
public abstract class ShopView : MonoBehaviour
|
|
{
|
|
public ShopModel ShopModel => model; //A getter to access shopModel. Will access inventory of trade partner in sell mode!
|
|
|
|
[SerializeField]
|
|
protected GameObject itemPrefab; //A prefab to display an item in the view
|
|
|
|
[SerializeField]
|
|
protected Button buyButton;
|
|
|
|
[SerializeField]
|
|
protected TextMeshProUGUI instructionText;
|
|
|
|
[SerializeField] protected LayoutGroup layoutGroup; // The layout group that represents this view visually
|
|
|
|
[SerializeField] private ModelComponent ownModel; // Reference to the model this view technically belongs to
|
|
[SerializeField] private InventoryComponent tradePartner; // Reference to the model this view technically belongs to
|
|
|
|
protected ShopModel model; // Model in MVC pattern
|
|
protected ShopModel other; // Other model in MVC pattern (our own inventory)
|
|
protected ShopController shopController; //Controller in MVC pattern
|
|
|
|
private ItemType itemFilter = ItemType.All; // View can filter items, and this is the filter we want to use for that
|
|
|
|
// Set up the view's necessary stuff before the view is enabled
|
|
protected virtual void Awake()
|
|
{
|
|
//model = new BuyModel(2f, 16, 500); //Right now use magic values to set up the shop
|
|
Debug.Assert(ownModel != null,"No shop model assigned!",this);
|
|
Debug.Assert(tradePartner != null,"No trade partner assigned!",this);
|
|
model = ownModel.Model;
|
|
shopController = gameObject.AddComponent<MouseController>().Initialize(model);//Set the default controller to be the mouse controller
|
|
SetupItemIconView(); //Setup the grid view's properties
|
|
InitializeButtons(); //Connect the buttons to the controller
|
|
|
|
//model.Subscribe(this);
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
// sanity check
|
|
if (model == null) model = ownModel.Model;
|
|
RegisterMoneyObserver(); // Make sure if this thing's got a money component somewhere we register it as an observer for the inventory we're looking at
|
|
model.SetTradePartner(tradePartner.Inventory);
|
|
PopulateItemIconView(); //Display items
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
ClearIconView();
|
|
model.SetTradePartner(null);
|
|
UnregisterMoneyObserver();
|
|
}
|
|
|
|
// If view is generic, and shopview was just an implementation, this would be more flexible in theory. But for now it's enough to just manually assign "ourselves" as trade partner if we know the model works on just one inventory
|
|
private void RegisterMoneyObserver()
|
|
{
|
|
var moneyComp = GetComponentInChildren<InventoryMoneyDisplay>();
|
|
if (moneyComp != null) tradePartner.Inventory.RegisterObserver(moneyComp);
|
|
}
|
|
|
|
// Undo the above
|
|
private void UnregisterMoneyObserver()
|
|
{
|
|
var moneyComp = GetComponentInChildren<InventoryMoneyDisplay>();
|
|
if (moneyComp != null) tradePartner.Inventory.RemoveObserver(moneyComp);
|
|
}
|
|
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
// SetupItemIconView()
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
//Setup the grid view according to the ViewConfig object's requirements, right now it just sets the constraint mode and column count,
|
|
//you can make cosmetic adjustments to the GridLayoutGroup by adding more configurations to ViewConfig and use them adjusting properties
|
|
//like cellSize, spacing, padding, etc.
|
|
protected abstract void SetupItemIconView();
|
|
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
// RepopulateItems()
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
//Clears the grid view and repopulates it with new icons (updates the visible icons)
|
|
private void RepopulateItemIconView() {
|
|
ClearIconView();
|
|
PopulateItemIconView();
|
|
}
|
|
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
// PopulateItems()
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
//Adds one icon for each item in the shop
|
|
private void PopulateItemIconView() {
|
|
foreach (Item item in model.inventory.GetItems()) {
|
|
if(itemFilter == ItemType.All || item.GetItemType() == itemFilter)
|
|
AddItemToView(item);
|
|
}
|
|
}
|
|
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
// ClearIconView()
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
//Removes all existing icons in the gridview
|
|
protected abstract void ClearIconView();
|
|
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
// AddItemToView()
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
//Adds a new item container to the view, each view can have its way of displaying items
|
|
protected abstract void AddItemToView(Item item);
|
|
|
|
protected abstract void RemoveItemFromView(Item item);
|
|
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
// InitializeButtons()
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
//This method adds a listener to the 'Buy' button. They are forwarded to the controller. Since this is the confirm button of
|
|
//the buy view, it will just call the controller interface's ConfirmSelectedItem function, the controller will handle the rest.
|
|
private void InitializeButtons() {
|
|
buyButton.onClick.AddListener(
|
|
delegate {
|
|
shopController.ConfirmSelectedItem();
|
|
}
|
|
);
|
|
}
|
|
|
|
// Set the item filter and automatically repopulate. Could use bit flags probably...
|
|
public void SetItemFilter(ItemType filter)
|
|
{
|
|
this.itemFilter = filter;
|
|
RepopulateItemIconView();
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
//RepopulateItemIconView();//Repopulate the view each frame, this is very inefficient and won't work in many scenarios and SHOULD NOT be in
|
|
//the final implementation, the view should be modified by the models via an observer or event queue pattern
|
|
|
|
//Switch between mouse and keyboard controllers
|
|
if (Input.GetKeyUp(KeyCode.K))
|
|
{
|
|
if (shopController is MouseController)
|
|
{
|
|
SwitchToKeyboardControl();
|
|
}
|
|
}
|
|
|
|
else if (Input.GetMouseButtonUp(0))
|
|
{
|
|
if (shopController is GridViewKeyboardController)
|
|
{
|
|
SwitchToMouseControl();
|
|
}
|
|
}
|
|
|
|
//Let the current controller handle input
|
|
shopController.HandleInput();
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
// SwitchToKeyboardControl()
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
protected abstract void SwitchToKeyboardControl();
|
|
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
// SwitchToMouseControl()
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
protected abstract void SwitchToMouseControl();
|
|
|
|
// These three are from the observable interface, and it was decided to leave this stuff to the implementation for now. Keeping here for reference
|
|
// public virtual void OnSelected(Item item)
|
|
// {
|
|
// Debug.Log("View selects item: " + item.name,this);
|
|
// RepopulateItemIconView();
|
|
// }
|
|
//
|
|
// public virtual void OnRemoved(Item item)
|
|
// {
|
|
// RemoveItemFromView(item);
|
|
// }
|
|
//
|
|
// public virtual void OnAdded(Item item)
|
|
// {
|
|
// throw new NotImplementedException();
|
|
// }
|
|
}
|
|
|