From 86c7e486d0bd027b05f6d648848b2298ae309fc4 Mon Sep 17 00:00:00 2001 From: Devin Date: Tue, 16 Nov 2021 19:47:58 +0100 Subject: [PATCH] Add basic upgrading system with unfinished UI --- Assets/Resources/UpgradeShop.asset | 3 +- Assets/Scenes/NewShop.unity | 2 +- .../Shop/Components/UpgradeModelComponent.cs | 13 ++++ .../Components/UpgradeModelComponent.cs.meta | 11 ++++ Assets/Scripts/Shop/Model/Item.cs | 6 +- Assets/Scripts/Shop/Model/ItemArmor.cs | 19 +++++- Assets/Scripts/Shop/Model/ItemPotion.cs | 10 +++ Assets/Scripts/Shop/Model/ItemWeapon.cs | 10 +++ Assets/Scripts/Shop/Model/ShopModel.cs | 8 ++- Assets/Scripts/Shop/Model/UpgradeModel.cs | 61 +++++++++++++++++++ .../Scripts/Shop/Model/UpgradeModel.cs.meta | 11 ++++ .../Shop/Scriptable Objects/ShopObject.cs | 1 + Assets/Scripts/Shop/View/ShopViewList.cs | 3 +- Assets/Scripts/Shop/View/ViewItemInfoPanel.cs | 13 +++- 14 files changed, 163 insertions(+), 8 deletions(-) create mode 100644 Assets/Scripts/Shop/Components/UpgradeModelComponent.cs create mode 100644 Assets/Scripts/Shop/Components/UpgradeModelComponent.cs.meta create mode 100644 Assets/Scripts/Shop/Model/UpgradeModel.cs create mode 100644 Assets/Scripts/Shop/Model/UpgradeModel.cs.meta diff --git a/Assets/Resources/UpgradeShop.asset b/Assets/Resources/UpgradeShop.asset index f79ca78..963476a 100644 --- a/Assets/Resources/UpgradeShop.asset +++ b/Assets/Resources/UpgradeShop.asset @@ -12,4 +12,5 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 3145dd14dac0cf84a909862b61ec2893, type: 3} m_Name: UpgradeShop m_EditorClassIdentifier: - PriceModifier: 2 + PriceModifier: 5 + UpgradeFactor: 1.5 diff --git a/Assets/Scenes/NewShop.unity b/Assets/Scenes/NewShop.unity index 7b51209..edf42f7 100644 --- a/Assets/Scenes/NewShop.unity +++ b/Assets/Scenes/NewShop.unity @@ -8577,7 +8577,7 @@ MonoBehaviour: m_GameObject: {fileID: 842666262} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 8e211938370fd3d43a99aae3848bdd1c, type: 3} + m_Script: {fileID: 11500000, guid: c0435c4334f16f74d9eb1c7fbd973641, type: 3} m_Name: m_EditorClassIdentifier: inventory: {fileID: 1237921497} diff --git a/Assets/Scripts/Shop/Components/UpgradeModelComponent.cs b/Assets/Scripts/Shop/Components/UpgradeModelComponent.cs new file mode 100644 index 0000000..0f332f2 --- /dev/null +++ b/Assets/Scripts/Shop/Components/UpgradeModelComponent.cs @@ -0,0 +1,13 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class UpgradeModelComponent : ModelComponent +{ + [SerializeField] private ShopObject shop; + protected override void CreateModel() + { + Debug.Assert(shop != null,"Shop model initial object never assigned!",this); + model = new UpgradeModel(shop); + } +} diff --git a/Assets/Scripts/Shop/Components/UpgradeModelComponent.cs.meta b/Assets/Scripts/Shop/Components/UpgradeModelComponent.cs.meta new file mode 100644 index 0000000..117239f --- /dev/null +++ b/Assets/Scripts/Shop/Components/UpgradeModelComponent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c0435c4334f16f74d9eb1c7fbd973641 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: -10 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Shop/Model/Item.cs b/Assets/Scripts/Shop/Model/Item.cs index 6dde38e..bc00397 100644 --- a/Assets/Scripts/Shop/Model/Item.cs +++ b/Assets/Scripts/Shop/Model/Item.cs @@ -11,7 +11,7 @@ public abstract class Item public readonly string description; public readonly ItemRarity rarity; - public int basePrice { get; private set; } // This is the base price for the item, the buying and selling prices can be + public int basePrice { get; protected set; } // This is the base price for the item, the buying and selling prices can be // generated based on this value. //------------------------------------------------------------------------------------------------------------------------ @@ -31,6 +31,10 @@ public abstract class Item // Returns a nicely formatted text about the item's stats. Implementation-specific, because different types of items generate these differently public abstract string GetStats(); + + public abstract void Upgrade(float upgradeFactor); // Each type of item will upgrade differently + + public abstract int GetUpgradeCosts(float upgradeFactor); // How much would it cost to upgrade this item by that amount? Base price } /// diff --git a/Assets/Scripts/Shop/Model/ItemArmor.cs b/Assets/Scripts/Shop/Model/ItemArmor.cs index 89df9cc..7864e0f 100644 --- a/Assets/Scripts/Shop/Model/ItemArmor.cs +++ b/Assets/Scripts/Shop/Model/ItemArmor.cs @@ -4,8 +4,10 @@ using UnityEngine; public class ItemArmor : Item { - public readonly int Defense; - public readonly int Block; + public int Defense { get; private set; } + + public int Block { get; private set; } + public ItemArmor(string name, string iconName, int pbasePrice,int pDefense, int pBlock, string descr = "", ItemRarity rarity = ItemRarity.Common) : base(name, iconName, pbasePrice, descr,rarity) { Block = pBlock; @@ -22,4 +24,17 @@ public class ItemArmor : Item { return "Defense: " + Defense + "\tBlock: " + Block; } + + public override void Upgrade(float upgradeFactor) + { + Block = (int) (Block * upgradeFactor); // Don't wanna randomise upgrades for now, to be honest + Defense = (int) (Defense * upgradeFactor); + // We increase value, but only by half as much as the upgrade improved stats. No one wants to buy a bad item upgraded to be passable. Cost to do so is higher by as much as the upgrade shop charges extra + basePrice += (int)(GetUpgradeCosts(upgradeFactor) * 0.5); // The goal is to make upgrading an endless money sink, and incentivise buying better base items + } + + public override int GetUpgradeCosts(float upgradeFactor) + { + return (int) (((basePrice * upgradeFactor) - basePrice)); + } } diff --git a/Assets/Scripts/Shop/Model/ItemPotion.cs b/Assets/Scripts/Shop/Model/ItemPotion.cs index 46b3aad..946d921 100644 --- a/Assets/Scripts/Shop/Model/ItemPotion.cs +++ b/Assets/Scripts/Shop/Model/ItemPotion.cs @@ -27,6 +27,16 @@ public class ItemPotion : Item ? "Strength: " + Effect + "\tType: " + Type + "\tTime: " + Time : "Strength: " + Effect + "\tType: " + Type; } + + public override void Upgrade(float upgradeFactor) + { + throw new NotImplementedException(); + } + + public override int GetUpgradeCosts(float upgradeFactor) + { + return 0; + } } [Serializable] diff --git a/Assets/Scripts/Shop/Model/ItemWeapon.cs b/Assets/Scripts/Shop/Model/ItemWeapon.cs index ab9dde1..d3a58f1 100644 --- a/Assets/Scripts/Shop/Model/ItemWeapon.cs +++ b/Assets/Scripts/Shop/Model/ItemWeapon.cs @@ -21,4 +21,14 @@ public class ItemWeapon : Item { return "Attack: " + Attack + "\tDamage: " + Damage; // Empty placeholder } + + public override void Upgrade(float upgradeFactor) + { + throw new System.NotImplementedException(); + } + + public override int GetUpgradeCosts(float upgradeFactor) + { + return 0; + } } diff --git a/Assets/Scripts/Shop/Model/ShopModel.cs b/Assets/Scripts/Shop/Model/ShopModel.cs index 72607a5..c3537a5 100644 --- a/Assets/Scripts/Shop/Model/ShopModel.cs +++ b/Assets/Scripts/Shop/Model/ShopModel.cs @@ -18,7 +18,7 @@ public abstract class ShopModel : IModelObservable public float PriceModifier => priceModifier; - private List> observers = new List>(); + protected List> observers = new List>(); //------------------------------------------------------------------------------------------------------------------------ // ShopModel() @@ -101,6 +101,12 @@ public abstract class ShopModel : IModelObservable public abstract void SetTradePartner(Inventory tradePartner); + // So, certain models may charge something fairly unrelated to the base price. Keyword upgrade shops. Let's make it possible to figure out what a shop would charge for an item + public virtual int GetPriceForItem(Item item) + { + return (int) (item.basePrice * priceModifier); // Default to the logical thing here + } + // Observer pattern. Anything that wants to know what happens regarding item selection subscribes to this. // This could mean all items of this model and its views do it, or all views do it. public IDisposable RegisterObserver(IShopModelObserver observer) diff --git a/Assets/Scripts/Shop/Model/UpgradeModel.cs b/Assets/Scripts/Shop/Model/UpgradeModel.cs new file mode 100644 index 0000000..be415d1 --- /dev/null +++ b/Assets/Scripts/Shop/Model/UpgradeModel.cs @@ -0,0 +1,61 @@ +using System; +using System.Configuration; +using UnityEngine; + +/// +/// The upgrade model differs a little from the other two. We do not care for a trade partner, only for ourselves. +/// On that note, we do use the price modifier to determine how expensive an upgrade is gonna be. +/// We do not upgrade by class, we merely improve the stats until it's no longer affordable. Self-balancing, right? +/// Still, upgrading a wooden sword to the point it's as good as a diamond sword (but 3x more expensive) technically does not make it more rare. Just impressive, really... +/// +public class UpgradeModel : ShopModel +{ + private float upgradeFactor; // How much would an upgrade improve stats? + public UpgradeModel(float pPriceModifier, int pItemCount, int pMoney) : base(pPriceModifier, pItemCount, pMoney) + { + + } + + // Rather than modifying the whole class, we just reuse the existing stuff but don't make it create any items. + // This makes it less work to make proper functionality, without having to break any potential old functionality. + // Additionally, saves us work having to rip out the inventory's own ability to generate items. + // Edit: Nevermind, let's just allow setting the inventory in the constructor, for shared inventories between models! + public UpgradeModel(ShopObject pShopInitials, Inventory inventory = null) : this(pShopInitials.PriceModifier, 0, 0) + { + if (inventory != null) this.inventory = inventory; + upgradeFactor = pShopInitials.UpgradeFactor; + } + + //------------------------------------------------------------------------------------------------------------------------ + // ConfirmSelectedItem() + //------------------------------------------------------------------------------------------------------------------------ + //Currently it just removes the selected item from the shop's inventory, rewrite this function and don't forget the unit test. + + public override void ConfirmSelectedItem() + { + var item = GetSelectedItem(); + inventory.ChangeBalance(-GetPriceForItem(item)); // Expensive upgrading! + // If no exception was thrown, we just assume we continue the upgrade! + item.Upgrade(upgradeFactor); + triggerTransaction(); + } + + public override void SetTradePartner(Inventory tradePartner) + { + //this.tradePartner = tradePartner; No need! + } + + public override int GetPriceForItem(Item item) + { + return (int) (item.GetUpgradeCosts(upgradeFactor) * priceModifier); + } + + // This thing triggers transaction events for each upgrade! + private void triggerTransaction() + { + foreach (var observer in observers) + { + observer.OnTransaction(inventory.Money); + } + } +} diff --git a/Assets/Scripts/Shop/Model/UpgradeModel.cs.meta b/Assets/Scripts/Shop/Model/UpgradeModel.cs.meta new file mode 100644 index 0000000..a45f477 --- /dev/null +++ b/Assets/Scripts/Shop/Model/UpgradeModel.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 32a48e31df172e24b8d2aa672369a274 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Shop/Scriptable Objects/ShopObject.cs b/Assets/Scripts/Shop/Scriptable Objects/ShopObject.cs index 79b54cc..2ca2112 100644 --- a/Assets/Scripts/Shop/Scriptable Objects/ShopObject.cs +++ b/Assets/Scripts/Shop/Scriptable Objects/ShopObject.cs @@ -9,4 +9,5 @@ public class ShopObject : ScriptableObject { //public int Money; public float PriceModifier; // How much more expensive than retail price does this shop sell stuff? + public float UpgradeFactor = 1; // Also default this one to 1.0. Used by anything that can upgrade stuff, to determine how much of an upgrade (or downgrade) it is } diff --git a/Assets/Scripts/Shop/View/ShopViewList.cs b/Assets/Scripts/Shop/View/ShopViewList.cs index 35019c2..719b15a 100644 --- a/Assets/Scripts/Shop/View/ShopViewList.cs +++ b/Assets/Scripts/Shop/View/ShopViewList.cs @@ -129,6 +129,7 @@ public class ShopViewList : ShopView, IShopModelObserver public void OnTransaction(int moneyDelta) { - + // Well we bought something so let's update the panel in any case + infoPanel?.Refresh(); } } diff --git a/Assets/Scripts/Shop/View/ViewItemInfoPanel.cs b/Assets/Scripts/Shop/View/ViewItemInfoPanel.cs index 485b84c..73b3fac 100644 --- a/Assets/Scripts/Shop/View/ViewItemInfoPanel.cs +++ b/Assets/Scripts/Shop/View/ViewItemInfoPanel.cs @@ -18,6 +18,9 @@ public class ViewItemInfoPanel : MonoBehaviour private List descr; private List rarity; private List icons; + + private Item lastItem; // Should we want to refresh for whatever reason + private ShopModel lastShop; private void Awake() { UpdateComponentInfo(); @@ -37,9 +40,16 @@ public class ViewItemInfoPanel : MonoBehaviour // TODO: Create and add all other types in here as components! } + public void Refresh() + { + SetItemInfo(lastItem,lastShop); + } + // When this is set, it updates all relevant game objects to reflect the item's propertiese. public void SetItemInfo(Item item,ShopModel owner = null) { + lastShop = owner; + lastItem = item; var multiplier = owner?.PriceModifier ?? 1; if (item == null) { @@ -65,7 +75,8 @@ public class ViewItemInfoPanel : MonoBehaviour foreach (var price in prices) { - price.SetPrice((int) (item.basePrice * multiplier)); + var cost = owner?.GetPriceForItem(item); + price.SetPrice(cost ?? (int) (item.basePrice * multiplier)); // If the shop has any special pricing, show that here } foreach (var descriptionDisplay in descr)