diff --git a/Nakama+Hiro/definitions/dev1/base-inventory.json b/Nakama+Hiro/definitions/dev1/base-inventory.json new file mode 100644 index 0000000..d1f99ec --- /dev/null +++ b/Nakama+Hiro/definitions/dev1/base-inventory.json @@ -0,0 +1,258 @@ +{ + "items": { + "iron_sword": { + "name": "Iron Sword", + "description": "A sharp sword made of iron.", + "category": "weapons", + "item_sets": ["common_weapons"], + "max_count": 99, + "stackable": false, + "consumable": false, + "string_properties": { + "equipment_slot": "right_hand", + "rarity": "common" + }, + "numeric_properties": { + "rank": 1 + }, + "disabled": false + }, + "gold_stack": { + "name": "Gold Stack", + "description": "A stack of golden coins. So shiny!", + "category": "currency", + "max_count": 99, + "stackable": true, + "consumable": true, + "string_properties": { + "rarity": "common" + }, + "keep_zero": true, + "consume_reward": { + "guaranteed": { + "currencies": { + "coins": { + "min": 100 + } + } + } + } + }, + "bomb": { + "name": "Bomb", + "description": "Goes BOOM!", + "category": "weapons", + "max_count": 99, + "stackable": true, + "consumable": true, + "string_properties": { + "rarity": "uncommon" + }, + "keep_zero": true, + "consume_reward": { + "guaranteed": { + "currencies": { + "coins": { + "min": 100 + } + } + } + } + }, + "small_crafting_bag": { + "name": "Small Crafting Bag", + "description": "A small bag of miscellaneous crafting materials.", + "category": "crafting_materials", + "max_count": 99, + "stackable": false, + "consumable": true, + "string_properties": { + "rarity": "uncommon" + }, + "consume_reward": { + "max_rolls": 2, + "weighted": [ + { + "items": { + "ruby_gem": { + "min": 1, + "max": 3 + } + }, + "weight": 40 + }, + { + "currencies": { + "coins": { + "min": 50, + "max": 200, + "multiple": 10 + } + }, + "weight": 60 + } + ] + } + }, + "wooden_shield": { + "name": "Wooden Shield", + "description": "A basic shield made from reinforced wood.", + "category": "armor", + "item_sets": ["shield", "common_armor"], + "max_count": 99, + "stackable": false, + "consumable": false, + "string_properties": { + "equipment_slot": "left_hand", + "rarity": "common" + }, + "numeric_properties": { + "defense": 15, + "block_chance": 10 + }, + "disabled": false + }, + "mana_potion": { + "name": "Mana Potion", + "description": "A vial of blue liquid that restores magical energy.", + "category": "potions", + "item_sets": ["consumables"], + "max_count": 99, + "stackable": true, + "consumable": true, + "string_properties": { + "rarity": "uncommon" + }, + "keep_zero": true, + "consume_reward": { + "guaranteed": { + "energies": { + "mana": { + "min": 30, + "max": 60 + } + } + } + } + }, + "iron_shield": { + "name": "Iron Shield", + "description": "A sturdy shield forged from iron. Provides solid protection.", + "category": "armor", + "item_sets": ["shield", "common_armor"], + "max_count": 99, + "stackable": false, + "consumable": false, + "string_properties": { + "rarity": "rare" + }, + "numeric_properties": { + "defense": 25, + "rank": 1 + }, + "disabled": false + }, + "magic_gem": { + "name": "Magic Gem", + "description": "A precious gemstone that radiates magical energy.", + "category": "crafting_materials", + "item_sets": ["materials", "gems"], + "max_count": 5, + "stackable": true, + "consumable": true, + "string_properties": { + "rarity": "epic" + } + }, + "golden_key": { + "name": "Golden Key", + "description": "An ornate golden key that opens special treasure chests.", + "category": "keys", + "item_sets": ["special_items"], + "max_count": 9, + "stackable": false, + "consumable": true, + "string_properties": { + "rarity": "rare" + }, + "keep_zero": true, + "consume_reward": { + "guaranteed": { + "currencies": { + "coins": { + "min": 500, + "max": 1000, + "multiple": 100 + } + } + }, + "max_rolls": 1, + "weighted": [ + { + "items": { + "ruby_gem": { + "min": 1, + "max": 3 + } + }, + "weight": 50 + }, + { + "currencies": { + "gems": { + "min": 10, + "max": 25, + "multiple": 5 + } + }, + "weight": 50 + } + ] + } + }, + "lucky_charm": { + "name": "Lucky Charm", + "description": "A four-leaf clover that brings good fortune when used.", + "category": "artifacts", + "item_sets": ["consumables", "buffs"], + "max_count": 5, + "stackable": true, + "consumable": true, + "string_properties": { + "rarity": "epic" + }, + "keep_zero": false, + "consume_reward": { + "guaranteed": { + "currencies": { + "coins": { + "min": 50, + "max": 150 + } + } + } + } + }, + "evil_eye": { + "name": "Eye of Sauron", + "description": "It is said to have the power to control the minds of others.", + "category": "artifacts", + "item_sets": ["special_items"], + "max_count": 1, + "stackable": false, + "consumable": false, + "string_properties": { + "rarity": "legendary" + }, + "keep_zero": false + } + }, + "limits": { + "categories": { + "armor": 10 + }, + "item_sets": { + "shield": 5 + } + } +} diff --git a/Nakama+Hiro/main.go b/Nakama+Hiro/main.go index d0842cb..068c9eb 100644 --- a/Nakama+Hiro/main.go +++ b/Nakama+Hiro/main.go @@ -63,7 +63,8 @@ func InitModule(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runti hiro.WithBaseSystem(fmt.Sprintf("definitions/%s/base-system.json", env), true), hiro.WithLeaderboardsSystem(fmt.Sprintf("definitions/%s/base-leaderboards.json", env), true), hiro.WithChallengesSystem(fmt.Sprintf("definitions/%s/base-challenges.json", env), true), - hiro.WithEconomySystem(fmt.Sprintf("definitions/%s/base-economy.json", env), true)) + hiro.WithEconomySystem(fmt.Sprintf("definitions/%s/base-economy.json", env), true), + hiro.WithInventorySystem(fmt.Sprintf("definitions/%s/base-inventory.json", env), true)) if err != nil { return err } diff --git a/UnityHiroInventory/.gitignore b/UnityHiroInventory/.gitignore new file mode 100644 index 0000000..ccf423b --- /dev/null +++ b/UnityHiroInventory/.gitignore @@ -0,0 +1,56 @@ + +# Created by https://www.gitignore.io/api/unity +# Edit at https://www.gitignore.io/?templates=unity + +# Jetbrain Rider Cache +.idea/ +Assets/Plugins/Editor/JetBrains* + +# Visual Studio Code +.vscode/ + + +### Unity ### +/[Ll]ibrary/ +/[Tt]emp/ +/[Oo]bj/ +/[Bb]uild/ +/[Bb]uilds/ +/[Ll]ogs/ +/[Uu]ser[Ss]ettings/ +Assets/AssetStoreTools* +# Unity local user project setting +UserSettings/ + +# Visual Studio cache directory +.vs/ + +# Autogenerated VS/MD/Consulo solution and project files +ExportedObj/ +.consulo/ +*.csproj +*.unityproj +*.sln +*.suo +*.tmp +*.user +*.userprefs +*.pidb +*.booproj +*.svd +*.pdb +*.opendb +*.VC.db + +# Unity3D generated meta files +*.pidb.meta +*.pdb.meta + +# Unity3D Generated File On Crash Reports +sysinfo.txt + +# Builds +*.apk +*.unitypackage + +# End of https://www.gitignore.io/api/unity \ No newline at end of file diff --git a/UnityHiroInventory/Assets/UnityHiroInventory.meta b/UnityHiroInventory/Assets/UnityHiroInventory.meta new file mode 100644 index 0000000..6daece2 --- /dev/null +++ b/UnityHiroInventory/Assets/UnityHiroInventory.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 051a355ed4cf14deb84f9c89447ad30e +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityHiroInventory/Assets/UnityHiroInventory/Editor.meta b/UnityHiroInventory/Assets/UnityHiroInventory/Editor.meta new file mode 100644 index 0000000..8504a2c --- /dev/null +++ b/UnityHiroInventory/Assets/UnityHiroInventory/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: dd78068405c264cd6beb0ee55cfa0eda +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityHiroInventory/Assets/UnityHiroInventory/Editor/AccountSwitcher.cs b/UnityHiroInventory/Assets/UnityHiroInventory/Editor/AccountSwitcher.cs new file mode 100644 index 0000000..01e1230 --- /dev/null +++ b/UnityHiroInventory/Assets/UnityHiroInventory/Editor/AccountSwitcher.cs @@ -0,0 +1,205 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Nakama; +using Hiro; +using Hiro.Unity; +using UnityEditor; +using UnityEngine; +using UnityEngine.SceneManagement; +using UnityEngine.UIElements; + +namespace HiroInventory.Editor +{ + public class AccountSwitcherEditor : EditorWindow + { + [SerializeField] private VisualTreeAsset tree; + + private DropdownField accountDropdown; + private Label usernamesLabel; + + private readonly SortedDictionary accountUsernames = new(); + + private const string AccountUsernamesKey = "AccountSwitcher_Usernames"; + + [MenuItem("Tools/Nakama/Account Switcher")] + public static void ShowWindow() + { + var inspectorType = typeof(UnityEditor.Editor).Assembly.GetType("UnityEditor.InspectorWindow"); + var window = GetWindow("Account Switcher", inspectorType); + + window.Focus(); + } + + [MenuItem("Tools/Nakama/Clear Test Accounts")] + public static void ClearSavedAccounts() + { + EditorPrefs.DeleteKey(AccountUsernamesKey); + Debug.Log("Cleared all saved account usernames"); + + // Refresh any open Account Switcher windows + var windows = Resources.FindObjectsOfTypeAll(); + foreach (var window in windows) + { + window.accountUsernames.Clear(); + window.UpdateUsernameLabels(); + } + } + + private void CreateGUI() + { + tree.CloneTree(rootVisualElement); + + accountDropdown = rootVisualElement.Q("account-dropdown"); + accountDropdown.RegisterValueChangedCallback(SwitchAccount); + + usernamesLabel = rootVisualElement.Q