├── .gitattributes ├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── .gitignore ├── LICENSE ├── README.md ├── RPG Databases.csproj ├── RPG Databases.csproj.old ├── RPG Databases.sln ├── addons ├── rpg_database │ ├── Scenes │ │ └── Base.tscn │ ├── Scripts │ │ ├── Armor.cs │ │ ├── Base.cs │ │ ├── Character.cs │ │ ├── Class.cs │ │ ├── Effects.cs │ │ ├── Enemy.cs │ │ ├── Item.cs │ │ ├── Skill.cs │ │ ├── States.cs │ │ ├── SystemScript.cs │ │ └── Weapon.cs │ ├── database.cs │ └── plugin.cfg └── rpg_databases_gd │ ├── Scenes │ └── Base.tscn │ ├── Scripts │ ├── armor.gd │ ├── base.gd │ ├── character.gd │ ├── class.gd │ ├── effects.gd │ ├── enemy.gd │ ├── item.gd │ ├── skill.gd │ ├── states.gd │ ├── system.gd │ └── weapon.gd │ ├── database.gd │ └── plugin.cfg ├── databases ├── Armor.json ├── Character.json ├── Class.json ├── Effect.json ├── Enemy.json ├── Item.json ├── Skill.json ├── State.json ├── System.json └── Weapon.json ├── default_env.tres ├── icon.png ├── icon.png.import ├── project.godot └── screenshots ├── armor.png ├── armor.png.import ├── character.png ├── character.png.import ├── class.png ├── class.png.import ├── item.png ├── item.png.import ├── skill.png ├── skill.png.import ├── weapon.png └── weapon.png.import /.gitattributes: -------------------------------------------------------------------------------- 1 | *.gd linguist-language=GDScript -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | Please complete the following information: 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Additional context** 32 | Add any other context about the problem here. 33 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Godot-specific ignores 3 | .import/ 4 | export.cfg 5 | export_presets.cfg 6 | assets/ 7 | # Mono-specific ignores 8 | .mono/ 9 | data_*/ 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 sdtv9507 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RPG Database 2 | 3 | RPG database for [Godot Engine](https://godotengine.org) inspired on RPG Maker's database editor made in C# 4 | 5 | ## How to use 6 | 7 | - Copy the folder rpg_database from the project in "res://addons/". 8 | - Create a new folder in the root of your project called "databases" (without the quotes). 9 | - If you are using the C# version, build the project. 10 | - Go to your project's Settings and enable the plugin. 11 | - A button should show above the inspector. Press it to open the database 12 | 13 | Feel free to open an issue if you find bugs or have a feature request 14 | 15 | # Version 1.1.1 16 | - Fixed bugs on Character's tab regarding adding Effect Types. 17 | - Fixed bugs on State's tab regarding saving and adding effects. 18 | - Fixed bugs on all tabs regarding change member button not clearing past data. 19 | - Added sample database. 20 | 21 | You can also find the project at [itch.io](https://sdtv9507.itch.io/godot-rpg-database-manager) 22 | -------------------------------------------------------------------------------- /RPG Databases.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net472 4 | RPGDatabases 5 | 6 | -------------------------------------------------------------------------------- /RPG Databases.csproj.old: -------------------------------------------------------------------------------- 1 | 2 | 3 | net472 4 | RPGDatabases 5 | 6 | -------------------------------------------------------------------------------- /RPG Databases.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio 2012 3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RPG Databases", "RPG Databases.csproj", "{CA9380EC-F8E6-4857-98C7-9B9641726EE3}" 4 | EndProject 5 | Global 6 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 7 | Debug|Any CPU = Debug|Any CPU 8 | ExportDebug|Any CPU = ExportDebug|Any CPU 9 | ExportRelease|Any CPU = ExportRelease|Any CPU 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {CA9380EC-F8E6-4857-98C7-9B9641726EE3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 13 | {CA9380EC-F8E6-4857-98C7-9B9641726EE3}.Debug|Any CPU.Build.0 = Debug|Any CPU 14 | {CA9380EC-F8E6-4857-98C7-9B9641726EE3}.ExportDebug|Any CPU.ActiveCfg = ExportDebug|Any CPU 15 | {CA9380EC-F8E6-4857-98C7-9B9641726EE3}.ExportDebug|Any CPU.Build.0 = ExportDebug|Any CPU 16 | {CA9380EC-F8E6-4857-98C7-9B9641726EE3}.ExportRelease|Any CPU.ActiveCfg = ExportRelease|Any CPU 17 | {CA9380EC-F8E6-4857-98C7-9B9641726EE3}.ExportRelease|Any CPU.Build.0 = ExportRelease|Any CPU 18 | EndGlobalSection 19 | EndGlobal 20 | -------------------------------------------------------------------------------- /addons/rpg_database/Scripts/Armor.cs: -------------------------------------------------------------------------------- 1 | using Godot; 2 | using System; 3 | 4 | [Tool] 5 | public class Armor : Control 6 | { 7 | // Declare member variables here. Examples: 8 | // private int a = 2; 9 | // private string b = "text"; 10 | 11 | string iconPath = ""; 12 | int armorSelected = 0; 13 | int statEdit = -1; 14 | // Called when the node enters the scene tree for the first time. 15 | public void Start() 16 | { 17 | Godot.Collections.Dictionary jsonDictionary = this.GetParent().GetParent().Call("ReadData", "Armor") as Godot.Collections.Dictionary; 18 | GetNode("ArmorButton").Clear(); 19 | for (int i = 0; i < jsonDictionary.Count; i++) 20 | { 21 | Godot.Collections.Dictionary armorData = jsonDictionary["armor" + i] as Godot.Collections.Dictionary; 22 | if (i > GetNode("ArmorButton").GetItemCount() - 1) 23 | { 24 | GetNode("ArmorButton").AddItem(armorData["name"] as string); 25 | } 26 | else 27 | { 28 | GetNode("ArmorButton").SetItemText(i, armorData["name"] as string); 29 | } 30 | } 31 | 32 | jsonDictionary = this.GetParent().GetParent().Call("ReadData", "System") as Godot.Collections.Dictionary; 33 | 34 | Godot.Collections.Dictionary systemData = jsonDictionary["armors"] as Godot.Collections.Dictionary; 35 | for (int i = 0; i < systemData.Count; i++) 36 | { 37 | if (i > GetNode("ATypeLabel/ATypeButton").GetItemCount() - 1) 38 | { 39 | GetNode("ATypeLabel/ATypeButton").AddItem(systemData[i.ToString()] as string); 40 | } 41 | else 42 | { 43 | GetNode("ATypeLabel/ATypeButton").SetItemText(i, systemData[i.ToString()] as string); 44 | } 45 | } 46 | 47 | systemData = jsonDictionary["slots"] as Godot.Collections.Dictionary; 48 | int final_id = 0; 49 | foreach (String str in systemData.Keys) 50 | { 51 | if (str[0] == 'a') 52 | { 53 | int id = Convert.ToInt32(str.Remove(0, 1)) - final_id; 54 | if (id > GetNode("SlotLabel/SlotButton").GetItemCount() - 1) 55 | { 56 | GetNode("SlotLabel/SlotButton").AddItem(systemData[str] as string); 57 | } 58 | else 59 | { 60 | GetNode("SlotLabel/SlotButton").SetItemText(id, systemData[str] as string); 61 | } 62 | } 63 | else 64 | { 65 | final_id += 1; 66 | } 67 | } 68 | RefreshData(armorSelected); 69 | } 70 | 71 | private void RefreshData(int id) 72 | { 73 | Godot.Collections.Dictionary jsonDictionary = this.GetParent().GetParent().Call("ReadData", "Armor") as Godot.Collections.Dictionary; 74 | Godot.Collections.Dictionary armorData = jsonDictionary["armor" + id] as Godot.Collections.Dictionary; 75 | 76 | jsonDictionary = this.GetParent().GetParent().Call("ReadData", "System") as Godot.Collections.Dictionary; 77 | Godot.Collections.Dictionary systemData = jsonDictionary["stats"] as Godot.Collections.Dictionary; 78 | 79 | GetNode("NameLabel/NameText").Text = armorData["name"] as string; 80 | string icon = armorData["icon"] as string; 81 | if (icon != "") 82 | { 83 | iconPath = icon; 84 | GetNode("IconLabel/IconSprite").Texture = GD.Load(armorData["icon"] as string) as Godot.Texture; 85 | } 86 | GetNode("DescLabel/DescText").Text = armorData["description"] as string; 87 | GetNode("ATypeLabel/ATypeButton").Selected = Convert.ToInt32(armorData["armor_type"]); 88 | GetNode("SlotLabel/SlotButton").Selected = Convert.ToInt32(armorData["slot_type"]); 89 | GetNode("PriceLabel/PriceSpin").Value = Convert.ToInt32(armorData["price"]); 90 | 91 | GetNode("StatsLabel/StatsContainer/DataContainer/StatNameCont/StatNameList").Clear(); 92 | GetNode("StatsLabel/StatsContainer/DataContainer/StatValueCont/StatValueList").Clear(); 93 | for (int i = 0; i < systemData.Count; i++) 94 | { 95 | string statName = systemData[i.ToString()] as string; 96 | Godot.Collections.Dictionary armorStatFormula = armorData["stat_list"] as Godot.Collections.Dictionary; 97 | string statFormula = ""; 98 | if (armorStatFormula.Contains(statName)) 99 | { 100 | statFormula = armorStatFormula[statName as string] as string; 101 | } 102 | else 103 | { 104 | statFormula = "0"; 105 | } 106 | GetNode("StatsLabel/StatsContainer/DataContainer/StatNameCont/StatNameList").AddItem(statName); 107 | GetNode("StatsLabel/StatsContainer/DataContainer/StatValueCont/StatValueList").AddItem(statFormula); 108 | } 109 | if (armorData.Contains("effects") == true) 110 | { 111 | this.ClearEffectList(); 112 | Godot.Collections.Array effectList = armorData["effects"] as Godot.Collections.Array; 113 | foreach (Godot.Collections.Dictionary effect in effectList) 114 | { 115 | this.AddEffectList(effect["name"].ToString(), Convert.ToInt32(effect["data_id"]), effect["value1"].ToString(), effect["value2"].ToString()); 116 | } 117 | } 118 | 119 | } 120 | 121 | private void _on_AddArmorButton_pressed() 122 | { 123 | GetNode("ArmorButton").AddItem("NewArmor"); 124 | int id = GetNode("ArmorButton").GetItemCount() - 1; 125 | Godot.Collections.Dictionary jsonDictionary = this.GetParent().GetParent().Call("ReadData", "Armor") as Godot.Collections.Dictionary; 126 | Godot.Collections.Dictionary armorData = new Godot.Collections.Dictionary(); 127 | Godot.Collections.Dictionary armorStats = new Godot.Collections.Dictionary(); 128 | armorData.Add("name", "NewArmor"); 129 | armorData.Add("icon", ""); 130 | armorData.Add("description", "New created armor"); 131 | armorData.Add("armor_type", 0); 132 | armorData.Add("slot_type", 0); 133 | armorData.Add("price", 50); 134 | armorStats.Add("hp", "0"); 135 | armorStats.Add("mp", "0"); 136 | armorStats.Add("atk", "0"); 137 | armorStats.Add("def", "0"); 138 | armorStats.Add("int", "0"); 139 | armorStats.Add("res", "0"); 140 | armorStats.Add("spd", "0"); 141 | armorStats.Add("luk", "0"); 142 | armorData.Add("stat_list", armorStats); 143 | jsonDictionary.Add("armor" + id, armorData); 144 | this.GetParent().GetParent().Call("StoreData", "Armor", jsonDictionary); 145 | } 146 | 147 | private void _on_RemoveArmor_pressed() 148 | { 149 | Godot.Collections.Dictionary jsonDictionary = this.GetParent().GetParent().Call("ReadData", "Armor") as Godot.Collections.Dictionary; 150 | if (jsonDictionary.Keys.Count > 1) 151 | { 152 | int armorId = armorSelected; 153 | while (armorId < jsonDictionary.Keys.Count - 1) 154 | { 155 | jsonDictionary["armor" + armorId] = jsonDictionary["armor" + (armorId + 1)]; 156 | armorId += 1; 157 | } 158 | jsonDictionary.Remove("armor" + armorId); 159 | this.GetParent().GetParent().Call("StoreData", "Armor", jsonDictionary); 160 | GetNode("ArmorButton").RemoveItem(armorSelected); 161 | if (armorSelected == 0) 162 | { 163 | GetNode("ArmorButton").Select(armorSelected + 1); 164 | armorSelected += 1; 165 | } 166 | else 167 | { 168 | GetNode("ArmorButton").Select(armorSelected - 1); 169 | armorSelected -= 1; 170 | } 171 | GetNode("ArmorButton").Select(armorSelected); 172 | RefreshData(armorSelected); 173 | } 174 | } 175 | 176 | private void _on_ArmorSaveButton_pressed() 177 | { 178 | SaveArmorData(); 179 | RefreshData(armorSelected); 180 | } 181 | 182 | private void _on_Search_pressed() 183 | { 184 | GetNode("IconLabel/IconSearch").PopupCentered(); 185 | } 186 | 187 | private void _on_IconSearch_file_selected(string path) 188 | { 189 | iconPath = path; 190 | GetNode("IconLabel/IconSprite").Texture = GD.Load(path) as Godot.Texture; 191 | } 192 | 193 | private void _on_ArmorButton_item_selected(int id) 194 | { 195 | armorSelected = id; 196 | RefreshData(id); 197 | } 198 | 199 | private void SaveArmorData() 200 | { 201 | Godot.Collections.Dictionary jsonDictionary = this.GetParent().GetParent().Call("ReadData", "Armor") as Godot.Collections.Dictionary; 202 | Godot.Collections.Dictionary armorData = jsonDictionary["armor"+armorSelected] as Godot.Collections.Dictionary; 203 | Godot.Collections.Dictionary armorStatFormula = armorData["stat_list"] as Godot.Collections.Dictionary; 204 | Godot.Collections.Array effectList = new Godot.Collections.Array(); 205 | 206 | armorData["name"] = GetNode("NameLabel/NameText").Text; 207 | GetNode("ArmorButton").SetItemText(armorSelected, GetNode("NameLabel/NameText").Text); 208 | armorData["icon"] = iconPath; 209 | armorData["description"] = GetNode("DescLabel/DescText").Text; 210 | armorData["armor_type"] = GetNode("ATypeLabel/ATypeButton").Selected; 211 | armorData["slot_type"] = GetNode("SlotLabel/SlotButton").Selected; 212 | armorData["price"] = GetNode("PriceLabel/PriceSpin").Value; 213 | int items = GetNode("StatsLabel/StatsContainer/DataContainer/StatNameCont/StatNameList").GetItemCount(); 214 | for (int i = 0; i < items; i++) 215 | { 216 | string stat = GetNode("StatsLabel/StatsContainer/DataContainer/StatNameCont/StatNameList").GetItemText(i); 217 | string formula = GetNode("StatsLabel/StatsContainer/DataContainer/StatValueCont/StatValueList").GetItemText(i); 218 | armorStatFormula[stat] = formula; 219 | } 220 | int effectSize = GetNode("EffectLabel/PanelContainer/VBoxContainer/HBoxContainer/EffectNames").GetItemCount(); 221 | for (int i = 0; i < effectSize; i++) 222 | { 223 | Godot.Collections.Dictionary effectData = new Godot.Collections.Dictionary(); 224 | effectData["name"] = GetNode("EffectLabel/PanelContainer/VBoxContainer/HBoxContainer/EffectNames").GetItemText(i); 225 | effectData["data_id"] = GetNode("EffectLabel/PanelContainer/VBoxContainer/HBoxContainer/DataType").GetItemText(i); 226 | effectData["value1"] = GetNode("EffectLabel/PanelContainer/VBoxContainer/HBoxContainer/EffectValue1").GetItemText(i); 227 | effectData["value2"] = GetNode("EffectLabel/PanelContainer/VBoxContainer/HBoxContainer/EffectValue2").GetItemText(i); 228 | effectList.Add(effectData); 229 | } 230 | armorData["effects"] = effectList; 231 | this.GetParent().GetParent().Call("StoreData", "Armor", jsonDictionary); 232 | } 233 | 234 | private void _on_StatValueList_item_activated(int index) 235 | { 236 | string statName = GetNode("StatsLabel/StatsContainer/DataContainer/StatNameCont/StatNameList").GetItemText(index); 237 | string statFormula = GetNode("StatsLabel/StatsContainer/DataContainer/StatValueCont/StatValueList").GetItemText(index); 238 | GetNode