├── DungeonManagerWpf ├── ClassDiagram1.cd ├── robe_O8p_icon.ico ├── App.config ├── Properties │ ├── Settings.settings │ ├── Settings.Designer.cs │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ └── Resources.resx ├── App.xaml ├── App.xaml.cs ├── MathConverter.cs ├── AttributeControl.xaml ├── NumericUpDown.xaml ├── DungeonManagerWpf.sln ├── SkillControl.xaml ├── Settings.cs ├── DiceWindow.xaml ├── AttributeControl.xaml.cs ├── NumericUpDown.xaml.cs ├── MainWindow.xaml ├── DungeonManagerWpf.csproj ├── MainWindow.xaml.cs ├── Character.cs ├── SkillControl.xaml.cs ├── DiceWindow.xaml.cs ├── CharacterWindow.xaml.cs └── CharacterWindow.xaml ├── robe_O8p_icon.ico ├── DungeonManager ├── App.config ├── Properties │ ├── Settings.settings │ ├── Settings.Designer.cs │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ └── Resources.resx ├── InitiativeTrackerForm.cs ├── Program.cs ├── InitiativeTrackerForm.Designer.cs ├── Settings.cs ├── Util.cs ├── DungeonManager.csproj ├── CreateCharacterForm.resx ├── InitiativeTrackerForm.resx ├── Character.cs ├── Form1.cs └── Form1.Designer.cs ├── README.md ├── DungeonManager.sln ├── .gitattributes └── .gitignore /DungeonManagerWpf/ClassDiagram1.cd: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /robe_O8p_icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DrainSmith/DungeonManager/HEAD/robe_O8p_icon.ico -------------------------------------------------------------------------------- /DungeonManagerWpf/robe_O8p_icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DrainSmith/DungeonManager/HEAD/DungeonManagerWpf/robe_O8p_icon.ico -------------------------------------------------------------------------------- /DungeonManager/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /DungeonManagerWpf/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /DungeonManagerWpf/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /DungeonManager/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DungeonManager 2 | A small Windows desktop application to help D&D 5e Dungeon Masters keep track of their characters' stats. 3 | 4 | This program does not replace normal character creation. You will need need a Player's Handbook or the Basic Rules PDF from Wizards of the Coast. 5 | 6 | You will need to have .NET 4.5.1 installed to run the program. 7 | -------------------------------------------------------------------------------- /DungeonManagerWpf/App.xaml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /DungeonManagerWpf/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Data; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using System.Windows; 8 | 9 | namespace DungeonManagerWpf 10 | { 11 | /// 12 | /// Interaction logic for App.xaml 13 | /// 14 | public partial class App : Application 15 | { 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /DungeonManager/InitiativeTrackerForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | 11 | namespace DungeonManager 12 | { 13 | public partial class InitiativeTrackerForm : Form 14 | { 15 | public InitiativeTrackerForm() 16 | { 17 | InitializeComponent(); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /DungeonManager/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using System.Windows.Forms; 6 | 7 | namespace DungeonManager 8 | { 9 | static class Program 10 | { 11 | /// 12 | /// The main entry point for the application. 13 | /// 14 | [STAThread] 15 | static void Main() 16 | { 17 | Application.EnableVisualStyles(); 18 | Application.SetCompatibleTextRenderingDefault(false); 19 | Application.Run(new Form1()); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /DungeonManagerWpf/MathConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Globalization; 6 | using System.Windows.Data; 7 | 8 | 9 | namespace DungeonManagerWpf 10 | { 11 | public class MathConverter : IValueConverter 12 | { 13 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 14 | { 15 | // Parse value into equation and remove spaces 16 | double retVal = (double)value; 17 | double param = Double.Parse((string)parameter); 18 | return retVal * param; 19 | } 20 | 21 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 22 | { 23 | throw new NotImplementedException(); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /DungeonManagerWpf/AttributeControl.xaml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 13 | 14 | -------------------------------------------------------------------------------- /DungeonManagerWpf/NumericUpDown.xaml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 10 | 48 | 49 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /DungeonManager/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /DungeonManagerWpf/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /DungeonManager/CreateCharacterForm.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /DungeonManager/InitiativeTrackerForm.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /DungeonManager/Character.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace DungeonManager 8 | { 9 | [Serializable] 10 | public class Character 11 | { 12 | public string _guid; 13 | public string Name; 14 | public List Levels = new List(); 15 | public List Features = new List(); 16 | public CharacterRace Race; 17 | public CharacterAlignment Alignment; 18 | public int HitPoints; 19 | public int ArmorClass; 20 | public int Strength = 10; 21 | public int Dexterity = 10; 22 | public int Constitution = 10; 23 | public int Intelligence = 10; 24 | public int Wisdom = 10; 25 | public int Charisma = 10; 26 | 27 | public bool StrengthSavingThrow; 28 | public bool DexteritySavingThrow; 29 | public bool ConstitutionSavingThrow; 30 | public bool IntelligenceSavingThrow; 31 | public bool WisdomSavingThrow; 32 | public bool CharismaSavingThrow; 33 | 34 | public int Initiative; 35 | public int Speed; 36 | 37 | public int Acrobatics = 0; // 0 - not proficient, 1 - proficient, 2 - double proficient 38 | public int AnimalHandling = 0; 39 | public int Arcana = 0; 40 | public int Athletics = 0; 41 | public int Deception = 0; 42 | public int History = 0; 43 | public int Insight = 0; 44 | public int Intimidation = 0; 45 | public int Investigation = 0; 46 | public int Medicine = 0; 47 | public int Nature = 0; 48 | public int Perception = 0; 49 | public int Performance = 0; 50 | public int Persuasion = 0; 51 | public int Religion = 0; 52 | public int SleightOfHand = 0; 53 | public int Stealth = 0; 54 | public int Survival = 0; 55 | 56 | public string Background; 57 | public string PersonalityTraits; 58 | public string Ideals; 59 | public string Bonds; 60 | public string Flaws; 61 | 62 | public Character() 63 | { 64 | _guid = Guid.NewGuid().ToString(); 65 | } 66 | 67 | [System.Xml.Serialization.XmlIgnore] 68 | public int ProficiencyBonus 69 | { 70 | get 71 | { 72 | int totalLevel = Levels.Sum(item => item._level); 73 | return 2 + (totalLevel - 1) / 4; 74 | } 75 | } 76 | 77 | public static int GetModifier(int AbilityScore) 78 | { 79 | // As per DMG, 30 is the largest ability score a creature can have. 80 | if (AbilityScore < 1 || AbilityScore > 30) 81 | throw new ArgumentOutOfRangeException("Must be 1 through 25"); 82 | return (int)Math.Floor(((double)(AbilityScore - 10)) / 2.0); 83 | } 84 | 85 | private int getCastingAbilityVal() 86 | { 87 | int retVal = 0; 88 | List chaClasses = new List() { 89 | CharacterClass.Bard, 90 | CharacterClass.Sorcerer, 91 | CharacterClass.Paladin, 92 | CharacterClass.Warlock 93 | }; 94 | List intClasses = new List() { 95 | CharacterClass.Fighter, 96 | CharacterClass.Rogue, 97 | CharacterClass.Wizard 98 | }; 99 | List wisClasses = new List() { 100 | CharacterClass.Druid, 101 | CharacterClass.Ranger, 102 | CharacterClass.Monk, 103 | CharacterClass.Cleric 104 | }; 105 | 106 | foreach (Level l in Levels) 107 | { 108 | if(wisClasses.Contains(l._class)) 109 | retVal = (GetModifier(Wisdom) > retVal) ? GetModifier(Wisdom) : retVal; 110 | if(intClasses.Contains(l._class)) 111 | retVal = (GetModifier(Intelligence) > retVal) ? GetModifier(Intelligence) : retVal; 112 | if (chaClasses.Contains(l._class)) 113 | retVal = (GetModifier(Charisma) > retVal) ? GetModifier(Charisma) : retVal; 114 | } 115 | return retVal; 116 | } 117 | 118 | public int SpellDC 119 | { 120 | get 121 | { 122 | return getCastingAbilityVal() + 8 + ProficiencyBonus; 123 | } 124 | } 125 | 126 | public int SpellAttackModifier 127 | { 128 | get 129 | { 130 | return getCastingAbilityVal() + ProficiencyBonus; 131 | } 132 | } 133 | } 134 | 135 | [Serializable] 136 | public class Level 137 | { 138 | public CharacterClass _class; 139 | public int _level; 140 | 141 | public Level() { } 142 | } 143 | 144 | [Serializable] 145 | public enum CharacterRace 146 | { 147 | Dwarf, 148 | Elf, 149 | Halfling, 150 | Human, 151 | Dragonborn, 152 | Gnome, 153 | HalfElf, 154 | HalfOrc, 155 | Tieling, 156 | AirGenasi, 157 | EarthGenasi, 158 | WaterGenasi, 159 | FireGenasi, 160 | Arakocra, 161 | DeepGnome, 162 | Goliath 163 | } 164 | 165 | [Serializable] 166 | public enum CharacterClass 167 | { 168 | Barbarian, 169 | Bard, 170 | Cleric, 171 | Druid, 172 | Fighter, 173 | Monk, 174 | Paladin, 175 | Ranger, 176 | Rogue, 177 | Sorcerer, 178 | Warlock, 179 | Wizard 180 | } 181 | 182 | [Serializable] 183 | public enum CharacterAlignment 184 | { 185 | LawfulGood, 186 | ChaoticGood, 187 | NeutralGood, 188 | LawfulNeutral, 189 | ChaoticNeutral, 190 | TrueNeutral, 191 | LawfulEvil, 192 | ChaoticEvil, 193 | NeutralEvil 194 | } 195 | 196 | 197 | } 198 | -------------------------------------------------------------------------------- /DungeonManagerWpf/DungeonManagerWpf.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {31EE33FF-ADF3-40DE-A4E7-6BA502D45DF4} 8 | WinExe 9 | Properties 10 | DungeonManagerWpf 11 | DungeonManagerWpf 12 | v4.5.1 13 | 512 14 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 15 | 4 16 | true 17 | 18 | 19 | AnyCPU 20 | true 21 | full 22 | false 23 | bin\Debug\ 24 | DEBUG;TRACE 25 | prompt 26 | 4 27 | 28 | 29 | AnyCPU 30 | pdbonly 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 4.0 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | MSBuild:Compile 55 | Designer 56 | 57 | 58 | AttributeControl.xaml 59 | 60 | 61 | DiceWindow.xaml 62 | 63 | 64 | NumericUpDown.xaml 65 | 66 | 67 | 68 | SkillControl.xaml 69 | 70 | 71 | Designer 72 | MSBuild:Compile 73 | 74 | 75 | Designer 76 | MSBuild:Compile 77 | 78 | 79 | Designer 80 | MSBuild:Compile 81 | 82 | 83 | MSBuild:Compile 84 | Designer 85 | 86 | 87 | App.xaml 88 | Code 89 | 90 | 91 | 92 | CharacterWindow.xaml 93 | 94 | 95 | MainWindow.xaml 96 | Code 97 | 98 | 99 | Designer 100 | MSBuild:Compile 101 | 102 | 103 | Designer 104 | MSBuild:Compile 105 | 106 | 107 | 108 | 109 | 110 | Code 111 | 112 | 113 | True 114 | True 115 | Resources.resx 116 | 117 | 118 | True 119 | Settings.settings 120 | True 121 | 122 | 123 | ResXFileCodeGenerator 124 | Resources.Designer.cs 125 | 126 | 127 | SettingsSingleFileGenerator 128 | Settings.Designer.cs 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 146 | -------------------------------------------------------------------------------- /DungeonManagerWpf/MainWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.ObjectModel; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using System.Windows; 8 | using System.Windows.Controls; 9 | using System.Windows.Data; 10 | using System.Windows.Documents; 11 | using System.Windows.Input; 12 | using System.Windows.Media; 13 | using System.Windows.Media.Imaging; 14 | using System.Windows.Navigation; 15 | using System.Windows.Shapes; 16 | using System.Data; 17 | 18 | namespace DungeonManagerWpf 19 | { 20 | /// 21 | /// Interaction logic for MainWindow.xaml 22 | /// 23 | public partial class MainWindow : Window 24 | { 25 | bool _isLoaded = false; 26 | private double _aspectRatio; 27 | 28 | public MainWindow() 29 | { 30 | InitializeComponent(); 31 | Settings.LoadSettings(); 32 | RefreshCharacters(); 33 | var dice = new DiceWindow(); 34 | dice.WindowStartupLocation = WindowStartupLocation.CenterScreen; 35 | dice.Show(); 36 | } 37 | 38 | private void titlebar_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 39 | { 40 | if (e.ClickCount == 2) 41 | { 42 | Button_Click(sender, e); 43 | } 44 | else 45 | DragMove(); 46 | } 47 | 48 | protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo) 49 | { 50 | if (_isLoaded) 51 | { 52 | if (sizeInfo.WidthChanged) 53 | { 54 | this.Width = sizeInfo.NewSize.Height * _aspectRatio; 55 | } 56 | else 57 | { 58 | this.Height = sizeInfo.NewSize.Width * _aspectRatio; 59 | } 60 | } 61 | } 62 | 63 | private void MinimizeButton_Click(object sender, RoutedEventArgs e) 64 | { 65 | WindowState = WindowState.Minimized; 66 | } 67 | 68 | private void ExitButton_Click(object sender, RoutedEventArgs e) 69 | { 70 | System.Windows.Application.Current.Shutdown(); 71 | } 72 | 73 | private void Button_Click(object sender, RoutedEventArgs e) 74 | { 75 | if (WindowState == System.Windows.WindowState.Maximized) 76 | WindowState = System.Windows.WindowState.Normal; 77 | else WindowState = System.Windows.WindowState.Maximized; 78 | } 79 | 80 | 81 | public void RefreshCharacters() 82 | { 83 | CharacterDataGrid.ItemsSource = null; 84 | CharacterDataGrid.Items.Clear(); 85 | CharacterDataGrid.ItemsSource = Settings.Characters.OrderBy(c => c._sortOrder); 86 | CharacterDataGrid.UnselectAll(); 87 | } 88 | 89 | private void Window_Loaded(object sender, RoutedEventArgs e) 90 | { 91 | //RefreshCharacters(); 92 | _aspectRatio = this.ActualWidth / this.ActualHeight; 93 | _isLoaded = true; 94 | } 95 | 96 | private void CharacterDataGrid_MouseDoubleClick(object sender, MouseButtonEventArgs e) 97 | { 98 | if (CharacterDataGrid.SelectedIndex != -1) 99 | { 100 | Character c = (Character)CharacterDataGrid.SelectedItem; 101 | OpenCharacter(c); 102 | } 103 | } 104 | 105 | private void OpenCharacter(Character c) 106 | { 107 | CharacterWindow cw = new CharacterWindow(c); 108 | cw.Closed += CharacterWindow_Closed; 109 | cw.Show(); 110 | } 111 | 112 | private void CharacterDataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e) 113 | { 114 | if ((e.PropertyName == "_guid") || 115 | (e.PropertyName == "HitPoints") || 116 | (e.PropertyName == "ProficiencyBonus") || 117 | (e.PropertyName == "SpellAttackModifier") || 118 | (e.PropertyName == "_sortOrder") 119 | ) 120 | e.Cancel = true; 121 | 122 | 123 | } 124 | 125 | private void Button_Click_1(object sender, RoutedEventArgs e) 126 | { 127 | if ((CharacterDataGrid.SelectedIndex != -1) && (CharacterDataGrid.SelectedIndex != CharacterDataGrid.Items.Count - 1)) 128 | { 129 | 130 | Character currentChar = (Character)CharacterDataGrid.SelectedItem; 131 | var previousChar = (Character)CharacterDataGrid.Items[CharacterDataGrid.SelectedIndex + 1]; 132 | int tempSort = currentChar._sortOrder; 133 | currentChar._sortOrder = previousChar._sortOrder; 134 | previousChar._sortOrder = tempSort; 135 | RefreshCharacters(); 136 | } 137 | } 138 | 139 | private void UpButton_Click(object sender, RoutedEventArgs e) 140 | { 141 | if (CharacterDataGrid.SelectedIndex > 0 ) 142 | { 143 | Character currentChar = (Character)CharacterDataGrid.SelectedItem; 144 | var previousChar = (Character)CharacterDataGrid.Items[CharacterDataGrid.SelectedIndex - 1]; 145 | int tempSort = currentChar._sortOrder; 146 | currentChar._sortOrder = previousChar._sortOrder; 147 | previousChar._sortOrder = tempSort; 148 | RefreshCharacters(); 149 | } 150 | } 151 | 152 | private void Button_Click_2(object sender, RoutedEventArgs e) 153 | { 154 | OpenCharacter(new Character()); 155 | } 156 | 157 | private void CharacterWindow_Closed(object sender, EventArgs e) 158 | { 159 | RefreshCharacters(); 160 | } 161 | 162 | private void Button_Click_3(object sender, RoutedEventArgs e) 163 | { 164 | if (CharacterDataGrid.SelectedIndex != -1) 165 | { 166 | Character currentChar = (Character)CharacterDataGrid.SelectedItem; 167 | Settings.Characters.Remove(currentChar); 168 | Settings.SaveSettings(); 169 | RefreshCharacters(); 170 | } 171 | } 172 | 173 | private void Button_Click_4(object sender, RoutedEventArgs e) 174 | { 175 | if (CharacterDataGrid.SelectedIndex != -1) 176 | { 177 | Character currentChar = (Character)CharacterDataGrid.SelectedItem; 178 | OpenCharacter(currentChar); 179 | } 180 | } 181 | } 182 | 183 | } 184 | -------------------------------------------------------------------------------- /DungeonManagerWpf/Character.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace DungeonManagerWpf 8 | { 9 | [Serializable] 10 | public class Character 11 | { 12 | public string _guid { get; set; } 13 | public int _sortOrder { get; set; } 14 | public string Name { get; set; } 15 | public List Levels = new List(); 16 | public List Features = new List(); 17 | public CharacterRace Race ; 18 | public CharacterAlignment Alignment; 19 | public int HitPoints { get; set; } 20 | public int ArmorClass { get; set; } 21 | public int Strength = 10; 22 | public int Dexterity = 10; 23 | public int Constitution = 10; 24 | public int Intelligence = 10; 25 | public int Wisdom = 10; 26 | public int Charisma = 10; 27 | 28 | public int StrengthSavingThrow; 29 | public int DexteritySavingThrow; 30 | public int ConstitutionSavingThrow; 31 | public int IntelligenceSavingThrow; 32 | public int WisdomSavingThrow; 33 | public int CharismaSavingThrow; 34 | 35 | public int Initiative; 36 | public int Speed; 37 | 38 | public int Acrobatics = 0; // 0 - not proficient, 1 - proficient, 2 - double proficient 39 | public int AnimalHandling = 0; 40 | public int Arcana = 0; 41 | public int Athletics = 0; 42 | public int Deception = 0; 43 | public int History = 0; 44 | public int Insight = 0; 45 | public int Intimidation = 0; 46 | public int Investigation = 0; 47 | public int Medicine = 0; 48 | public int Nature = 0; 49 | public int Perception = 0; 50 | public int Performance = 0; 51 | public int Persuasion = 0; 52 | public int Religion = 0; 53 | public int SleightOfHand = 0; 54 | public int Stealth = 0; 55 | public int Survival = 0; 56 | 57 | public string Background; 58 | public string PersonalityTraits; 59 | public string Ideals; 60 | public string Bonds; 61 | public string Flaws; 62 | 63 | public Character() 64 | { 65 | _guid = Guid.NewGuid().ToString(); 66 | _sortOrder = (new Random()).Next(10, 30); 67 | } 68 | 69 | [System.Xml.Serialization.XmlIgnore] 70 | public int ProficiencyBonus 71 | { 72 | get 73 | { 74 | int totalLevel = Levels.Sum(item => item.LevelValue); 75 | return 2 + (totalLevel - 1) / 4; 76 | } 77 | } 78 | 79 | public static int GetModifier(int AbilityScore) 80 | { 81 | // As per DMG, 30 is the largest ability score a creature can have. 82 | if (AbilityScore < 1 || AbilityScore > 30) 83 | throw new ArgumentOutOfRangeException("Must be 1 through 30"); 84 | return (int)Math.Floor(((double)(AbilityScore - 10)) / 2.0); 85 | } 86 | 87 | private int getCastingAbilityVal() 88 | { 89 | int retVal = 0; 90 | List chaClasses = new List() { 91 | CharacterClass.Bard, 92 | CharacterClass.Sorcerer, 93 | CharacterClass.Paladin, 94 | CharacterClass.Warlock 95 | }; 96 | List intClasses = new List() { 97 | CharacterClass.Fighter, 98 | CharacterClass.Rogue, 99 | CharacterClass.Wizard 100 | }; 101 | List wisClasses = new List() { 102 | CharacterClass.Druid, 103 | CharacterClass.Ranger, 104 | CharacterClass.Monk, 105 | CharacterClass.Cleric 106 | }; 107 | 108 | foreach (Level l in Levels) 109 | { 110 | if (wisClasses.Contains(l.Class)) 111 | retVal = (GetModifier(Wisdom) > retVal) ? GetModifier(Wisdom) : retVal; 112 | if (intClasses.Contains(l.Class)) 113 | retVal = (GetModifier(Intelligence) > retVal) ? GetModifier(Intelligence) : retVal; 114 | if (chaClasses.Contains(l.Class)) 115 | retVal = (GetModifier(Charisma) > retVal) ? GetModifier(Charisma) : retVal; 116 | } 117 | return retVal; 118 | } 119 | 120 | public int SpellDC 121 | { 122 | get 123 | { 124 | return getCastingAbilityVal() + 8 + ProficiencyBonus; 125 | } 126 | } 127 | 128 | public int SpellAttackModifier 129 | { 130 | get 131 | { 132 | return getCastingAbilityVal() + ProficiencyBonus; 133 | } 134 | } 135 | 136 | public int PassivePerception 137 | { 138 | get 139 | { 140 | int retval = 10 + GetModifier(Wisdom); 141 | if (Perception == 1) 142 | retval += ProficiencyBonus; 143 | if (Perception == 2) 144 | retval += ProficiencyBonus * 2; 145 | return retval; 146 | } 147 | } 148 | 149 | } 150 | 151 | [Serializable] 152 | public class Level 153 | { 154 | public CharacterClass Class; 155 | public int LevelValue; 156 | 157 | public Level() { } 158 | 159 | public Level(CharacterClass Class, int LevelValue) 160 | { 161 | this.Class = Class; 162 | this.LevelValue = LevelValue; 163 | } 164 | 165 | public override string ToString() 166 | { 167 | return Class + " : " + LevelValue; 168 | } 169 | } 170 | 171 | [Serializable] 172 | public enum CharacterRace 173 | { 174 | Dwarf, 175 | Elf, 176 | Halfling, 177 | Human, 178 | Dragonborn, 179 | Gnome, 180 | HalfElf, 181 | HalfOrc, 182 | Tiefling, 183 | AirGenasi, 184 | EarthGenasi, 185 | WaterGenasi, 186 | FireGenasi, 187 | Arakocra, 188 | DeepGnome, 189 | Goliath 190 | } 191 | 192 | [Serializable] 193 | public enum CharacterClass 194 | { 195 | Barbarian, 196 | Bard, 197 | Cleric, 198 | Druid, 199 | Fighter, 200 | Monk, 201 | Paladin, 202 | Ranger, 203 | Rogue, 204 | Sorcerer, 205 | Warlock, 206 | Wizard 207 | } 208 | 209 | [Serializable] 210 | public enum CharacterAlignment 211 | { 212 | LawfulGood, 213 | ChaoticGood, 214 | NeutralGood, 215 | LawfulNeutral, 216 | ChaoticNeutral, 217 | TrueNeutral, 218 | LawfulEvil, 219 | ChaoticEvil, 220 | NeutralEvil 221 | } 222 | 223 | public class CharacterComparer : IComparer 224 | { 225 | public int Compare(Character a, Character b) 226 | { 227 | if (a._sortOrder > b._sortOrder) 228 | return 1; 229 | else if (a._sortOrder < b._sortOrder) 230 | return -1; 231 | else return 0; 232 | } 233 | } 234 | 235 | } 236 | -------------------------------------------------------------------------------- /DungeonManager/Form1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | using System.Xml.Serialization; 11 | using System.IO; 12 | 13 | namespace DungeonManager 14 | { 15 | public partial class Form1 : Form 16 | { 17 | public Form1() 18 | { 19 | InitializeComponent(); 20 | Settings.LoadSettings(); 21 | Settings.MainForm = this; 22 | RefreshCharacters(); 23 | } 24 | 25 | private void button1_Click(object sender, EventArgs e) 26 | { 27 | var f = new CreateCharacterForm(); 28 | f.Show(); 29 | Settings.SaveSettings(); 30 | } 31 | 32 | public void RefreshCharacters() 33 | { 34 | dataGridView1.DataSource = null; 35 | dataGridView1.Rows.Clear(); 36 | dataGridView1.Columns.Clear(); 37 | 38 | dataGridView1.Columns.Add("guid", "Guid"); 39 | dataGridView1.Columns.Add("Name", "Name"); 40 | dataGridView1.Columns.Add("Armor Class", "Armor Class"); 41 | dataGridView1.Columns.Add("Passive Perception", "Passive Perception"); 42 | dataGridView1.Columns.Add("Spell DC", "Spell DC"); 43 | 44 | for (int x = 0; x < Settings.Characters.Count; x++) 45 | { 46 | int pp = 10 + Util.GetModifier(Settings.Characters[x].Wisdom); 47 | if (Settings.Characters[x].WisdomSavingThrow) 48 | pp += Settings.Characters[x].ProficiencyBonus; 49 | int dc = Util.GetSpellDC(Settings.Characters[x]); 50 | 51 | dataGridView1.Rows.Add(Settings.Characters[x]._guid, Settings.Characters[x].Name, Settings.Characters[x].ArmorClass, pp, dc); 52 | } 53 | 54 | dataGridView1.Columns[0].Visible = false; 55 | } 56 | 57 | private void dataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e) 58 | { 59 | if (dataGridView1.SelectedRows.Count == 1) 60 | { 61 | string _guid = (string)dataGridView1.SelectedRows[0].Cells[0].Value; 62 | var c = Settings.Characters.Find(ch => ch._guid == _guid); 63 | var f = new CreateCharacterForm(c); 64 | f.Show(); 65 | 66 | } 67 | } 68 | 69 | private void saveToolStripMenuItem_Click(object sender, EventArgs e) 70 | { 71 | Settings.SaveSettings(); 72 | } 73 | 74 | private void button2_Click(object sender, EventArgs e) 75 | { 76 | if (dataGridView1.SelectedRows.Count == 1) 77 | { 78 | if (MessageBox.Show("Are you sure you want to permanently delete this character?", "DungeonManager", MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.Yes) 79 | { 80 | string _guid = (string)dataGridView1.SelectedRows[0].Cells[0].Value; 81 | int i = Settings.Characters.FindIndex(ch => ch._guid == _guid); 82 | //int rowIndex = dataGridView1.SelectedRows[0].Index; 83 | //dataGridView1.Rows.RemoveAt(rowIndex); 84 | Settings.Characters.RemoveAt(i); 85 | Settings.SaveSettings(); 86 | RefreshCharacters(); 87 | } 88 | } 89 | } 90 | 91 | private void button3_Click(object sender, EventArgs e) 92 | { 93 | if (dataGridView1.SelectedRows.Count == 1) 94 | { 95 | string _guid = (string)dataGridView1.SelectedRows[0].Cells[0].Value; 96 | var c = Settings.Characters.Find(ch => ch._guid == _guid); 97 | var f = new CreateCharacterForm(c); 98 | f.Show(); 99 | } 100 | } 101 | 102 | private void ChracterUpButton_Click(object sender, EventArgs e) 103 | { 104 | if (dataGridView1.SelectedRows.Count == 1) 105 | { 106 | int selectedRowIndex = dataGridView1.SelectedRows[0].Index; 107 | if (selectedRowIndex - 1 < 0) 108 | return; 109 | else 110 | { 111 | DataGridViewRow row = dataGridView1.SelectedRows[0]; 112 | dataGridView1.Rows.Remove(row); 113 | dataGridView1.Rows.Insert(selectedRowIndex - 1, row); 114 | dataGridView1.ClearSelection(); 115 | dataGridView1.Rows[selectedRowIndex - 1].Selected = true; 116 | } 117 | } 118 | } 119 | 120 | private void CharacterDownButton_Click(object sender, EventArgs e) 121 | { 122 | if (dataGridView1.SelectedRows.Count == 1) 123 | { 124 | int selectedRowIndex = dataGridView1.SelectedRows[0].Index; 125 | if (selectedRowIndex +1 >= dataGridView1.Rows.Count) 126 | return; 127 | else 128 | { 129 | DataGridViewRow row = dataGridView1.SelectedRows[0]; 130 | dataGridView1.Rows.Remove(row); 131 | dataGridView1.Rows.Insert(selectedRowIndex + 1, row); 132 | dataGridView1.ClearSelection(); 133 | dataGridView1.Rows[selectedRowIndex + 1].Selected = true; 134 | } 135 | } 136 | } 137 | 138 | private void saveSelectedCharacterToolStripMenuItem_Click(object sender, EventArgs e) 139 | { 140 | if (dataGridView1.SelectedRows.Count == 1) 141 | { 142 | string _guid = (string)dataGridView1.SelectedRows[0].Cells[0].Value; 143 | var c = Settings.Characters.Find(ch => ch._guid == _guid); 144 | saveFileDialog1.FileName = c.Name + ".chr"; 145 | if (saveFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK) 146 | { 147 | string settingsPath = saveFileDialog1.FileName; 148 | 149 | 150 | 151 | XmlSerializer xmlSerial = new XmlSerializer(typeof(Character)); 152 | try 153 | { 154 | using (Stream fStream = new FileStream(settingsPath, FileMode.Create, FileAccess.Write, FileShare.None)) 155 | { 156 | xmlSerial.Serialize(fStream, c); 157 | } 158 | 159 | } 160 | catch (Exception exp) 161 | { 162 | System.Windows.Forms.MessageBox.Show("Could not save character to file. Check permissions.", "DungeonManager"); 163 | } 164 | } 165 | } 166 | } 167 | 168 | private void importCharacterToolStripMenuItem_Click(object sender, EventArgs e) 169 | { 170 | if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK) 171 | { 172 | string settingsPath = openFileDialog1.FileName; 173 | try 174 | { 175 | Character XmlSave; 176 | XmlSerializer xmlSerial = new XmlSerializer(typeof(Character)); 177 | using (Stream fStream = new FileStream(settingsPath, FileMode.Open, FileAccess.Read, FileShare.None)) 178 | { 179 | XmlSave = (Character)xmlSerial.Deserialize(fStream); 180 | XmlSave._guid = Guid.NewGuid().ToString(); 181 | Settings.Characters.Add(XmlSave); 182 | Settings.SaveSettings(); 183 | RefreshCharacters(); 184 | } 185 | 186 | } 187 | catch (Exception exp) 188 | { 189 | 190 | } 191 | } 192 | } 193 | } 194 | } 195 | -------------------------------------------------------------------------------- /DungeonManagerWpf/SkillControl.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows; 7 | using System.Windows.Controls; 8 | using System.Windows.Data; 9 | using System.Windows.Documents; 10 | using System.Windows.Input; 11 | using System.Windows.Media; 12 | using System.Windows.Media.Imaging; 13 | using System.Windows.Navigation; 14 | using System.Windows.Shapes; 15 | using System.ComponentModel; 16 | using System.Collections.ObjectModel; 17 | 18 | namespace DungeonManagerWpf 19 | { 20 | /// 21 | /// Interaction logic for SkillControl.xaml 22 | /// 23 | public partial class SkillControl : UserControl 24 | { 25 | public string SkillName 26 | { 27 | get { return (string)GetValue(SkillNameProperty); } 28 | set { SetValue(SkillNameProperty, value); } 29 | } 30 | 31 | public int BaseAttribute 32 | { 33 | get { return (int)GetValue(BaseAttributeModProperty); } 34 | set { SetValue(BaseAttributeModProperty, value); } 35 | } 36 | 37 | public int ProficiencyBonus 38 | { 39 | get { return (int)GetValue(ProficiencyBonusProperty); } 40 | set { SetValue(ProficiencyBonusProperty, value); } 41 | } 42 | 43 | public Proficiency SkillProficiency 44 | { 45 | get { return (Proficiency)GetValue(SkillProficiencyProperty); } 46 | set { SetValue(SkillProficiencyProperty, value); } 47 | } 48 | 49 | private string ModifierString 50 | { 51 | get {return (string)GetValue(ModifierStringProperty);} 52 | set {SetValue(ModifierStringProperty, value);} 53 | } 54 | 55 | public bool JackOfAllTrades 56 | { 57 | get { return (bool)GetValue(JackOfAllTradesProperty); } 58 | set { SetValue(JackOfAllTradesProperty, value); } 59 | } 60 | 61 | public static readonly DependencyProperty SkillNameProperty = 62 | DependencyProperty.Register("SkillName", typeof(string), 63 | typeof(SkillControl), new PropertyMetadata("")); 64 | 65 | public static readonly DependencyProperty BaseAttributeModProperty = 66 | DependencyProperty.Register("BaseAttribute", typeof(int), 67 | typeof(SkillControl), new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.None, new PropertyChangedCallback(BaseAttributeModProperty_PropertyChanged))); 68 | 69 | public static readonly DependencyProperty JackOfAllTradesProperty = DependencyProperty.Register("JackOfAllTrades", typeof(bool), typeof(SkillControl), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.None, new PropertyChangedCallback(JackOfAllTradesProperty_PropertyChanged))); 70 | 71 | private static void JackOfAllTradesProperty_PropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) 72 | { 73 | if (args.OldValue != args.NewValue) 74 | { 75 | SkillControl c = (SkillControl)obj; 76 | c.UpdateAllValues(); 77 | } 78 | } 79 | 80 | public static readonly DependencyProperty ProficiencyBonusProperty = DependencyProperty.Register("ProficiencyBonus", typeof(int), typeof (SkillControl), new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.None, new PropertyChangedCallback(ProficiencyBonusProperty_PropertyChanged))); 81 | 82 | public static readonly DependencyProperty SkillProficiencyProperty = DependencyProperty.Register("SkillProficiency", typeof(Proficiency), typeof(SkillControl), new FrameworkPropertyMetadata(Proficiency.NotProficient, FrameworkPropertyMetadataOptions.None, new PropertyChangedCallback(SkillProficiencyProperty_PropertyChanged))); 83 | 84 | public static readonly DependencyProperty ModifierStringProperty = DependencyProperty.Register("ModifierString", typeof(string), typeof(SkillControl), new PropertyMetadata("+0")); 85 | 86 | public SkillControl() 87 | { 88 | InitializeComponent(); 89 | LayoutRoot.DataContext = this; 90 | } 91 | 92 | private static void SkillProficiencyProperty_PropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) 93 | { 94 | if (args.OldValue != args.NewValue) 95 | { 96 | SkillControl c = (SkillControl)obj; 97 | c.UpdateCheckBoxes(); 98 | } 99 | } 100 | 101 | private static void ProficiencyBonusProperty_PropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) 102 | { 103 | if (args.OldValue != args.NewValue) 104 | { 105 | SkillControl c = (SkillControl)obj; 106 | c.UpdateAllValues(); 107 | } 108 | } 109 | 110 | private static void BaseAttributeModProperty_PropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) 111 | { 112 | if (args.OldValue != args.NewValue) 113 | { 114 | SkillControl c = (SkillControl)obj; 115 | c.UpdateAllValues(); 116 | } 117 | } 118 | 119 | public bool HideExpertise 120 | { 121 | get { if (ExpertiseCheckBox.Visibility == Visibility.Visible) return true; else return false;} 122 | set { ExpertiseCheckBox.Visibility = Visibility.Hidden; } 123 | } 124 | 125 | 126 | public int ModifierValue 127 | { 128 | get 129 | { 130 | var temp = GetModifier(BaseAttribute); 131 | if (SkillProficiency == Proficiency.Proficient) 132 | temp = temp + ProficiencyBonus; 133 | else if (SkillProficiency == Proficiency.Expertise) 134 | temp = temp + ProficiencyBonus + ProficiencyBonus; 135 | else if (JackOfAllTrades) 136 | temp = temp + (int)Math.Floor((double)(ProficiencyBonus / 2)); 137 | return temp; 138 | } 139 | } 140 | 141 | 142 | 143 | private void ExpertiseCheckBox_Checked(object sender, RoutedEventArgs e) 144 | { 145 | var oldvalue = SkillProficiency; 146 | if ((ExpertiseCheckBox.IsChecked == true) && (ProficiencyCheckBox.IsChecked == false)) 147 | { 148 | ProficiencyCheckBox.IsChecked = true; 149 | } 150 | UpdateProficiencies(); 151 | UpdateAllValues(); 152 | ProficiencyChanged(new ProficiencyChangedEventArgs(SkillProficiency, oldvalue)); 153 | } 154 | 155 | private void ProficiencyCheckBox_Checked(object sender, RoutedEventArgs e) 156 | { 157 | var oldvalue = SkillProficiency; 158 | if ((ExpertiseCheckBox.IsChecked == true) && (ProficiencyCheckBox.IsChecked == false)) 159 | { 160 | ExpertiseCheckBox.IsChecked = false; 161 | 162 | } 163 | UpdateProficiencies(); 164 | UpdateAllValues(); 165 | ProficiencyChanged(new ProficiencyChangedEventArgs(SkillProficiency, oldvalue)); 166 | } 167 | 168 | private void UpdateAllValues() 169 | { 170 | var i = ModifierValue; 171 | var s = ""; 172 | if (i < 0) 173 | s = i.ToString(); 174 | else s= "+" + i; 175 | ModifierString = s; 176 | } 177 | 178 | private void UpdateProficiencies() 179 | { 180 | if ((ExpertiseCheckBox.IsChecked == true) && (ProficiencyCheckBox.IsChecked == true)) 181 | SkillProficiency = Proficiency.Expertise; 182 | else if ((ExpertiseCheckBox.IsChecked == false) && (ProficiencyCheckBox.IsChecked == true)) 183 | SkillProficiency = Proficiency.Proficient; 184 | else if ((ExpertiseCheckBox.IsChecked == false) && (ProficiencyCheckBox.IsChecked == false)) 185 | SkillProficiency = Proficiency.NotProficient; 186 | } 187 | 188 | private void UpdateCheckBoxes() 189 | { 190 | if (SkillProficiency == Proficiency.NotProficient) 191 | { 192 | ProficiencyCheckBox.IsChecked = false; 193 | ExpertiseCheckBox.IsChecked = false; 194 | } 195 | else if (SkillProficiency == Proficiency.Proficient) 196 | { 197 | ProficiencyCheckBox.IsChecked = true; 198 | ExpertiseCheckBox.IsChecked = false; 199 | } 200 | else if (SkillProficiency == Proficiency.Expertise) 201 | { 202 | ProficiencyCheckBox.IsChecked = true; 203 | ExpertiseCheckBox.IsChecked = true; 204 | } 205 | } 206 | 207 | public static int GetModifier(int AbilityScore) 208 | { 209 | // As per DMG, 30 is the largest ability score a creature can have. 210 | if (AbilityScore < 1 || AbilityScore > 30) 211 | return 0; 212 | //throw new ArgumentOutOfRangeException("Must be 1 through 30"); 213 | return (int)Math.Floor(((double)(AbilityScore - 10)) / 2.0); 214 | } 215 | 216 | private EventHandler _onProficiencyChangedEvent; 217 | public event EventHandler OnProficiencyChangedEvent 218 | { 219 | add { _onProficiencyChangedEvent += value; } 220 | remove { _onProficiencyChangedEvent -= value; } 221 | } 222 | 223 | private void ProficiencyChanged(ProficiencyChangedEventArgs args) 224 | { 225 | _onProficiencyChangedEvent?.Invoke(this, args); 226 | } 227 | 228 | } 229 | 230 | public class ProficiencyChangedEventArgs : EventArgs 231 | { 232 | public Proficiency NewValue; 233 | public Proficiency OldValue; 234 | 235 | public ProficiencyChangedEventArgs(Proficiency NewValue, Proficiency OldValue) 236 | { 237 | this.NewValue = NewValue; 238 | this.OldValue = OldValue; 239 | } 240 | } 241 | 242 | public enum Proficiency : byte 243 | { 244 | NotProficient = 0, 245 | Proficient = 1, 246 | Expertise = 2 247 | } 248 | 249 | } 250 | -------------------------------------------------------------------------------- /DungeonManagerWpf/DiceWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows; 7 | using System.Windows.Controls; 8 | using System.Windows.Data; 9 | using System.Windows.Documents; 10 | using System.Windows.Input; 11 | using System.Windows.Media; 12 | using System.Windows.Media.Imaging; 13 | using System.Windows.Shapes; 14 | 15 | namespace DungeonManagerWpf 16 | { 17 | /// 18 | /// Interaction logic for DiceWindow.xaml 19 | /// 20 | public partial class DiceWindow : Window 21 | { 22 | int d4 = 0; 23 | int d6 = 0; 24 | int d8 = 0; 25 | int d10 = 0; 26 | int d12 = 0; 27 | int d20 = 0; 28 | int d100 = 0; 29 | private double _aspectRatio; 30 | private bool _isLoaded; 31 | 32 | public DiceWindow() 33 | { 34 | InitializeComponent(); 35 | } 36 | 37 | public void DisplayActiveDice() 38 | { 39 | 40 | ActiveDiceTextBox.Text = ""; 41 | string text = ""; 42 | if (d4 > 0) 43 | text += "D4: " + d4 + " "; 44 | if (d6 > 0) 45 | text += "D6: " + d6 + " "; 46 | if (d8 > 0) 47 | text += "D8: " + d8 + " "; 48 | if (d10 > 0) 49 | text += "D10: " + d10 + " "; 50 | if (d12 > 0) 51 | text += "D12: " + d12 + " "; 52 | if (d20 > 0) 53 | text += "D20: " + d20 + " "; 54 | if (d100 > 0) 55 | text += "D100: " + d100; 56 | ActiveDiceTextBox.Text = text; 57 | } 58 | 59 | private void PlusD4Button_Click(object sender, RoutedEventArgs e) 60 | { 61 | d4++; 62 | DisplayActiveDice(); 63 | } 64 | 65 | private void PlusD6Button_Click(object sender, RoutedEventArgs e) 66 | { 67 | d6++; 68 | DisplayActiveDice(); 69 | } 70 | 71 | private void PlusD8Button_Click(object sender, RoutedEventArgs e) 72 | { 73 | d8++; 74 | DisplayActiveDice(); 75 | } 76 | 77 | private void PlusD10Button_Click(object sender, RoutedEventArgs e) 78 | { 79 | d10++; 80 | DisplayActiveDice(); 81 | } 82 | 83 | private void PlusD12Button_Click(object sender, RoutedEventArgs e) 84 | { 85 | d12++; 86 | DisplayActiveDice(); 87 | } 88 | 89 | private void PlusD20Button_Click(object sender, RoutedEventArgs e) 90 | { 91 | d20++; 92 | DisplayActiveDice(); 93 | } 94 | 95 | private void PlusD100Button_Click(object sender, RoutedEventArgs e) 96 | { 97 | d100++; 98 | DisplayActiveDice(); 99 | } 100 | 101 | private void MinusD4Button_Click(object sender, RoutedEventArgs e) 102 | { 103 | if (d4 > 0) 104 | { 105 | d4--; 106 | DisplayActiveDice(); 107 | } 108 | } 109 | 110 | private void MinusD6Button_Click(object sender, RoutedEventArgs e) 111 | { 112 | if (d6 > 0) 113 | { 114 | d6--; 115 | DisplayActiveDice(); 116 | } 117 | } 118 | 119 | private void MinusD8Button_Click(object sender, RoutedEventArgs e) 120 | { 121 | if (d8 > 0) 122 | { 123 | d8--; 124 | DisplayActiveDice(); 125 | } 126 | } 127 | 128 | private void MinusD10Button_Click(object sender, RoutedEventArgs e) 129 | { 130 | if (d10 > 0) 131 | { 132 | d10--; 133 | DisplayActiveDice(); 134 | } 135 | } 136 | 137 | private void MinusD12Button_Click(object sender, RoutedEventArgs e) 138 | { 139 | if (d12 > 0) 140 | { 141 | d12--; 142 | DisplayActiveDice(); 143 | } 144 | } 145 | 146 | private void MinusD20Button_Click(object sender, RoutedEventArgs e) 147 | { 148 | if (d20 > 0) 149 | { 150 | d20--; 151 | DisplayActiveDice(); 152 | } 153 | } 154 | 155 | private void MinusD100Button_Click(object sender, RoutedEventArgs e) 156 | { 157 | if (d100 > 0) 158 | { 159 | d100--; 160 | DisplayActiveDice(); 161 | } 162 | } 163 | 164 | public void Roll() 165 | { 166 | 167 | OutputTextBox.Text = ""; 168 | int grandTotal = 0; 169 | Random rand = new Random(); 170 | if (d4 > 0) 171 | { 172 | int total = 0; 173 | for (int x = 0; x < d4; x++) 174 | { 175 | int val = rand.Next(1, 4); 176 | total += val; 177 | OutputTextBox.AppendText(val + ", "); 178 | } 179 | grandTotal += total; 180 | OutputTextBox.Text = OutputTextBox.Text.Remove(OutputTextBox.Text.Length - 2); 181 | OutputTextBox.AppendText("\r\n"); 182 | OutputTextBox.AppendText("D4 total: " + total + "\r\n"); 183 | } 184 | 185 | if (d6 > 0) 186 | { 187 | int total = 0; 188 | for (int x = 0; x < d6; x++) 189 | { 190 | int val = rand.Next(1, 6); 191 | total += val; 192 | OutputTextBox.AppendText(val + ", "); 193 | } 194 | grandTotal += total; 195 | OutputTextBox.Text = OutputTextBox.Text.Remove(OutputTextBox.Text.Length - 2); 196 | OutputTextBox.AppendText("\r\n"); 197 | OutputTextBox.AppendText("D6 total: " + total + "\r\n"); 198 | } 199 | 200 | if (d8 > 0) 201 | { 202 | int total = 0; 203 | for (int x = 0; x < d8; x++) 204 | { 205 | int val = rand.Next(1, 8); 206 | total += val; 207 | OutputTextBox.AppendText(val + ", "); 208 | } 209 | grandTotal += total; 210 | OutputTextBox.Text = OutputTextBox.Text.Remove(OutputTextBox.Text.Length - 2); 211 | OutputTextBox.AppendText("\r\n"); 212 | OutputTextBox.AppendText("D8 total: " + total + "\r\n"); 213 | } 214 | 215 | if (d10 > 0) 216 | { 217 | int total = 0; 218 | for (int x = 0; x < d10; x++) 219 | { 220 | int val = rand.Next(1, 10); 221 | total += val; 222 | OutputTextBox.AppendText(val + ", "); 223 | } 224 | grandTotal += total; 225 | OutputTextBox.Text = OutputTextBox.Text.Remove(OutputTextBox.Text.Length - 2); 226 | OutputTextBox.AppendText("\r\n"); 227 | OutputTextBox.AppendText("D10 total: " + total + "\r\n"); 228 | } 229 | 230 | if (d12 > 0) 231 | { 232 | int total = 0; 233 | for (int x = 0; x < d12; x++) 234 | { 235 | int val = rand.Next(1, 12); 236 | total += val; 237 | OutputTextBox.AppendText(val + ", "); 238 | } 239 | grandTotal += total; 240 | OutputTextBox.Text = OutputTextBox.Text.Remove(OutputTextBox.Text.Length - 2); 241 | OutputTextBox.AppendText("\r\n"); 242 | OutputTextBox.AppendText("D12 total: " + total + "\r\n"); 243 | } 244 | 245 | if (d20 > 0) 246 | { 247 | int total = 0; 248 | for (int x = 0; x < d20; x++) 249 | { 250 | int val = rand.Next(1, 20); 251 | total += val; 252 | OutputTextBox.AppendText(val + ", "); 253 | } 254 | grandTotal += total; 255 | OutputTextBox.Text = OutputTextBox.Text.Remove(OutputTextBox.Text.Length - 2); 256 | OutputTextBox.AppendText("\r\n"); 257 | OutputTextBox.AppendText("D20 total: " + total + "\r\n"); 258 | } 259 | 260 | if (d100 > 0) 261 | { 262 | int total = 0; 263 | for (int x = 0; x < d100; x++) 264 | { 265 | int val = rand.Next(1, 100); 266 | total += val; 267 | OutputTextBox.AppendText(val + ", "); 268 | } 269 | grandTotal += total; 270 | OutputTextBox.Text = OutputTextBox.Text.Remove(OutputTextBox.Text.Length - 2); 271 | OutputTextBox.AppendText("\r\n"); 272 | OutputTextBox.AppendText("D100 total: " + total + "\r\n"); 273 | } 274 | 275 | OutputTextBox.AppendText("Grand Total: " + grandTotal); 276 | } 277 | 278 | private void ClearAllButton_Click(object sender, RoutedEventArgs e) 279 | { 280 | d4 = 0; 281 | d6 = 0; 282 | d8 = 0; 283 | d10 = 0; 284 | d12 = 0; 285 | d20 = 0; 286 | d100 = 0; 287 | OutputTextBox.Text = String.Empty; 288 | ActiveDiceTextBox.Text = String.Empty; 289 | } 290 | 291 | private void RollButton_Click(object sender, RoutedEventArgs e) 292 | { 293 | Roll(); 294 | } 295 | 296 | protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo) 297 | { 298 | if (_isLoaded) 299 | { 300 | if (sizeInfo.WidthChanged) 301 | { 302 | this.Width = sizeInfo.NewSize.Height * _aspectRatio; 303 | } 304 | else 305 | { 306 | this.Height = sizeInfo.NewSize.Width * _aspectRatio; 307 | } 308 | } 309 | } 310 | 311 | private void Window_Loaded(object sender, RoutedEventArgs e) 312 | { 313 | _aspectRatio = this.ActualWidth / this.ActualHeight; 314 | _isLoaded = true; 315 | } 316 | } 317 | } 318 | -------------------------------------------------------------------------------- /DungeonManager/Form1.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace DungeonManager 2 | { 3 | partial class Form1 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1)); 32 | this.dataGridView1 = new System.Windows.Forms.DataGridView(); 33 | this.button3 = new System.Windows.Forms.Button(); 34 | this.ChracterUpButton = new System.Windows.Forms.Button(); 35 | this.CharacterDownButton = new System.Windows.Forms.Button(); 36 | this.menuStrip1 = new System.Windows.Forms.MenuStrip(); 37 | this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 38 | this.saveSelectedCharacterToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 39 | this.importCharacterToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 40 | this.editToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 41 | this.addNewCharacterToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 42 | this.deleteSelectedCharacterToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 43 | this.splitContainer1 = new System.Windows.Forms.SplitContainer(); 44 | this.splitContainer2 = new System.Windows.Forms.SplitContainer(); 45 | this.splitContainer3 = new System.Windows.Forms.SplitContainer(); 46 | this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog(); 47 | this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog(); 48 | ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit(); 49 | this.menuStrip1.SuspendLayout(); 50 | ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); 51 | this.splitContainer1.Panel1.SuspendLayout(); 52 | this.splitContainer1.Panel2.SuspendLayout(); 53 | this.splitContainer1.SuspendLayout(); 54 | ((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).BeginInit(); 55 | this.splitContainer2.Panel1.SuspendLayout(); 56 | this.splitContainer2.Panel2.SuspendLayout(); 57 | this.splitContainer2.SuspendLayout(); 58 | ((System.ComponentModel.ISupportInitialize)(this.splitContainer3)).BeginInit(); 59 | this.splitContainer3.Panel1.SuspendLayout(); 60 | this.splitContainer3.Panel2.SuspendLayout(); 61 | this.splitContainer3.SuspendLayout(); 62 | this.SuspendLayout(); 63 | // 64 | // dataGridView1 65 | // 66 | this.dataGridView1.AllowUserToAddRows = false; 67 | this.dataGridView1.AllowUserToDeleteRows = false; 68 | this.dataGridView1.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.ColumnHeader; 69 | this.dataGridView1.BackgroundColor = System.Drawing.SystemColors.Control; 70 | this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; 71 | this.dataGridView1.Dock = System.Windows.Forms.DockStyle.Fill; 72 | this.dataGridView1.EditMode = System.Windows.Forms.DataGridViewEditMode.EditProgrammatically; 73 | this.dataGridView1.Location = new System.Drawing.Point(0, 0); 74 | this.dataGridView1.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2); 75 | this.dataGridView1.Name = "dataGridView1"; 76 | this.dataGridView1.RowHeadersVisible = false; 77 | this.dataGridView1.RowTemplate.Height = 28; 78 | this.dataGridView1.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; 79 | this.dataGridView1.Size = new System.Drawing.Size(350, 275); 80 | this.dataGridView1.TabIndex = 2; 81 | this.dataGridView1.CellDoubleClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView1_CellDoubleClick); 82 | // 83 | // button3 84 | // 85 | this.button3.Dock = System.Windows.Forms.DockStyle.Fill; 86 | this.button3.Location = new System.Drawing.Point(0, 0); 87 | this.button3.Name = "button3"; 88 | this.button3.Size = new System.Drawing.Size(402, 50); 89 | this.button3.TabIndex = 5; 90 | this.button3.Text = "Open Selected Character"; 91 | this.button3.UseVisualStyleBackColor = true; 92 | this.button3.Click += new System.EventHandler(this.button3_Click); 93 | // 94 | // ChracterUpButton 95 | // 96 | this.ChracterUpButton.Dock = System.Windows.Forms.DockStyle.Fill; 97 | this.ChracterUpButton.Location = new System.Drawing.Point(0, 0); 98 | this.ChracterUpButton.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2); 99 | this.ChracterUpButton.Name = "ChracterUpButton"; 100 | this.ChracterUpButton.Size = new System.Drawing.Size(48, 140); 101 | this.ChracterUpButton.TabIndex = 6; 102 | this.ChracterUpButton.Text = "/\\"; 103 | this.ChracterUpButton.UseVisualStyleBackColor = true; 104 | this.ChracterUpButton.Click += new System.EventHandler(this.ChracterUpButton_Click); 105 | // 106 | // CharacterDownButton 107 | // 108 | this.CharacterDownButton.Dock = System.Windows.Forms.DockStyle.Fill; 109 | this.CharacterDownButton.Location = new System.Drawing.Point(0, 0); 110 | this.CharacterDownButton.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2); 111 | this.CharacterDownButton.Name = "CharacterDownButton"; 112 | this.CharacterDownButton.Size = new System.Drawing.Size(48, 141); 113 | this.CharacterDownButton.TabIndex = 7; 114 | this.CharacterDownButton.Text = "\\/"; 115 | this.CharacterDownButton.UseVisualStyleBackColor = true; 116 | this.CharacterDownButton.Click += new System.EventHandler(this.CharacterDownButton_Click); 117 | // 118 | // menuStrip1 119 | // 120 | this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { 121 | this.fileToolStripMenuItem, 122 | this.editToolStripMenuItem}); 123 | this.menuStrip1.Location = new System.Drawing.Point(0, 0); 124 | this.menuStrip1.Name = "menuStrip1"; 125 | this.menuStrip1.Size = new System.Drawing.Size(402, 24); 126 | this.menuStrip1.TabIndex = 8; 127 | this.menuStrip1.Text = "menuStrip1"; 128 | // 129 | // fileToolStripMenuItem 130 | // 131 | this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { 132 | this.saveSelectedCharacterToolStripMenuItem, 133 | this.importCharacterToolStripMenuItem}); 134 | this.fileToolStripMenuItem.Name = "fileToolStripMenuItem"; 135 | this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20); 136 | this.fileToolStripMenuItem.Text = "File"; 137 | // 138 | // saveSelectedCharacterToolStripMenuItem 139 | // 140 | this.saveSelectedCharacterToolStripMenuItem.Name = "saveSelectedCharacterToolStripMenuItem"; 141 | this.saveSelectedCharacterToolStripMenuItem.Size = new System.Drawing.Size(212, 22); 142 | this.saveSelectedCharacterToolStripMenuItem.Text = "Export Selected Character"; 143 | this.saveSelectedCharacterToolStripMenuItem.Click += new System.EventHandler(this.saveSelectedCharacterToolStripMenuItem_Click); 144 | // 145 | // importCharacterToolStripMenuItem 146 | // 147 | this.importCharacterToolStripMenuItem.Name = "importCharacterToolStripMenuItem"; 148 | this.importCharacterToolStripMenuItem.Size = new System.Drawing.Size(212, 22); 149 | this.importCharacterToolStripMenuItem.Text = "Import Character from file"; 150 | this.importCharacterToolStripMenuItem.Click += new System.EventHandler(this.importCharacterToolStripMenuItem_Click); 151 | // 152 | // editToolStripMenuItem 153 | // 154 | this.editToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { 155 | this.addNewCharacterToolStripMenuItem, 156 | this.deleteSelectedCharacterToolStripMenuItem}); 157 | this.editToolStripMenuItem.Name = "editToolStripMenuItem"; 158 | this.editToolStripMenuItem.Size = new System.Drawing.Size(39, 20); 159 | this.editToolStripMenuItem.Text = "Edit"; 160 | // 161 | // addNewCharacterToolStripMenuItem 162 | // 163 | this.addNewCharacterToolStripMenuItem.Name = "addNewCharacterToolStripMenuItem"; 164 | this.addNewCharacterToolStripMenuItem.Size = new System.Drawing.Size(208, 22); 165 | this.addNewCharacterToolStripMenuItem.Text = "Create New Character"; 166 | this.addNewCharacterToolStripMenuItem.Click += new System.EventHandler(this.button1_Click); 167 | // 168 | // deleteSelectedCharacterToolStripMenuItem 169 | // 170 | this.deleteSelectedCharacterToolStripMenuItem.Name = "deleteSelectedCharacterToolStripMenuItem"; 171 | this.deleteSelectedCharacterToolStripMenuItem.Size = new System.Drawing.Size(208, 22); 172 | this.deleteSelectedCharacterToolStripMenuItem.Text = "Delete Selected Character"; 173 | this.deleteSelectedCharacterToolStripMenuItem.Click += new System.EventHandler(this.button2_Click); 174 | // 175 | // splitContainer1 176 | // 177 | this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; 178 | this.splitContainer1.IsSplitterFixed = true; 179 | this.splitContainer1.Location = new System.Drawing.Point(0, 24); 180 | this.splitContainer1.Name = "splitContainer1"; 181 | this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal; 182 | // 183 | // splitContainer1.Panel1 184 | // 185 | this.splitContainer1.Panel1.Controls.Add(this.splitContainer2); 186 | // 187 | // splitContainer1.Panel2 188 | // 189 | this.splitContainer1.Panel2.Controls.Add(this.button3); 190 | this.splitContainer1.Panel2MinSize = 50; 191 | this.splitContainer1.Size = new System.Drawing.Size(402, 329); 192 | this.splitContainer1.SplitterDistance = 275; 193 | this.splitContainer1.TabIndex = 9; 194 | // 195 | // splitContainer2 196 | // 197 | this.splitContainer2.Dock = System.Windows.Forms.DockStyle.Fill; 198 | this.splitContainer2.Location = new System.Drawing.Point(0, 0); 199 | this.splitContainer2.Name = "splitContainer2"; 200 | // 201 | // splitContainer2.Panel1 202 | // 203 | this.splitContainer2.Panel1.Controls.Add(this.dataGridView1); 204 | // 205 | // splitContainer2.Panel2 206 | // 207 | this.splitContainer2.Panel2.Controls.Add(this.splitContainer3); 208 | this.splitContainer2.Panel2MinSize = 40; 209 | this.splitContainer2.Size = new System.Drawing.Size(402, 275); 210 | this.splitContainer2.SplitterDistance = 350; 211 | this.splitContainer2.TabIndex = 0; 212 | // 213 | // splitContainer3 214 | // 215 | this.splitContainer3.Dock = System.Windows.Forms.DockStyle.Fill; 216 | this.splitContainer3.Location = new System.Drawing.Point(0, 0); 217 | this.splitContainer3.MinimumSize = new System.Drawing.Size(48, 285); 218 | this.splitContainer3.Name = "splitContainer3"; 219 | this.splitContainer3.Orientation = System.Windows.Forms.Orientation.Horizontal; 220 | // 221 | // splitContainer3.Panel1 222 | // 223 | this.splitContainer3.Panel1.Controls.Add(this.ChracterUpButton); 224 | // 225 | // splitContainer3.Panel2 226 | // 227 | this.splitContainer3.Panel2.Controls.Add(this.CharacterDownButton); 228 | this.splitContainer3.Size = new System.Drawing.Size(48, 285); 229 | this.splitContainer3.SplitterDistance = 140; 230 | this.splitContainer3.TabIndex = 8; 231 | // 232 | // saveFileDialog1 233 | // 234 | this.saveFileDialog1.DefaultExt = "chr"; 235 | this.saveFileDialog1.Filter = "Character File (*.chr)|*.chr"; 236 | this.saveFileDialog1.Tag = ""; 237 | // 238 | // openFileDialog1 239 | // 240 | this.openFileDialog1.DefaultExt = "chr"; 241 | this.openFileDialog1.FileName = "openFileDialog1"; 242 | this.openFileDialog1.Filter = "Character File (*.chr)|*.chr"; 243 | // 244 | // Form1 245 | // 246 | this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); 247 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; 248 | this.ClientSize = new System.Drawing.Size(402, 353); 249 | this.Controls.Add(this.splitContainer1); 250 | this.Controls.Add(this.menuStrip1); 251 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow; 252 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 253 | this.MainMenuStrip = this.menuStrip1; 254 | this.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2); 255 | this.Name = "Form1"; 256 | this.Text = "DungeonManager"; 257 | ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit(); 258 | this.menuStrip1.ResumeLayout(false); 259 | this.menuStrip1.PerformLayout(); 260 | this.splitContainer1.Panel1.ResumeLayout(false); 261 | this.splitContainer1.Panel2.ResumeLayout(false); 262 | ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit(); 263 | this.splitContainer1.ResumeLayout(false); 264 | this.splitContainer2.Panel1.ResumeLayout(false); 265 | this.splitContainer2.Panel2.ResumeLayout(false); 266 | ((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).EndInit(); 267 | this.splitContainer2.ResumeLayout(false); 268 | this.splitContainer3.Panel1.ResumeLayout(false); 269 | this.splitContainer3.Panel2.ResumeLayout(false); 270 | ((System.ComponentModel.ISupportInitialize)(this.splitContainer3)).EndInit(); 271 | this.splitContainer3.ResumeLayout(false); 272 | this.ResumeLayout(false); 273 | this.PerformLayout(); 274 | 275 | } 276 | 277 | #endregion 278 | 279 | private System.Windows.Forms.DataGridView dataGridView1; 280 | private System.Windows.Forms.Button button3; 281 | private System.Windows.Forms.Button ChracterUpButton; 282 | private System.Windows.Forms.Button CharacterDownButton; 283 | private System.Windows.Forms.MenuStrip menuStrip1; 284 | private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem; 285 | private System.Windows.Forms.ToolStripMenuItem saveSelectedCharacterToolStripMenuItem; 286 | private System.Windows.Forms.ToolStripMenuItem importCharacterToolStripMenuItem; 287 | private System.Windows.Forms.ToolStripMenuItem editToolStripMenuItem; 288 | private System.Windows.Forms.ToolStripMenuItem deleteSelectedCharacterToolStripMenuItem; 289 | private System.Windows.Forms.ToolStripMenuItem addNewCharacterToolStripMenuItem; 290 | private System.Windows.Forms.SplitContainer splitContainer1; 291 | private System.Windows.Forms.SplitContainer splitContainer2; 292 | private System.Windows.Forms.SplitContainer splitContainer3; 293 | private System.Windows.Forms.SaveFileDialog saveFileDialog1; 294 | private System.Windows.Forms.OpenFileDialog openFileDialog1; 295 | } 296 | } 297 | 298 | -------------------------------------------------------------------------------- /DungeonManagerWpf/CharacterWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Text.RegularExpressions; 6 | using System.Threading.Tasks; 7 | using System.Windows; 8 | using System.Windows.Controls; 9 | using System.Windows.Data; 10 | using System.Windows.Documents; 11 | using System.Windows.Input; 12 | using System.Windows.Media; 13 | using System.Windows.Media.Imaging; 14 | using System.Windows.Shapes; 15 | 16 | namespace DungeonManagerWpf 17 | { 18 | /// 19 | /// Interaction logic for CharacterWindow.xaml 20 | /// 21 | public partial class CharacterWindow : Window 22 | { 23 | private Character _character; 24 | bool _changeOccured = false; 25 | private bool _isLoaded; 26 | private double _aspectRatio; 27 | 28 | public CharacterWindow(Character c) 29 | { 30 | this.DataContext = this; 31 | InitializeComponent(); 32 | this.WindowStartupLocation = WindowStartupLocation.Manual; 33 | this.Top = 0; 34 | this.Left = 0; 35 | this._character = c; 36 | 37 | } 38 | 39 | private void LoadCharacter(Character c) 40 | { 41 | this._character = c; 42 | LevelsListBox.ItemsSource = c.Levels; 43 | FeaturesListBox.ItemsSource = c.Features; 44 | CheckForJackOfAllTrades(); 45 | ProficiencyNumeric.Content = c.ProficiencyBonus; 46 | NameTextBox.Text = c.Name; 47 | RaceComboBox.SelectedItem = c.Race; 48 | AlignmentComboBox.SelectedItem = c.Alignment; 49 | AcrobaticsSkill.SkillProficiency = (Proficiency)c.Acrobatics; 50 | AnimalHandlingSkill.SkillProficiency = (Proficiency)c.AnimalHandling; 51 | ArcanaSkill.SkillProficiency = (Proficiency)c.Arcana; 52 | AthleticsSkill.SkillProficiency = (Proficiency)c.Athletics; 53 | DeceptionSkill.SkillProficiency = (Proficiency)c.Deception; 54 | HistorySkill.SkillProficiency = (Proficiency)c.History; 55 | InsightSkill.SkillProficiency = (Proficiency)c.Insight; 56 | IntimidationSkill.SkillProficiency = (Proficiency)c.Intimidation; 57 | InvestigationSkill.SkillProficiency = (Proficiency)c.Investigation; 58 | MedicineSkill.SkillProficiency = (Proficiency)c.Medicine; 59 | NatureSkill.SkillProficiency = (Proficiency)c.Nature; 60 | PerceptionSkill.SkillProficiency = (Proficiency)c.Perception; 61 | PersuasionSkill.SkillProficiency = (Proficiency)c.Persuasion; 62 | ReligionSkill.SkillProficiency = (Proficiency)c.Religion; 63 | SleightOfHandSkill.SkillProficiency = (Proficiency)c.SleightOfHand; 64 | StealthSkill.SkillProficiency = (Proficiency)c.Stealth; 65 | SurvivalSkill.SkillProficiency = (Proficiency)c.Survival; 66 | StrengthSavingThrow.SkillProficiency = (Proficiency)c.StrengthSavingThrow; 67 | DexteritySavingThrow.SkillProficiency = (Proficiency)c.DexteritySavingThrow; 68 | ConstitutionSavingThrow.SkillProficiency = (Proficiency)c.ConstitutionSavingThrow; 69 | IntelligenceSavingThrow.SkillProficiency = (Proficiency)c.IntelligenceSavingThrow; 70 | WisdomSavingThrow.SkillProficiency = (Proficiency)c.WisdomSavingThrow; 71 | CharismaSavingThrow.SkillProficiency = (Proficiency)c.CharismaSavingThrow; 72 | 73 | StrengthAttribute.AttributeValue = c.Strength; 74 | DexterityAttribute.AttributeValue = c.Dexterity; 75 | ConstitutionAttribute.AttributeValue = c.Constitution; 76 | IntelligenceAttribute.AttributeValue = c.Intelligence; 77 | WisdomAttribute.AttributeValue = c.Wisdom; 78 | CharismaAttribute.AttributeValue = c.Charisma; 79 | 80 | ArmorClassNumeric.Value = c.ArmorClass; 81 | SpeedTextBox.Text = c.Speed.ToString(); 82 | SpellSaveLabel.Content = c.SpellDC.ToString(); 83 | SpellAttackLabel.Content = c.SpellAttackModifier.ToString(); 84 | PassivePerceptionLabel.Content = c.PassivePerception; 85 | InitiativeNumeric.Value = c.Initiative; 86 | HitPointsTextBox.Text = c.HitPoints.ToString(); 87 | 88 | 89 | PersonalityTextBox.Text = c.PersonalityTraits; 90 | IdealsTextBox.Text = c.Ideals; 91 | BondsTextBox.Text = c.Bonds; 92 | FlawsTextBox.Text = c.Flaws; 93 | BackgroundTextBox.Text = c.Background; 94 | _changeOccured = false; 95 | } 96 | 97 | protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo) 98 | { 99 | if (_isLoaded) 100 | { 101 | if (sizeInfo.WidthChanged) 102 | { 103 | this.Width = sizeInfo.NewSize.Height * _aspectRatio; 104 | } 105 | else 106 | { 107 | this.Height = sizeInfo.NewSize.Width * _aspectRatio; 108 | } 109 | } 110 | } 111 | 112 | private void SaveCharacter(Character c) 113 | { 114 | 115 | int i = Settings.Characters.FindIndex(ch => ch._guid == c._guid); 116 | if (i != -1) 117 | Settings.Characters.RemoveAt(i); 118 | Settings.Characters.Add(c); 119 | Settings.SaveSettings(); 120 | } 121 | 122 | private void titlebar_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 123 | { 124 | if (e.ClickCount == 2) 125 | { 126 | Button_Click(sender, e); 127 | } 128 | else 129 | DragMove(); 130 | } 131 | 132 | private void MinimizeButton_Click(object sender, RoutedEventArgs e) 133 | { 134 | WindowState = WindowState.Minimized; 135 | } 136 | 137 | private void ExitButton_Click(object sender, RoutedEventArgs e) 138 | { 139 | this.Close(); 140 | } 141 | 142 | private void Button_Click(object sender, RoutedEventArgs e) 143 | { 144 | if (WindowState == System.Windows.WindowState.Maximized) 145 | WindowState = System.Windows.WindowState.Normal; 146 | else WindowState = System.Windows.WindowState.Maximized; 147 | } 148 | 149 | private void Window_Loaded(object sender, RoutedEventArgs e) 150 | { 151 | _aspectRatio = this.ActualWidth / this.ActualHeight; 152 | _isLoaded = true; 153 | LoadCharacter(_character); 154 | } 155 | 156 | private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) 157 | { 158 | if (_changeOccured) 159 | { 160 | var result = MessageBox.Show("Save changes?", "DungeonManager", MessageBoxButton.YesNoCancel); 161 | if (result == MessageBoxResult.Yes) 162 | { 163 | SaveCharacter(_character); 164 | } 165 | else if (result == MessageBoxResult.Cancel) 166 | { 167 | e.Cancel = true; 168 | } 169 | } 170 | } 171 | 172 | private void NameTextBox_TextChanged(object sender, TextChangedEventArgs e) 173 | { 174 | _character.Name = NameTextBox.Text; 175 | _changeOccured = true; 176 | } 177 | 178 | private void AlignmentComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) 179 | { 180 | _character.Alignment = (CharacterAlignment)AlignmentComboBox.SelectedItem; 181 | _changeOccured = true; 182 | } 183 | 184 | private void RaceComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) 185 | { 186 | _character.Race = (CharacterRace)RaceComboBox.SelectedItem; 187 | } 188 | 189 | private void StrengthAttribute_OnValueChangedEvent(object sender, ValueChangedEventArgs e) 190 | { 191 | _character.Strength = e.NewValue; 192 | _changeOccured = true; 193 | } 194 | 195 | private void DexterityAttribute_OnValueChangedEvent(object sender, ValueChangedEventArgs e) 196 | { 197 | _character.Dexterity = e.NewValue; 198 | _changeOccured = true; 199 | } 200 | 201 | private void ConstitutionAttribute_OnValueChangedEvent(object sender, ValueChangedEventArgs e) 202 | { 203 | _character.Constitution = e.NewValue; 204 | _changeOccured = true; 205 | } 206 | 207 | private void IntelligenceAttribute_OnValueChangedEvent(object sender, ValueChangedEventArgs e) 208 | { 209 | _character.Intelligence = e.NewValue; 210 | _changeOccured = true; 211 | } 212 | 213 | private void WisdomAttribute_OnValueChangedEvent(object sender, ValueChangedEventArgs e) 214 | { 215 | _character.Wisdom = e.NewValue; 216 | _changeOccured = true; 217 | } 218 | 219 | private void CharismaAttribute_OnValueChangedEvent(object sender, ValueChangedEventArgs e) 220 | { 221 | _character.Charisma = e.NewValue; 222 | _changeOccured = true; 223 | } 224 | 225 | private void ArmorClassNumeric_OnValueChangedEvent(object sender, ValueChangedEventArgs e) 226 | { 227 | _character.ArmorClass = e.NewValue; 228 | _changeOccured = true; 229 | } 230 | 231 | private void InitiativeNumeric_OnValueChangedEvent(object sender, ValueChangedEventArgs e) 232 | { 233 | _character.Initiative = e.NewValue; 234 | _changeOccured = true; 235 | } 236 | 237 | private void SpeedTextBox_TextChanged(object sender, TextChangedEventArgs e) 238 | { 239 | if (SpeedTextBox.Text != "") 240 | { 241 | _character.Speed = Int32.Parse(SpeedTextBox.Text); 242 | _changeOccured = true; 243 | } 244 | } 245 | 246 | private static bool IsNumber(string text) 247 | { 248 | Regex regex = new Regex("[^0-9]+"); 249 | return regex.IsMatch(text); 250 | } 251 | 252 | private void SpeedTextBox_PreviewTextInput(object sender, TextCompositionEventArgs e) 253 | { 254 | e.Handled = IsNumber(e.Text); 255 | } 256 | 257 | private void StrengthSavingThrow_OnProficiencyChangedEvent(object sender, ProficiencyChangedEventArgs e) 258 | { 259 | _character.StrengthSavingThrow = (int)e.NewValue; 260 | _changeOccured = true; 261 | } 262 | 263 | private void DexteritySavingThrow_OnProficiencyChangedEvent(object sender, ProficiencyChangedEventArgs e) 264 | { 265 | _character.DexteritySavingThrow = (int)e.NewValue; 266 | _changeOccured = true; 267 | } 268 | 269 | private void ConstitutionSavingThrow_OnProficiencyChangedEvent(object sender, ProficiencyChangedEventArgs e) 270 | { 271 | _character.ConstitutionSavingThrow = (int)e.NewValue; 272 | _changeOccured = true; 273 | } 274 | 275 | private void IntelligenceSavingThrow_OnProficiencyChangedEvent(object sender, ProficiencyChangedEventArgs e) 276 | { 277 | _character.IntelligenceSavingThrow = (int)e.NewValue; 278 | _changeOccured = true; 279 | } 280 | 281 | private void WisdomSavingThrow_OnProficiencyChangedEvent(object sender, ProficiencyChangedEventArgs e) 282 | { 283 | _character.Wisdom = (int)e.NewValue; 284 | _changeOccured = true; 285 | } 286 | 287 | private void CharismaSavingThrow_OnProficiencyChangedEvent(object sender, ProficiencyChangedEventArgs e) 288 | { 289 | _character.CharismaSavingThrow = (int)e.NewValue; 290 | _changeOccured = true; 291 | } 292 | 293 | private void AcrobaticsSkill_OnProficiencyChangedEvent(object sender, ProficiencyChangedEventArgs e) 294 | { 295 | _character.Acrobatics = (int)e.NewValue; 296 | _changeOccured = true; 297 | } 298 | 299 | private void AnimalHandlingSkill_OnProficiencyChangedEvent(object sender, ProficiencyChangedEventArgs e) 300 | { 301 | _character.AnimalHandling = (int)e.NewValue; 302 | _changeOccured = true; 303 | } 304 | 305 | private void ArcanaSkill_OnProficiencyChangedEvent(object sender, ProficiencyChangedEventArgs e) 306 | { 307 | _character.Arcana = (int)e.NewValue; 308 | _changeOccured = true; 309 | } 310 | 311 | private void AthleticsSkill_OnProficiencyChangedEvent(object sender, ProficiencyChangedEventArgs e) 312 | { 313 | _character.Athletics = (int)e.NewValue; 314 | _changeOccured = true; 315 | } 316 | 317 | private void DeceptionSkill_OnProficiencyChangedEvent(object sender, ProficiencyChangedEventArgs e) 318 | { 319 | _character.Deception = (int)e.NewValue; 320 | _changeOccured = true; 321 | } 322 | 323 | private void HistorySkill_OnProficiencyChangedEvent(object sender, ProficiencyChangedEventArgs e) 324 | { 325 | _character.History = (int)e.NewValue; 326 | _changeOccured = true; 327 | } 328 | 329 | private void InsightSkill_OnProficiencyChangedEvent(object sender, ProficiencyChangedEventArgs e) 330 | { 331 | _character.Insight = (int)e.NewValue; 332 | _changeOccured = true; 333 | } 334 | 335 | private void IntimidationSkill_OnProficiencyChangedEvent(object sender, ProficiencyChangedEventArgs e) 336 | { 337 | _character.Intimidation = (int)e.NewValue; 338 | _changeOccured = true; 339 | } 340 | 341 | private void InvestigationSkill_OnProficiencyChangedEvent(object sender, ProficiencyChangedEventArgs e) 342 | { 343 | _character.Investigation = (int)e.NewValue; 344 | _changeOccured = true; 345 | } 346 | 347 | private void MedicineSkill_OnProficiencyChangedEvent(object sender, ProficiencyChangedEventArgs e) 348 | { 349 | _character.Medicine = (int)e.NewValue; 350 | _changeOccured = true; 351 | } 352 | 353 | private void NatureSkill_OnProficiencyChangedEvent(object sender, ProficiencyChangedEventArgs e) 354 | { 355 | _character.Nature = (int)e.NewValue; 356 | _changeOccured = true; 357 | } 358 | 359 | private void PerceptionSkill_OnProficiencyChangedEvent(object sender, ProficiencyChangedEventArgs e) 360 | { 361 | _character.Perception = (int)e.NewValue; 362 | _changeOccured = true; 363 | } 364 | 365 | private void PerformanceSkill_OnProficiencyChangedEvent(object sender, ProficiencyChangedEventArgs e) 366 | { 367 | _character.Performance = (int)e.NewValue; 368 | _changeOccured = true; 369 | } 370 | 371 | private void PersuasionSkill_OnProficiencyChangedEvent(object sender, ProficiencyChangedEventArgs e) 372 | { 373 | _character.Persuasion = (int)e.NewValue; 374 | _changeOccured = true; 375 | } 376 | 377 | private void ReligionSkill_OnProficiencyChangedEvent(object sender, ProficiencyChangedEventArgs e) 378 | { 379 | _character.Religion = (int)e.NewValue; 380 | _changeOccured = true; 381 | } 382 | 383 | private void SleightOfHandSkill_OnProficiencyChangedEvent(object sender, ProficiencyChangedEventArgs e) 384 | { 385 | _character.SleightOfHand = (int)e.NewValue; 386 | _changeOccured = true; 387 | } 388 | 389 | private void StealthSkill_OnProficiencyChangedEvent(object sender, ProficiencyChangedEventArgs e) 390 | { 391 | _character.Stealth = (int)e.NewValue; 392 | _changeOccured = true; 393 | } 394 | 395 | private void SurvivalSkill_OnProficiencyChangedEvent(object sender, ProficiencyChangedEventArgs e) 396 | { 397 | _character.Survival = (int)e.NewValue; 398 | _changeOccured = true; 399 | } 400 | 401 | 402 | private void LevelAddButton_Click(object sender, RoutedEventArgs e) 403 | { 404 | var cl = (CharacterClass)NewLevelCombobox.SelectedItem; 405 | var lv = NewLevelNumeric.Value; 406 | var level = new Level(cl, lv); 407 | 408 | int i = _character.Levels.FindIndex(ch => ch.Class == cl); 409 | if (i != -1) 410 | _character.Levels.RemoveAt(i); 411 | _character.Levels.Add(level); 412 | LevelsListBox.ItemsSource = null; 413 | LevelsListBox.Items.Clear(); 414 | LevelsListBox.ItemsSource = _character.Levels; 415 | _changeOccured = true; 416 | } 417 | 418 | private void LevelRemoveButton_Click(object sender, RoutedEventArgs e) 419 | { 420 | if (LevelsListBox.SelectedIndex != -1) 421 | { 422 | var l = (Level)LevelsListBox.SelectedItem; 423 | _character.Levels.Remove(l); 424 | LevelsListBox.ItemsSource = null; 425 | LevelsListBox.Items.Clear(); 426 | LevelsListBox.ItemsSource = _character.Levels; 427 | _changeOccured = true; 428 | } 429 | } 430 | 431 | private void LevelUpButton_Click(object sender, RoutedEventArgs e) 432 | { 433 | if (LevelsListBox.SelectedIndex != -1) 434 | { 435 | var l = (Level)LevelsListBox.SelectedItem; 436 | _character.Levels.Remove(l); 437 | l.LevelValue = l.LevelValue + 1; 438 | _character.Levels.Add(l); 439 | LevelsListBox.ItemsSource = null; 440 | LevelsListBox.Items.Clear(); 441 | LevelsListBox.ItemsSource = _character.Levels; 442 | _changeOccured = true; 443 | } 444 | } 445 | 446 | private void PersonalityTextBox_TextChanged(object sender, TextChangedEventArgs e) 447 | { 448 | _character.PersonalityTraits = PersonalityTextBox.Text; 449 | _changeOccured = true; 450 | } 451 | 452 | private void IdealsTextBox_TextChanged(object sender, TextChangedEventArgs e) 453 | { 454 | _character.Ideals = IdealsTextBox.Text; 455 | _changeOccured = true; 456 | } 457 | 458 | private void BondsTextBox_TextChanged(object sender, TextChangedEventArgs e) 459 | { 460 | _character.Bonds = BondsTextBox.Text; 461 | _changeOccured = true; 462 | } 463 | 464 | private void FlawsTextBox_TextChanged(object sender, TextChangedEventArgs e) 465 | { 466 | _character.Flaws = FlawsTextBox.Text; 467 | _changeOccured = true; 468 | } 469 | 470 | private void Window_SizeChanged(object sender, SizeChangedEventArgs e) 471 | { 472 | 473 | 474 | } 475 | 476 | private void AddFeatureButton_Click(object sender, RoutedEventArgs e) 477 | { 478 | _character.Features.Remove(NewFeatureTextBox.Text); 479 | _character.Features.Add(NewFeatureTextBox.Text); 480 | NewFeatureTextBox.Text = String.Empty; 481 | FeaturesListBox.ItemsSource = null; 482 | FeaturesListBox.Items.Clear(); 483 | FeaturesListBox.ItemsSource = _character.Features; 484 | CheckForJackOfAllTrades(); 485 | _changeOccured = true; 486 | 487 | } 488 | 489 | private void CheckForJackOfAllTrades() 490 | { 491 | var i = _character.Features.FindIndex(f => f.ToLower() == "jackofalltrades" || f.ToLower() == "jack of all trades"); 492 | if (i != -1) 493 | JackOfAllTradesCheckBox.IsChecked = true; 494 | else JackOfAllTradesCheckBox.IsChecked = false; 495 | } 496 | 497 | private void RemoveFeaturebutton_Click(object sender, RoutedEventArgs e) 498 | { 499 | if (FeaturesListBox.SelectedIndex != -1) 500 | { 501 | _character.Features.Remove((string)FeaturesListBox.SelectedItem); 502 | FeaturesListBox.ItemsSource = null; 503 | FeaturesListBox.Items.Clear(); 504 | FeaturesListBox.ItemsSource = _character.Features; 505 | CheckForJackOfAllTrades(); 506 | _changeOccured = true; 507 | } 508 | } 509 | 510 | private void BackgroundTextBox_TextChanged(object sender, TextChangedEventArgs e) 511 | { 512 | _character.Background = BackgroundTextBox.Text; 513 | } 514 | } 515 | } -------------------------------------------------------------------------------- /DungeonManagerWpf/CharacterWindow.xaml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 10 | 11 | 12 | 13 | 14 | 16 | 17 | 18 | 19 | 20 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 34 | 35 | 113 | 114 | 115 | 195 | 196 |