├── .gitattributes ├── .gitignore ├── Pseudo Codes For Logic ├── Player Move Function.txt ├── Use A Potion Function.txt ├── Use A Weapon Function.txt └── Vendors Planning.txt ├── README.md ├── Releases └── v1.0.zip └── SuperAdventure ├── Engine ├── Engine.csproj ├── HealingPotion.cs ├── InventoryItem.cs ├── Item.cs ├── LivingCreature.cs ├── Location.cs ├── LootItem.cs ├── MessageEventArgs.cs ├── Monster.cs ├── Player.cs ├── PlayerQuest.cs ├── Properties │ └── AssemblyInfo.cs ├── Quest.cs ├── QuestCompletionItem.cs ├── RandomNumberGenerator.cs ├── Vendor.cs ├── Weapon.cs └── World.cs ├── SuperAdventure.sln └── SuperAdventure ├── App.config ├── Program.cs ├── Properties ├── AssemblyInfo.cs ├── Resources.Designer.cs ├── Resources.resx ├── Settings.Designer.cs └── Settings.settings ├── SuperAdventure.Designer.cs ├── SuperAdventure.cs ├── SuperAdventure.csproj ├── SuperAdventure.resx ├── TradingScreen.Designer.cs ├── TradingScreen.cs └── TradingScreen.resx /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | x64/ 17 | x86/ 18 | build/ 19 | bld/ 20 | [Bb]in/ 21 | [Oo]bj/ 22 | 23 | # Visual Studio 2015 cache/options directory 24 | .vs/ 25 | 26 | # MSTest test Results 27 | [Tt]est[Rr]esult*/ 28 | [Bb]uild[Ll]og.* 29 | 30 | # NUNIT 31 | *.VisualState.xml 32 | TestResult.xml 33 | 34 | # Build Results of an ATL Project 35 | [Dd]ebugPS/ 36 | [Rr]eleasePS/ 37 | dlldata.c 38 | 39 | # DNX 40 | project.lock.json 41 | artifacts/ 42 | 43 | *_i.c 44 | *_p.c 45 | *_i.h 46 | *.ilk 47 | *.meta 48 | *.obj 49 | *.pch 50 | *.pdb 51 | *.pgc 52 | *.pgd 53 | *.rsp 54 | *.sbr 55 | *.tlb 56 | *.tli 57 | *.tlh 58 | *.tmp 59 | *.tmp_proj 60 | *.log 61 | *.vspscc 62 | *.vssscc 63 | .builds 64 | *.pidb 65 | *.svclog 66 | *.scc 67 | 68 | # Chutzpah Test files 69 | _Chutzpah* 70 | 71 | # Visual C++ cache files 72 | ipch/ 73 | *.aps 74 | *.ncb 75 | *.opensdf 76 | *.sdf 77 | *.cachefile 78 | 79 | # Visual Studio profiler 80 | *.psess 81 | *.vsp 82 | *.vspx 83 | 84 | # TFS 2012 Local Workspace 85 | $tf/ 86 | 87 | # Guidance Automation Toolkit 88 | *.gpState 89 | 90 | # ReSharper is a .NET coding add-in 91 | _ReSharper*/ 92 | *.[Rr]e[Ss]harper 93 | *.DotSettings.user 94 | 95 | # JustCode is a .NET coding add-in 96 | .JustCode 97 | 98 | # TeamCity is a build add-in 99 | _TeamCity* 100 | 101 | # DotCover is a Code Coverage Tool 102 | *.dotCover 103 | 104 | # NCrunch 105 | _NCrunch_* 106 | .*crunch*.local.xml 107 | 108 | # MightyMoose 109 | *.mm.* 110 | AutoTest.Net/ 111 | 112 | # Web workbench (sass) 113 | .sass-cache/ 114 | 115 | # Installshield output folder 116 | [Ee]xpress/ 117 | 118 | # DocProject is a documentation generator add-in 119 | DocProject/buildhelp/ 120 | DocProject/Help/*.HxT 121 | DocProject/Help/*.HxC 122 | DocProject/Help/*.hhc 123 | DocProject/Help/*.hhk 124 | DocProject/Help/*.hhp 125 | DocProject/Help/Html2 126 | DocProject/Help/html 127 | 128 | # Click-Once directory 129 | publish/ 130 | 131 | # Publish Web Output 132 | *.[Pp]ublish.xml 133 | *.azurePubxml 134 | ## TODO: Comment the next line if you want to checkin your 135 | ## web deploy settings but do note that will include unencrypted 136 | ## passwords 137 | #*.pubxml 138 | 139 | *.publishproj 140 | 141 | # NuGet Packages 142 | *.nupkg 143 | # The packages folder can be ignored because of Package Restore 144 | **/packages/* 145 | # except build/, which is used as an MSBuild target. 146 | !**/packages/build/ 147 | # Uncomment if necessary however generally it will be regenerated when needed 148 | #!**/packages/repositories.config 149 | 150 | # Windows Azure Build Output 151 | csx/ 152 | *.build.csdef 153 | 154 | # Windows Store app package directory 155 | AppPackages/ 156 | 157 | # Visual Studio cache files 158 | # files ending in .cache can be ignored 159 | *.[Cc]ache 160 | # but keep track of directories ending in .cache 161 | !*.[Cc]ache/ 162 | 163 | # Others 164 | ClientBin/ 165 | [Ss]tyle[Cc]op.* 166 | ~$* 167 | *~ 168 | *.dbmdl 169 | *.dbproj.schemaview 170 | *.pfx 171 | *.publishsettings 172 | node_modules/ 173 | orleans.codegen.cs 174 | 175 | # RIA/Silverlight projects 176 | Generated_Code/ 177 | 178 | # Backup & report files from converting an old project file 179 | # to a newer Visual Studio version. Backup files are not needed, 180 | # because we have git ;-) 181 | _UpgradeReport_Files/ 182 | Backup*/ 183 | UpgradeLog*.XML 184 | UpgradeLog*.htm 185 | 186 | # SQL Server files 187 | *.mdf 188 | *.ldf 189 | 190 | # Business Intelligence projects 191 | *.rdl.data 192 | *.bim.layout 193 | *.bim_*.settings 194 | 195 | # Microsoft Fakes 196 | FakesAssemblies/ 197 | 198 | # Node.js Tools for Visual Studio 199 | .ntvs_analysis.dat 200 | 201 | # Visual Studio 6 build log 202 | *.plg 203 | 204 | # Visual Studio 6 workspace options file 205 | *.opt 206 | 207 | # LightSwitch generated files 208 | GeneratedArtifacts/ 209 | _Pvt_Extensions/ 210 | ModelManifest.xml 211 | -------------------------------------------------------------------------------- /Pseudo Codes For Logic/Player Move Function.txt: -------------------------------------------------------------------------------- 1 | Here is an outline of the logic for a player move function as pseudo-code. 2 | 3 | 1 If the location has an item required to enter it 4 | 2 If the player does not have the item 5 | 3 Display message 6 | 3 Don't let the player move here (stop processing the move) 7 | 1 Update the player's current location 8 | 2 Display location name and description 9 | 2 Show/hide the available movement buttons 10 | 1 Completely heal the player (we assume they rested/healed while moving) 11 | 2 Update hit points display in UI 12 | 1 Does the location have a quest? 13 | 2 If so, does the player already have the quest? 14 | 3 If so, is the quest already completed? 15 | 4 If not, does the player have the items to complete the quest? 16 | 5 If so, complete the quest 17 | 6 Display messages 18 | 6 Remove quest completion items from inventory 19 | 6 Give quest rewards 20 | 6 Mark player's quest as completed 21 | 3 If not, give the player the quest 22 | 4 Display message 23 | 4 Add quest to player quest list 24 | 1 Is there a monster at the location? 25 | 2 If so, 26 | 3 Display message 27 | 3 Spawn new monster to fight 28 | 3 Display combat comboboxes and buttons 29 | 4 Repopulate comboboxes, in case inventory changed 30 | 2 If not 31 | 3 Hide combat comboboxes and buttons 32 | 1 Refresh the player's inventory in the UI – in case it changed 33 | 1 Refresh the player's quest list in the UI – in case it changed 34 | 1 Refresh the cboWeapons ComboBox in the UI 35 | 1 Refresh the cboPotions ComboBox in the UI -------------------------------------------------------------------------------- /Pseudo Codes For Logic/Use A Potion Function.txt: -------------------------------------------------------------------------------- 1 | Use a potion function 2 | 1 Get currently selected potion from cboPotions ComboBox 3 | 1 Add healing amount to player's CurrentHitPoints 4 | 2 CurrentHitPoints cannot exceed player's MaximumHitPoints 5 | 1 Remove the potion from the player's inventory 6 | 1 Display message 7 | 1 Monster gets their turn to attack 8 | 2 Determine the amount of damage the monster does to the player 9 | 2 Display message 10 | 2 Subtract damage from player's CurrentHitPoints 11 | 3 Refresh player data in UI 12 | 2 If player is dead (zero hit points remaining) 13 | 3 Display message 14 | 3 Move player to Home location 15 | 1 Refresh player data in UI -------------------------------------------------------------------------------- /Pseudo Codes For Logic/Use A Weapon Function.txt: -------------------------------------------------------------------------------- 1 | Use a weapon function 2 | 1 Get the currently selected weapon from the cboWeapons ComboBox 3 | 1 Determine the amount of damage the player does to the monster 4 | 1 Apply the damage to the monster's CurrentHitPoints 5 | 2 Display message 6 | 1 If the monster is dead (zero hit points remaining) 7 | 2 Display a victory message 8 | 2 Give player experience points for killing the monster 9 | 3 Display message 10 | 2 Give player gold for killing the monster 11 | 3 Display message 12 | 2 Get loot items from the monster 13 | 3 Display message for each loot item 14 | 3 Add item to player's inventory 15 | 2 Refresh player data on UI 16 | 3 Gold and ExperiencePoints 17 | 3 Inventory list and ComboBoxes 18 | 2 Move player to current location 19 | 3 This will heal the player and create a new monster 20 | 1 If the monster is still alive 21 | 2 Determine the amount of damage the monster does to the player 22 | 2 Display message 23 | 2 Subtract damage from player's CurrentHitPoints 24 | 3 Refresh player data in UI 25 | 2 If player is dead (zero hit points remaining) 26 | 3 Display message 27 | 3 Move player to Home location -------------------------------------------------------------------------------- /Pseudo Codes For Logic/Vendors Planning.txt: -------------------------------------------------------------------------------- 1 | Features for adding a vendor 2 | 3 | Here are the changes we need to make: 4 | 1. Add a price to items 5 | 2. Create a new Vendor class. This class will have properties for the vendor's name and 6 | their inventory. 7 | 3. Change the Location class, to hold an (optional) Vendor at that location 8 | 4. Change the UI to let the player buy and sell items with the vendor -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### Notice 2 | Development has ended! 3 | 4 | #### OOP-Text-Based-RPG 5 | I just create this repository because I just want to make practice of my OOP (Object-Oriented-Programming) skills. With that project, I'm going to make a native super simple RPG Text Based game using C# on Windows Form Application. 6 | 7 | #### What are the classes/objects in our game? 8 | For our game, we want to do these things: 9 | 10 | - The player goes to locations. 11 | - The player may need to have certain items to enter a location. 12 | - The location might have a quest available. 13 | - To complete a quest, the player must collect certain items and turn them in. 14 | - The player can collect items by going to a location and fighting monsters there. 15 | - The player fights monsters with weapons. 16 | - The player can use a healing potion while fighting. 17 | - The player receives loot items after defeating a monster. 18 | - After turning in the quest, the player receives reward items. 19 | 20 | So, the nouns (classes/objects) in this game will be Player, Location, Item, Quest, Monster, 21 | Weapon and Healing Potion. We'll need a few others, but we can start with these. 22 | 23 | #### Version 1.0 released. 24 | 25 | #### What's next? 26 | This is a very simple RPG, and there is a lot you can do to expand it. 27 | 28 | Here are a few ideas: 29 | - Save the player's current game to disk, and re-load it later 30 | - As the player gains experience, increase their level 31 | - Increase MaximumHitPoints with each new level 32 | - Add a minimum level requirement for some items 33 | - Add a minimum level requirement for some locations 34 | - Add randomization to battles 35 | - Determine if the player hits the monster 36 | - Determine if the monster hits the player 37 | - Add player attributes (strength, dexterity, etc.) 38 | - Use attributes in battle: who attacks first, amount of damage, etc. 39 | - Add armor and jewelry 40 | - Makes it more difficult for the monster to hit the player 41 | - Has special benefits: increased chance to hit, increased damage, etc. 42 | - Add crafting skills the player can acquire 43 | - Add crafting recipes the player use 44 | - Require the appropriate skill 45 | - Requires components (inventory items) 46 | - Make some quests repeatable 47 | - Make quest chains (player must complete Quest A before they can receive Quest B) 48 | - Add magic scrolls 49 | - Add spells 50 | - Level requirements for the spells 51 | - Spells require components to cast (maybe?) 52 | - Add more potions 53 | - More powerful healing potions 54 | - Potions to improve player's to hit chances, or damage 55 | - Add poisons to use in battle 56 | - Add pets 57 | - Help the player in battle by attacking opponents 58 | - Help the player in battle by healing the player 59 | - Add stores/vendors 60 | - Player can sell useless items and buy new equipment, scrolls, potions, poisons, 61 | and crafting/spell components 62 | 63 | There are also more programming techniques you can learn to make the program a little 64 | cleaner. 65 | - LINQ, when searching lists 66 | - Events/delegates, to handle communication between the logic project and the UI 67 | project – which will let you move more logic code out of the UI project 68 | - BindingList, so you don't have to repeatedly repopulate the DataGridViews and ComboBox 69 | in the UI 70 | 71 | #### What will the game look like? 72 | ![alt tag](https://s30.postimg.org/um0v4fkn5/Game_screenshot.png) 73 | 74 | ![alt tag](https://s15.postimg.org/ggzlsk8vf/Trader.png) 75 | -------------------------------------------------------------------------------- /Releases/v1.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gkaragoz/OOP-Text-Based-RPG/d2176da939d49749800e5c3c23cba03d4abe7799/Releases/v1.0.zip -------------------------------------------------------------------------------- /SuperAdventure/Engine/Engine.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {4166EF61-D200-4A0D-9B05-AFEE45C2C8B7} 8 | Library 9 | Properties 10 | Engine 11 | Engine 12 | v4.5.2 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 69 | -------------------------------------------------------------------------------- /SuperAdventure/Engine/HealingPotion.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 Engine 8 | { 9 | public class HealingPotion : Item 10 | { 11 | public int AmountToHeal { get; set; } 12 | 13 | public HealingPotion(int id, string name, string namePlural, 14 | int amountToHeal, int price) : base(id, name, namePlural, price) 15 | { 16 | AmountToHeal = amountToHeal; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /SuperAdventure/Engine/InventoryItem.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.ComponentModel; 7 | 8 | namespace Engine 9 | { 10 | public class InventoryItem : INotifyPropertyChanged 11 | { 12 | private Item _details; 13 | private int _quantity; 14 | 15 | public int ItemID 16 | { 17 | get { return Details.ID; } 18 | } 19 | public int Price 20 | { 21 | get { return Details.Price; } 22 | } 23 | public Item Details 24 | { 25 | get { return _details; } 26 | set 27 | { 28 | _details = value; 29 | OnPropertyChanged("Details"); 30 | } 31 | } 32 | public int Quantity 33 | { 34 | get { return _quantity; } 35 | set 36 | { 37 | _quantity = value; 38 | OnPropertyChanged("Quantity"); 39 | OnPropertyChanged("Description"); 40 | } 41 | } 42 | public string Description 43 | { 44 | get 45 | { 46 | return Quantity > 1 ? Details.NamePlural : 47 | Details.Name; 48 | } 49 | } 50 | public event PropertyChangedEventHandler PropertyChanged; 51 | 52 | public InventoryItem(Item details, int quantity) 53 | { 54 | Details = details; 55 | Quantity = quantity; 56 | } 57 | 58 | protected void OnPropertyChanged(string name) 59 | { 60 | if (PropertyChanged != null) 61 | { 62 | PropertyChanged( 63 | this, new PropertyChangedEventArgs(name)); 64 | } 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /SuperAdventure/Engine/Item.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 Engine 8 | { 9 | public class Item 10 | { 11 | public int ID { get; set; } 12 | public string Name { get; set; } 13 | public string NamePlural { get; set; } 14 | public int Price { get; set; } 15 | 16 | public Item(int id, string name, string namePlural, int price) 17 | { 18 | ID = id; 19 | Name = name; 20 | NamePlural = namePlural; 21 | Price = price; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /SuperAdventure/Engine/LivingCreature.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.ComponentModel; 7 | 8 | namespace Engine 9 | { 10 | public class LivingCreature : INotifyPropertyChanged 11 | { 12 | private int _currentHitPoints; 13 | public int CurrentHitPoints 14 | { 15 | get { return _currentHitPoints; } 16 | set 17 | { 18 | _currentHitPoints = value; 19 | OnPropertyChanged("CurrentHitPoints"); 20 | } 21 | } 22 | public int MaximumHitPoints { get; set; } 23 | 24 | public event PropertyChangedEventHandler PropertyChanged; 25 | 26 | public LivingCreature(int currentHitPoints, 27 | int maximumHitPoints) 28 | { 29 | CurrentHitPoints = currentHitPoints; 30 | MaximumHitPoints = maximumHitPoints; 31 | } 32 | 33 | protected void OnPropertyChanged(string name) 34 | { 35 | if (PropertyChanged != null) 36 | { 37 | PropertyChanged(this, new PropertyChangedEventArgs(name)); 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /SuperAdventure/Engine/Location.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 Engine 8 | { 9 | public class Location 10 | { 11 | public int ID { get; set; } 12 | public string Name { get; set; } 13 | public string Description { get; set; } 14 | 15 | public Item ItemRequiredToEnter { get; set; } 16 | public Quest QuestAvailableHere { get; set; } 17 | public Monster MonsterLivingHere { get; set; } 18 | public Vendor VendorWorkingHere { get; set; } 19 | public Location LocationToNorth { get; set; } 20 | public Location LocationToEast { get; set; } 21 | public Location LocationToSouth { get; set; } 22 | public Location LocationToWest { get; set; } 23 | 24 | public Location(int id, string name, string description, 25 | Item itemRequiredToEnter = null, 26 | Quest questAvailableHere = null, 27 | Monster monsterLivingHere = null) 28 | { 29 | ID = id; 30 | Name = name; 31 | Description = description; 32 | ItemRequiredToEnter = itemRequiredToEnter; 33 | QuestAvailableHere = questAvailableHere; 34 | MonsterLivingHere = monsterLivingHere; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /SuperAdventure/Engine/LootItem.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 Engine 8 | { 9 | public class LootItem 10 | { 11 | public Item Details { get; set; } 12 | public int DropPercentage { get; set; } 13 | public bool IsDefaultItem { get; set; } 14 | 15 | public LootItem(Item details, int dropPercentage, bool isDefaultItem) 16 | { 17 | Details = details; 18 | DropPercentage = dropPercentage; 19 | IsDefaultItem = isDefaultItem; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /SuperAdventure/Engine/MessageEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Engine 4 | { 5 | public class MessageEventArgs : EventArgs 6 | { 7 | public string Message { get; private set; } 8 | public bool AddExtraNewLine { get; private set; } 9 | 10 | public MessageEventArgs(string message, bool addExtraNewLine) 11 | { 12 | Message = message; 13 | AddExtraNewLine = addExtraNewLine; 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /SuperAdventure/Engine/Monster.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 Engine 8 | { 9 | public class Monster : LivingCreature 10 | { 11 | public int ID { get; set; } 12 | public string Name { get; set; } 13 | public int MaximumDamage { get; set; } 14 | public int RewardExperiencePoints { get; set; } 15 | public int RewardGold { get; set; } 16 | public List LootTable { get; set; } 17 | 18 | public Monster(int id, string name, int maximumDamage, 19 | int rewardExperiencePoints, int rewardGold, 20 | int currentHitPoints, int maximumHitPoints) : 21 | base(currentHitPoints, maximumHitPoints) 22 | { 23 | ID = id; 24 | Name = name; 25 | MaximumDamage = maximumDamage; 26 | RewardExperiencePoints = rewardExperiencePoints; 27 | RewardGold = rewardGold; 28 | LootTable = new List(); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /SuperAdventure/Engine/Player.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using System.Xml; 8 | 9 | namespace Engine 10 | { 11 | public class Player : LivingCreature 12 | { 13 | private int _gold; 14 | private int _experiencePoints; 15 | private Location _currentLocation; 16 | private Monster _currentMonster; 17 | 18 | public event EventHandler OnMessage; 19 | 20 | public int Gold 21 | { 22 | get { return _gold; } 23 | set 24 | { 25 | _gold = value; 26 | OnPropertyChanged("Gold"); 27 | } 28 | } 29 | 30 | public int ExperiencePoints 31 | { 32 | get { return _experiencePoints; } 33 | private set 34 | { 35 | _experiencePoints = value; 36 | OnPropertyChanged("ExperiencePoints"); 37 | OnPropertyChanged("Level"); 38 | } 39 | } 40 | 41 | public int Level 42 | { 43 | get { return ((ExperiencePoints / 100) + 1); } 44 | } 45 | 46 | public Location CurrentLocation 47 | { 48 | get { return _currentLocation; } 49 | set 50 | { 51 | _currentLocation = value; 52 | OnPropertyChanged("CurrentLocation"); 53 | } 54 | } 55 | 56 | public Weapon CurrentWeapon { get; set; } 57 | 58 | public BindingList Inventory { get; set; } 59 | 60 | public List Weapons 61 | { 62 | get { return Inventory.Where(x => x.Details is Weapon).Select(x => x.Details as Weapon).ToList(); } 63 | } 64 | 65 | public List Potions 66 | { 67 | get { return Inventory.Where(x => x.Details is HealingPotion).Select(x => x.Details as HealingPotion).ToList(); } 68 | } 69 | 70 | public BindingList Quests { get; set; } 71 | 72 | private Player(int currentHitPoints, int maximumHitPoints, int gold, int experiencePoints) : base(currentHitPoints, maximumHitPoints) 73 | { 74 | Gold = gold; 75 | ExperiencePoints = experiencePoints; 76 | 77 | Inventory = new BindingList(); 78 | Quests = new BindingList(); 79 | } 80 | 81 | public static Player CreateDefaultPlayer() 82 | { 83 | Player player = new Player(10, 10, 20, 0); 84 | player.Inventory.Add(new InventoryItem(World.ItemByID(World.ITEM_ID_RUSTY_SWORD), 1)); 85 | player.CurrentLocation = World.LocationByID(World.LOCATION_ID_HOME); 86 | 87 | return player; 88 | } 89 | 90 | public void AddExperiencePoints(int experiencePointsToAdd) 91 | { 92 | ExperiencePoints += experiencePointsToAdd; 93 | MaximumHitPoints = (Level * 10); 94 | } 95 | 96 | public static Player CreatePlayerFromXmlString(string xmlPlayerData) 97 | { 98 | try 99 | { 100 | XmlDocument playerData = new XmlDocument(); 101 | 102 | playerData.LoadXml(xmlPlayerData); 103 | 104 | int currentHitPoints = Convert.ToInt32(playerData.SelectSingleNode("/Player/Stats/CurrentHitPoints").InnerText); 105 | int maximumHitPoints = Convert.ToInt32(playerData.SelectSingleNode("/Player/Stats/MaximumHitPoints").InnerText); 106 | int gold = Convert.ToInt32(playerData.SelectSingleNode("/Player/Stats/Gold").InnerText); 107 | int experiencePoints = Convert.ToInt32(playerData.SelectSingleNode("/Player/Stats/ExperiencePoints").InnerText); 108 | 109 | Player player = new Player(currentHitPoints, maximumHitPoints, gold, experiencePoints); 110 | 111 | int currentLocationID = Convert.ToInt32(playerData.SelectSingleNode("/Player/Stats/CurrentLocation").InnerText); 112 | player.CurrentLocation = World.LocationByID(currentLocationID); 113 | 114 | if (playerData.SelectSingleNode("/Player/Stats/CurrentWeapon") != null) 115 | { 116 | int currentWeaponID = Convert.ToInt32(playerData.SelectSingleNode("/Player/Stats/CurrentWeapon").InnerText); 117 | player.CurrentWeapon = (Weapon)World.ItemByID(currentWeaponID); 118 | } 119 | 120 | foreach (XmlNode node in playerData.SelectNodes("/Player/InventoryItems/InventoryItem")) 121 | { 122 | int id = Convert.ToInt32(node.Attributes["ID"].Value); 123 | int quantity = Convert.ToInt32(node.Attributes["Quantity"].Value); 124 | 125 | for (int i = 0; i < quantity; i++) 126 | { 127 | player.AddItemToInventory(World.ItemByID(id)); 128 | } 129 | } 130 | 131 | foreach (XmlNode node in playerData.SelectNodes("/Player/PlayerQuests/PlayerQuest")) 132 | { 133 | int id = Convert.ToInt32(node.Attributes["ID"].Value); 134 | bool isCompleted = Convert.ToBoolean(node.Attributes["IsCompleted"].Value); 135 | 136 | PlayerQuest playerQuest = new PlayerQuest(World.QuestByID(id)); 137 | playerQuest.IsCompleted = isCompleted; 138 | 139 | player.Quests.Add(playerQuest); 140 | } 141 | 142 | return player; 143 | } 144 | catch 145 | { 146 | // If there was an error with the XML data, return a default player object 147 | return Player.CreateDefaultPlayer(); 148 | } 149 | } 150 | 151 | public bool HasRequiredItemToEnterThisLocation(Location location) 152 | { 153 | if (location.ItemRequiredToEnter == null) 154 | { 155 | // There is no required item for this location, so return "true" 156 | return true; 157 | } 158 | 159 | // See if the player has the required item in their inventory 160 | return Inventory.Any(ii => ii.Details.ID == location.ItemRequiredToEnter.ID); 161 | } 162 | 163 | public bool HasThisQuest(Quest quest) 164 | { 165 | return Quests.Any(pq => pq.Details.ID == quest.ID); 166 | } 167 | 168 | public bool CompletedThisQuest(Quest quest) 169 | { 170 | foreach (PlayerQuest playerQuest in Quests) 171 | { 172 | if (playerQuest.Details.ID == quest.ID) 173 | { 174 | return playerQuest.IsCompleted; 175 | } 176 | } 177 | 178 | return false; 179 | } 180 | 181 | public bool HasAllQuestCompletionItems(Quest quest) 182 | { 183 | // See if the player has all the items needed to complete the quest here 184 | foreach (QuestCompletionItem qci in quest.QuestCompletionItems) 185 | { 186 | // Check each item in the player's inventory, to see if they have it, and enough of it 187 | if (!Inventory.Any(ii => ii.Details.ID == qci.Details.ID && ii.Quantity >= qci.Quantity)) 188 | { 189 | return false; 190 | } 191 | } 192 | 193 | // If we got here, then the player must have all the required items, and enough of them, to complete the quest. 194 | return true; 195 | } 196 | 197 | public void RemoveQuestCompletionItems(Quest quest) 198 | { 199 | foreach (QuestCompletionItem qci in quest.QuestCompletionItems) 200 | { 201 | // Subtract the quantity from the player's inventory that was needed to complete the quest 202 | InventoryItem item = Inventory.SingleOrDefault(ii => ii.Details.ID == qci.Details.ID); 203 | 204 | if (item != null) 205 | { 206 | RemoveItemFromInventory(item.Details, qci.Quantity); 207 | } 208 | } 209 | } 210 | 211 | public void AddItemToInventory(Item itemToAdd, int quantity = 1) 212 | { 213 | InventoryItem item = Inventory.SingleOrDefault(ii => ii.Details.ID == itemToAdd.ID); 214 | 215 | if (item == null) 216 | { 217 | // They didn't have the item, so add it to their inventory 218 | Inventory.Add(new InventoryItem(itemToAdd, quantity)); 219 | } 220 | else 221 | { 222 | // They have the item in their inventory, so increase the quantity 223 | item.Quantity += quantity; 224 | } 225 | 226 | RaiseInventoryChangedEvent(itemToAdd); 227 | } 228 | 229 | public void RemoveItemFromInventory(Item itemToRemove, int quantity = 1) 230 | { 231 | InventoryItem item = Inventory.SingleOrDefault(ii => ii.Details.ID == itemToRemove.ID); 232 | 233 | if (item == null) 234 | { 235 | // The item is not in the player's inventory, so ignore it. 236 | // We might want to raise an error for this situation 237 | } 238 | else 239 | { 240 | // They have the item in their inventory, so decrease the quantity 241 | item.Quantity -= quantity; 242 | 243 | // Don't allow negative quantities. 244 | // We might want to raise an error for this situation 245 | if (item.Quantity < 0) 246 | { 247 | item.Quantity = 0; 248 | } 249 | 250 | // If the quantity is zero, remove the item from the list 251 | if (item.Quantity == 0) 252 | { 253 | Inventory.Remove(item); 254 | } 255 | 256 | // Notify the UI that the inventory has changed 257 | RaiseInventoryChangedEvent(itemToRemove); 258 | } 259 | } 260 | 261 | private void RaiseInventoryChangedEvent(Item item) 262 | { 263 | if (item is Weapon) 264 | { 265 | OnPropertyChanged("Weapons"); 266 | } 267 | 268 | if (item is HealingPotion) 269 | { 270 | OnPropertyChanged("Potions"); 271 | } 272 | } 273 | 274 | public void MarkQuestCompleted(Quest quest) 275 | { 276 | // Find the quest in the player's quest list 277 | PlayerQuest playerQuest = Quests.SingleOrDefault(pq => pq.Details.ID == quest.ID); 278 | 279 | if (playerQuest != null) 280 | { 281 | playerQuest.IsCompleted = true; 282 | } 283 | } 284 | 285 | private void RaiseMessage(string message, bool addExtraNewLine = false) 286 | { 287 | if (OnMessage != null) 288 | { 289 | OnMessage(this, new MessageEventArgs(message, addExtraNewLine)); 290 | } 291 | } 292 | 293 | public void MoveTo(Location newLocation) 294 | { 295 | //Does the location have any required items 296 | if (!HasRequiredItemToEnterThisLocation(newLocation)) 297 | { 298 | RaiseMessage("You must have a " + newLocation.ItemRequiredToEnter.Name + " to enter this location."); 299 | return; 300 | } 301 | 302 | // Update the player's current location 303 | CurrentLocation = newLocation; 304 | 305 | // Completely heal the player 306 | CurrentHitPoints = MaximumHitPoints; 307 | 308 | // Does the location have a quest? 309 | if (newLocation.QuestAvailableHere != null) 310 | { 311 | // See if the player already has the quest, and if they've completed it 312 | bool playerAlreadyHasQuest = HasThisQuest(newLocation.QuestAvailableHere); 313 | bool playerAlreadyCompletedQuest = CompletedThisQuest(newLocation.QuestAvailableHere); 314 | 315 | // See if the player already has the quest 316 | if (playerAlreadyHasQuest) 317 | { 318 | // If the player has not completed the quest yet 319 | if (!playerAlreadyCompletedQuest) 320 | { 321 | // See if the player has all the items needed to complete the quest 322 | bool playerHasAllItemsToCompleteQuest = HasAllQuestCompletionItems(newLocation.QuestAvailableHere); 323 | 324 | // The player has all items required to complete the quest 325 | if (playerHasAllItemsToCompleteQuest) 326 | { 327 | // Display message 328 | RaiseMessage(""); 329 | RaiseMessage("You complete the '" + newLocation.QuestAvailableHere.Name + "' quest."); 330 | 331 | // Remove quest items from inventory 332 | RemoveQuestCompletionItems(newLocation.QuestAvailableHere); 333 | 334 | // Give quest rewards 335 | RaiseMessage("You receive: "); 336 | RaiseMessage(newLocation.QuestAvailableHere.RewardExperiencePoints + " experience points"); 337 | RaiseMessage(newLocation.QuestAvailableHere.RewardGold + " gold"); 338 | RaiseMessage(newLocation.QuestAvailableHere.RewardItem.Name, true); 339 | 340 | AddExperiencePoints(newLocation.QuestAvailableHere.RewardExperiencePoints); 341 | Gold += newLocation.QuestAvailableHere.RewardGold; 342 | 343 | // Add the reward item to the player's inventory 344 | AddItemToInventory(newLocation.QuestAvailableHere.RewardItem); 345 | 346 | // Mark the quest as completed 347 | MarkQuestCompleted(newLocation.QuestAvailableHere); 348 | } 349 | } 350 | } 351 | else 352 | { 353 | // The player does not already have the quest 354 | 355 | // Display the messages 356 | RaiseMessage("You receive the " + newLocation.QuestAvailableHere.Name + " quest."); 357 | RaiseMessage(newLocation.QuestAvailableHere.Description); 358 | RaiseMessage("To complete it, return with:"); 359 | foreach (QuestCompletionItem qci in newLocation.QuestAvailableHere.QuestCompletionItems) 360 | { 361 | if (qci.Quantity == 1) 362 | { 363 | RaiseMessage(qci.Quantity + " " + qci.Details.Name); 364 | } 365 | else 366 | { 367 | RaiseMessage(qci.Quantity + " " + qci.Details.NamePlural); 368 | } 369 | } 370 | RaiseMessage(""); 371 | 372 | // Add the quest to the player's quest list 373 | Quests.Add(new PlayerQuest(newLocation.QuestAvailableHere)); 374 | } 375 | } 376 | 377 | // Does the location have a monster? 378 | if (newLocation.MonsterLivingHere != null) 379 | { 380 | RaiseMessage("You see a " + newLocation.MonsterLivingHere.Name); 381 | 382 | // Make a new monster, using the values from the standard monster in the World.Monster list 383 | Monster standardMonster = World.MonsterByID(newLocation.MonsterLivingHere.ID); 384 | 385 | _currentMonster = new Monster(standardMonster.ID, standardMonster.Name, standardMonster.MaximumDamage, 386 | standardMonster.RewardExperiencePoints, standardMonster.RewardGold, standardMonster.CurrentHitPoints, standardMonster.MaximumHitPoints); 387 | 388 | foreach (LootItem lootItem in standardMonster.LootTable) 389 | { 390 | _currentMonster.LootTable.Add(lootItem); 391 | } 392 | } 393 | else 394 | { 395 | _currentMonster = null; 396 | } 397 | } 398 | 399 | public void UseWeapon(Weapon weapon) 400 | { 401 | // Determine the amount of damage to do to the monster 402 | int damageToMonster = RandomNumberGenerator.NumberBetween(weapon.MinimumDamage, weapon.MaximumDamage); 403 | 404 | // Apply the damage to the monster's CurrentHitPoints 405 | _currentMonster.CurrentHitPoints -= damageToMonster; 406 | 407 | // Display message 408 | RaiseMessage("You hit the " + _currentMonster.Name + " for " + damageToMonster + " points."); 409 | 410 | // Check if the monster is dead 411 | if (_currentMonster.CurrentHitPoints <= 0) 412 | { 413 | // Monster is dead 414 | RaiseMessage(""); 415 | RaiseMessage("You defeated the " + _currentMonster.Name); 416 | 417 | // Give player experience points for killing the monster 418 | AddExperiencePoints(_currentMonster.RewardExperiencePoints); 419 | RaiseMessage("You receive " + _currentMonster.RewardExperiencePoints + " experience points"); 420 | 421 | // Give player gold for killing the monster 422 | Gold += _currentMonster.RewardGold; 423 | RaiseMessage("You receive " + _currentMonster.RewardGold + " gold"); 424 | 425 | // Get random loot items from the monster 426 | List lootedItems = new List(); 427 | 428 | // Add items to the lootedItems list, comparing a random number to the drop percentage 429 | foreach (LootItem lootItem in _currentMonster.LootTable) 430 | { 431 | if (RandomNumberGenerator.NumberBetween(1, 100) <= lootItem.DropPercentage) 432 | { 433 | lootedItems.Add(new InventoryItem(lootItem.Details, 1)); 434 | } 435 | } 436 | 437 | // If no items were randomly selected, then add the default loot item(s). 438 | if (lootedItems.Count == 0) 439 | { 440 | foreach (LootItem lootItem in _currentMonster.LootTable) 441 | { 442 | if (lootItem.IsDefaultItem) 443 | { 444 | lootedItems.Add(new InventoryItem(lootItem.Details, 1)); 445 | } 446 | } 447 | } 448 | 449 | // Add the looted items to the player's inventory 450 | foreach (InventoryItem inventoryItem in lootedItems) 451 | { 452 | AddItemToInventory(inventoryItem.Details); 453 | 454 | if (inventoryItem.Quantity == 1) 455 | { 456 | RaiseMessage("You loot " + inventoryItem.Quantity + " " + inventoryItem.Details.Name); 457 | } 458 | else 459 | { 460 | RaiseMessage("You loot " + inventoryItem.Quantity + " " + inventoryItem.Details.NamePlural); 461 | } 462 | } 463 | 464 | // Add a blank line to the messages box, just for appearance. 465 | RaiseMessage(""); 466 | 467 | // Move player to current location (to heal player and create a new monster to fight) 468 | MoveTo(CurrentLocation); 469 | } 470 | else 471 | { 472 | // Monster is still alive 473 | 474 | // Determine the amount of damage the monster does to the player 475 | int damageToPlayer = RandomNumberGenerator.NumberBetween(0, _currentMonster.MaximumDamage); 476 | 477 | // Display message 478 | RaiseMessage("The " + _currentMonster.Name + " did " + damageToPlayer + " points of damage."); 479 | 480 | // Subtract damage from player 481 | CurrentHitPoints -= damageToPlayer; 482 | 483 | if (CurrentHitPoints <= 0) 484 | { 485 | // Display message 486 | RaiseMessage("The " + _currentMonster.Name + " killed you."); 487 | 488 | // Move player to "Home" 489 | MoveHome(); 490 | } 491 | } 492 | } 493 | 494 | public void UsePotion(HealingPotion potion) 495 | { 496 | // Add healing amount to the player's current hit points 497 | CurrentHitPoints = (CurrentHitPoints + potion.AmountToHeal); 498 | 499 | // CurrentHitPoints cannot exceed player's MaximumHitPoints 500 | if (CurrentHitPoints > MaximumHitPoints) 501 | { 502 | CurrentHitPoints = MaximumHitPoints; 503 | } 504 | 505 | // Remove the potion from the player's inventory 506 | RemoveItemFromInventory(potion, 1); 507 | 508 | // Display message 509 | RaiseMessage("You drink a " + potion.Name); 510 | 511 | // Monster gets their turn to attack 512 | 513 | // Determine the amount of damage the monster does to the player 514 | int damageToPlayer = RandomNumberGenerator.NumberBetween(0, _currentMonster.MaximumDamage); 515 | 516 | // Display message 517 | RaiseMessage("The " + _currentMonster.Name + " did " + damageToPlayer + " points of damage."); 518 | 519 | // Subtract damage from player 520 | CurrentHitPoints -= damageToPlayer; 521 | 522 | if (CurrentHitPoints <= 0) 523 | { 524 | // Display message 525 | RaiseMessage("The " + _currentMonster.Name + " killed you."); 526 | 527 | // Move player to "Home" 528 | MoveHome(); 529 | } 530 | } 531 | 532 | private void MoveHome() 533 | { 534 | MoveTo(World.LocationByID(World.LOCATION_ID_HOME)); 535 | } 536 | 537 | public void MoveNorth() 538 | { 539 | if (CurrentLocation.LocationToNorth != null) 540 | { 541 | MoveTo(CurrentLocation.LocationToNorth); 542 | } 543 | } 544 | 545 | public void MoveEast() 546 | { 547 | if (CurrentLocation.LocationToEast != null) 548 | { 549 | MoveTo(CurrentLocation.LocationToEast); 550 | } 551 | } 552 | 553 | public void MoveSouth() 554 | { 555 | if (CurrentLocation.LocationToSouth != null) 556 | { 557 | MoveTo(CurrentLocation.LocationToSouth); 558 | } 559 | } 560 | 561 | public void MoveWest() 562 | { 563 | if (CurrentLocation.LocationToWest != null) 564 | { 565 | MoveTo(CurrentLocation.LocationToWest); 566 | } 567 | } 568 | 569 | public string ToXmlString() 570 | { 571 | XmlDocument playerData = new XmlDocument(); 572 | 573 | // Create the top-level XML node 574 | XmlNode player = playerData.CreateElement("Player"); 575 | playerData.AppendChild(player); 576 | 577 | // Create the "Stats" child node to hold the other player statistics nodes 578 | XmlNode stats = playerData.CreateElement("Stats"); 579 | player.AppendChild(stats); 580 | 581 | // Create the child nodes for the "Stats" node 582 | XmlNode currentHitPoints = playerData.CreateElement("CurrentHitPoints"); 583 | currentHitPoints.AppendChild(playerData.CreateTextNode(this.CurrentHitPoints.ToString())); 584 | stats.AppendChild(currentHitPoints); 585 | 586 | XmlNode maximumHitPoints = playerData.CreateElement("MaximumHitPoints"); 587 | maximumHitPoints.AppendChild(playerData.CreateTextNode(this.MaximumHitPoints.ToString())); 588 | stats.AppendChild(maximumHitPoints); 589 | 590 | XmlNode gold = playerData.CreateElement("Gold"); 591 | gold.AppendChild(playerData.CreateTextNode(this.Gold.ToString())); 592 | stats.AppendChild(gold); 593 | 594 | XmlNode experiencePoints = playerData.CreateElement("ExperiencePoints"); 595 | experiencePoints.AppendChild(playerData.CreateTextNode(this.ExperiencePoints.ToString())); 596 | stats.AppendChild(experiencePoints); 597 | 598 | XmlNode currentLocation = playerData.CreateElement("CurrentLocation"); 599 | currentLocation.AppendChild(playerData.CreateTextNode(this.CurrentLocation.ID.ToString())); 600 | stats.AppendChild(currentLocation); 601 | 602 | if (CurrentWeapon != null) 603 | { 604 | XmlNode currentWeapon = playerData.CreateElement("CurrentWeapon"); 605 | currentWeapon.AppendChild(playerData.CreateTextNode(this.CurrentWeapon.ID.ToString())); 606 | stats.AppendChild(currentWeapon); 607 | } 608 | 609 | // Create the "InventoryItems" child node to hold each InventoryItem node 610 | XmlNode inventoryItems = playerData.CreateElement("InventoryItems"); 611 | player.AppendChild(inventoryItems); 612 | 613 | // Create an "InventoryItem" node for each item in the player's inventory 614 | foreach (InventoryItem item in this.Inventory) 615 | { 616 | XmlNode inventoryItem = playerData.CreateElement("InventoryItem"); 617 | 618 | XmlAttribute idAttribute = playerData.CreateAttribute("ID"); 619 | idAttribute.Value = item.Details.ID.ToString(); 620 | inventoryItem.Attributes.Append(idAttribute); 621 | 622 | XmlAttribute quantityAttribute = playerData.CreateAttribute("Quantity"); 623 | quantityAttribute.Value = item.Quantity.ToString(); 624 | inventoryItem.Attributes.Append(quantityAttribute); 625 | 626 | inventoryItems.AppendChild(inventoryItem); 627 | } 628 | 629 | // Create the "PlayerQuests" child node to hold each PlayerQuest node 630 | XmlNode playerQuests = playerData.CreateElement("PlayerQuests"); 631 | player.AppendChild(playerQuests); 632 | 633 | // Create a "PlayerQuest" node for each quest the player has acquired 634 | foreach (PlayerQuest quest in this.Quests) 635 | { 636 | XmlNode playerQuest = playerData.CreateElement("PlayerQuest"); 637 | 638 | XmlAttribute idAttribute = playerData.CreateAttribute("ID"); 639 | idAttribute.Value = quest.Details.ID.ToString(); 640 | playerQuest.Attributes.Append(idAttribute); 641 | 642 | XmlAttribute isCompletedAttribute = playerData.CreateAttribute("IsCompleted"); 643 | isCompletedAttribute.Value = quest.IsCompleted.ToString(); 644 | playerQuest.Attributes.Append(isCompletedAttribute); 645 | 646 | playerQuests.AppendChild(playerQuest); 647 | } 648 | 649 | return playerData.InnerXml; // The XML document, as a string, so we can save the data to disk 650 | } 651 | } 652 | } -------------------------------------------------------------------------------- /SuperAdventure/Engine/PlayerQuest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Engine 9 | { 10 | public class PlayerQuest : INotifyPropertyChanged 11 | { 12 | private Quest _details; 13 | private bool _isCompleted; 14 | 15 | public Quest Details 16 | { 17 | get { return _details; } 18 | set 19 | { 20 | _details = value; 21 | OnPropertyChanged("Details"); 22 | } 23 | } 24 | 25 | public bool IsCompleted 26 | { 27 | get { return _isCompleted; } 28 | set 29 | { 30 | _isCompleted = value; 31 | OnPropertyChanged("IsCompleted"); 32 | OnPropertyChanged("Name"); 33 | } 34 | } 35 | 36 | public string Name 37 | { 38 | get { return Details.Name; } 39 | } 40 | 41 | public PlayerQuest(Quest details) 42 | { 43 | Details = details; 44 | IsCompleted = false; 45 | } 46 | 47 | public event PropertyChangedEventHandler PropertyChanged; 48 | 49 | protected void OnPropertyChanged(string name) 50 | { 51 | if (PropertyChanged != null) 52 | { 53 | PropertyChanged(this, new PropertyChangedEventArgs(name)); 54 | } 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /SuperAdventure/Engine/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Engine")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Engine")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("4166ef61-d200-4a0d-9b05-afee45c2c8b7")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /SuperAdventure/Engine/Quest.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 Engine 8 | { 9 | public class Quest 10 | { 11 | public int ID { get; set; } 12 | public string Name { get; set; } 13 | public string Description { get; set; } 14 | public int RewardExperiencePoints { get; set; } 15 | public int RewardGold { get; set; } 16 | public Item RewardItem { get; set; } 17 | public List QuestCompletionItems { get; set; } 18 | 19 | public Quest(int id, string name, string description, 20 | int rewardExperiencePoints, int rewardGold) 21 | { 22 | ID = id; 23 | Name = name; 24 | Description = description; 25 | RewardExperiencePoints = rewardExperiencePoints; 26 | RewardGold = rewardGold; 27 | QuestCompletionItems = new List(); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /SuperAdventure/Engine/QuestCompletionItem.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 Engine 8 | { 9 | public class QuestCompletionItem 10 | { 11 | public Item Details { get; set; } 12 | public int Quantity { get; set; } 13 | 14 | public QuestCompletionItem(Item details, int quantity) 15 | { 16 | Details = details; 17 | Quantity = quantity; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /SuperAdventure/Engine/RandomNumberGenerator.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 Engine 8 | { 9 | public static class RandomNumberGenerator 10 | { 11 | private static Random _generator = new Random(); 12 | 13 | public static int NumberBetween(int minimumValue, int maximumValue) 14 | { 15 | return _generator.Next(minimumValue, maximumValue + 1); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /SuperAdventure/Engine/Vendor.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel; 3 | using System.Linq; 4 | 5 | namespace Engine 6 | { 7 | public class Vendor : INotifyPropertyChanged 8 | { 9 | public string Name { get; set; } 10 | public BindingList Inventory { get; private set; } 11 | 12 | public Vendor(string name) 13 | { 14 | Name = name; 15 | Inventory = new BindingList(); 16 | } 17 | 18 | public void AddItemToInventory(Item itemToAdd, int quantity = 1) 19 | { 20 | InventoryItem item = Inventory.SingleOrDefault( 21 | ii => ii.Details.ID == itemToAdd.ID); 22 | 23 | if (item == null) 24 | { 25 | // They didn't have the item, so add it to their inventory 26 | Inventory.Add(new InventoryItem(itemToAdd, quantity)); 27 | } 28 | else 29 | { 30 | // They have the item in their inventory, so increase the quantity 31 | item.Quantity += quantity; 32 | } 33 | 34 | OnPropertyChanged("Inventory"); 35 | } 36 | public void RemoveItemFromInventory(Item itemToRemove, int quantity = 1) 37 | { 38 | InventoryItem item = Inventory.SingleOrDefault( 39 | ii => ii.Details.ID == itemToRemove.ID); 40 | 41 | if (item == null) 42 | { 43 | // The item is not in the player's inventory, so ignore it. 44 | // We might want to raise an error for this situation 45 | } 46 | else 47 | { 48 | // They have the item in their inventory, so decrease the quantity 49 | item.Quantity -= quantity; 50 | 51 | // Don't allow negative quantities. 52 | // We might want to raise an error for this situation 53 | if (item.Quantity < 0) 54 | { 55 | item.Quantity = 0; 56 | } 57 | 58 | // If the quantity is zero, remove the item from the list 59 | if (item.Quantity == 0) 60 | { 61 | Inventory.Remove(item); 62 | } 63 | 64 | // Notify the UI that the inventory has changed 65 | OnPropertyChanged("Inventory"); 66 | } 67 | } 68 | 69 | public event PropertyChangedEventHandler PropertyChanged; 70 | 71 | private void OnPropertyChanged(string name) 72 | { 73 | if (PropertyChanged != null) 74 | { 75 | PropertyChanged(this, new PropertyChangedEventArgs(name)); 76 | } 77 | } 78 | } 79 | } -------------------------------------------------------------------------------- /SuperAdventure/Engine/Weapon.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 Engine 8 | { 9 | public class Weapon : Item 10 | { 11 | public int MinimumDamage { get; set; } 12 | public int MaximumDamage { get; set; } 13 | 14 | public Weapon(int id, string name, string namePlural, 15 | int minimumDamage, int maximumDamage, int price) : 16 | base(id, name, namePlural, price) 17 | { 18 | MinimumDamage = minimumDamage; 19 | MaximumDamage = maximumDamage; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /SuperAdventure/Engine/World.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 Engine 8 | { 9 | public static class World 10 | { 11 | public static readonly List Items = new List(); 12 | public static readonly List Monsters = new List(); 13 | public static readonly List Quests = new List(); 14 | public static readonly List Locations = new List(); 15 | 16 | public const int ITEM_ID_RUSTY_SWORD = 1; 17 | public const int ITEM_ID_RAT_TAIL = 2; 18 | public const int ITEM_ID_PIECE_OF_FUR = 3; 19 | public const int ITEM_ID_SNAKE_FANG = 4; 20 | public const int ITEM_ID_SNAKESKIN = 5; 21 | public const int ITEM_ID_CLUB = 6; 22 | public const int ITEM_ID_HEALING_POTION = 7; 23 | public const int ITEM_ID_SPIDER_FANG = 8; 24 | public const int ITEM_ID_SPIDER_SILK = 9; 25 | public const int ITEM_ID_ADVENTURER_PASS = 10; 26 | 27 | public const int UNSELLABLE_ITEM_PRICE = -1; 28 | 29 | public const int MONSTER_ID_RAT = 1; 30 | public const int MONSTER_ID_SNAKE = 2; 31 | public const int MONSTER_ID_GIANT_SPIDER = 3; 32 | 33 | public const int QUEST_ID_CLEAR_ALCHEMIST_GARDEN = 1; 34 | public const int QUEST_ID_CLEAR_FARMERS_FIELD = 2; 35 | 36 | public const int LOCATION_ID_HOME = 1; 37 | public const int LOCATION_ID_TOWN_SQUARE = 2; 38 | public const int LOCATION_ID_GUARD_POST = 3; 39 | public const int LOCATION_ID_ALCHEMIST_HUT = 4; 40 | public const int LOCATION_ID_ALCHEMISTS_GARDEN = 5; 41 | public const int LOCATION_ID_FARMHOUSE = 6; 42 | public const int LOCATION_ID_FARM_FIELD = 7; 43 | public const int LOCATION_ID_BRIDGE = 8; 44 | public const int LOCATION_ID_SPIDER_FIELD = 9; 45 | 46 | static World() 47 | { 48 | PopulateItems(); 49 | PopulateMonsters(); 50 | PopulateQuests(); 51 | PopulateLocations(); 52 | } 53 | 54 | private static void PopulateItems() 55 | { 56 | Items.Add(new Weapon(ITEM_ID_RUSTY_SWORD, "Rusty sword", "Rusty swords", 0, 5, 5)); 57 | Items.Add(new Item(ITEM_ID_RAT_TAIL, "Rat tail", "Rat tails", 1)); 58 | Items.Add(new Item(ITEM_ID_PIECE_OF_FUR, "Piece of fur", "Pieces of fur", 1)); 59 | Items.Add(new Item(ITEM_ID_SNAKE_FANG, "Snake fang", "Snake fangs", 1)); 60 | Items.Add(new Item(ITEM_ID_SNAKESKIN, "Snakeskin", "Snakeskins", 2)); 61 | Items.Add(new Weapon(ITEM_ID_CLUB, "Club", "Clubs", 3, 10, 8)); 62 | Items.Add(new HealingPotion(ITEM_ID_HEALING_POTION, "Healing potion", "Healing potions", 5, 3)); 63 | Items.Add(new Item(ITEM_ID_SPIDER_FANG, "Spider fang", "Spider fangs", 1)); 64 | Items.Add(new Item(ITEM_ID_SPIDER_SILK, "Spider silk", "Spider silks", 1)); 65 | Items.Add(new Item(ITEM_ID_ADVENTURER_PASS, "Adventurer pass", "Adventurer passes", UNSELLABLE_ITEM_PRICE)); 66 | } 67 | 68 | private static void PopulateMonsters() 69 | { 70 | Monster rat = new Monster(MONSTER_ID_RAT, "Rat", 5, 3, 10, 3, 3); 71 | rat.LootTable.Add(new LootItem(ItemByID(ITEM_ID_RAT_TAIL), 75, false)); 72 | rat.LootTable.Add(new LootItem(ItemByID(ITEM_ID_PIECE_OF_FUR), 75, true)); 73 | 74 | Monster snake = new Monster(MONSTER_ID_SNAKE, "Snake", 5, 3, 10, 3, 3); 75 | snake.LootTable.Add(new LootItem(ItemByID(ITEM_ID_SNAKE_FANG), 75, false)); 76 | snake.LootTable.Add(new LootItem(ItemByID(ITEM_ID_SNAKESKIN), 75, true)); 77 | 78 | Monster giantSpider = new Monster(MONSTER_ID_GIANT_SPIDER, 79 | "Giant spider", 20, 5, 40, 10, 10); 80 | giantSpider.LootTable.Add(new LootItem( 81 | ItemByID(ITEM_ID_SPIDER_FANG), 75, true)); 82 | giantSpider.LootTable.Add(new LootItem( 83 | ItemByID(ITEM_ID_SPIDER_SILK), 25, false)); 84 | 85 | Monsters.Add(rat); 86 | Monsters.Add(snake); 87 | Monsters.Add(giantSpider); 88 | } 89 | 90 | private static void PopulateQuests() 91 | { 92 | Quest clearAlchemistGarden = new Quest(QUEST_ID_CLEAR_ALCHEMIST_GARDEN, 93 | "Clear the alchemist's garden", 94 | "Kill rats in the alchemist's garden and bring back 3 rat tails." + 95 | "You will receive a healing potion and 10 gold pieces.", 20, 10); 96 | 97 | clearAlchemistGarden.QuestCompletionItems.Add(new QuestCompletionItem( 98 | ItemByID(ITEM_ID_RAT_TAIL), 3)); 99 | 100 | clearAlchemistGarden.RewardItem = ItemByID(ITEM_ID_HEALING_POTION); 101 | 102 | Quest clearFarmersField = new Quest(QUEST_ID_CLEAR_FARMERS_FIELD, 103 | "Clear the farmer's field", 104 | "Kill snakes in the farmer's field and bring back 3 snake fangs." + 105 | "You will receive an adventurer's pass and 20 gold pieces.", 20, 20); 106 | 107 | clearFarmersField.QuestCompletionItems.Add(new QuestCompletionItem( 108 | ItemByID(ITEM_ID_SNAKE_FANG), 3)); 109 | 110 | clearFarmersField.RewardItem = ItemByID(ITEM_ID_ADVENTURER_PASS); 111 | 112 | Quests.Add(clearAlchemistGarden); 113 | Quests.Add(clearFarmersField); 114 | } 115 | 116 | private static void PopulateLocations() 117 | { 118 | // Create each location 119 | Location home = new Location(LOCATION_ID_HOME, "Home", 120 | "Your house. You really need to clean up the place."); 121 | 122 | Location townSquare = new Location(LOCATION_ID_TOWN_SQUARE, 123 | "Town square", "You see a fountain."); 124 | Vendor bobTheRatCatcher = new Vendor("Bob the Rat-Catcher"); 125 | bobTheRatCatcher.AddItemToInventory(ItemByID(ITEM_ID_PIECE_OF_FUR), 5); 126 | bobTheRatCatcher.AddItemToInventory(ItemByID(ITEM_ID_RAT_TAIL), 3); 127 | townSquare.VendorWorkingHere = bobTheRatCatcher; 128 | 129 | Location alchemistHut = new Location(LOCATION_ID_ALCHEMIST_HUT, 130 | "Alchemist's hut", "There are many strange plants on the shelves."); 131 | alchemistHut.QuestAvailableHere = QuestByID(QUEST_ID_CLEAR_ALCHEMIST_GARDEN); 132 | 133 | Location alchemistsGarden = new Location(LOCATION_ID_ALCHEMISTS_GARDEN, 134 | "Alchemist's garden", "Many plants are growing here."); 135 | alchemistsGarden.MonsterLivingHere = MonsterByID(MONSTER_ID_RAT); 136 | 137 | Location farmhouse = new Location(LOCATION_ID_FARMHOUSE, 138 | "Farmhouse", "There is a small farmhouse, with a farmer in front."); 139 | farmhouse.QuestAvailableHere = QuestByID(QUEST_ID_CLEAR_FARMERS_FIELD); 140 | 141 | Location farmersField = new Location(LOCATION_ID_FARM_FIELD, 142 | "Farmer's field", "You see rows of vegetables growing here."); 143 | farmersField.MonsterLivingHere = MonsterByID(MONSTER_ID_SNAKE); 144 | 145 | Location guardPost = new Location(LOCATION_ID_GUARD_POST, 146 | "Guard post", "There is a large, tough-looking guard here.", 147 | ItemByID(ITEM_ID_ADVENTURER_PASS)); 148 | 149 | Location bridge = new Location(LOCATION_ID_BRIDGE, 150 | "Bridge", "A stone bridge crosses a wide river."); 151 | 152 | Location spiderField = new Location(LOCATION_ID_SPIDER_FIELD, 153 | "Forest", "You see spider webs covering covering the trees in this forest."); 154 | spiderField.MonsterLivingHere = MonsterByID(MONSTER_ID_GIANT_SPIDER); 155 | 156 | // Link the locations together 157 | home.LocationToNorth = townSquare; 158 | 159 | townSquare.LocationToNorth = alchemistHut; 160 | townSquare.LocationToSouth = home; 161 | townSquare.LocationToEast = guardPost; 162 | townSquare.LocationToWest = farmhouse; 163 | 164 | farmhouse.LocationToEast = townSquare; 165 | farmhouse.LocationToWest = farmersField; 166 | 167 | farmersField.LocationToEast = farmhouse; 168 | 169 | alchemistHut.LocationToSouth = townSquare; 170 | alchemistHut.LocationToNorth = alchemistsGarden; 171 | 172 | alchemistsGarden.LocationToSouth = alchemistHut; 173 | 174 | guardPost.LocationToEast = bridge; 175 | guardPost.LocationToWest = townSquare; 176 | 177 | bridge.LocationToWest = guardPost; 178 | bridge.LocationToEast = spiderField; 179 | 180 | spiderField.LocationToWest = bridge; 181 | 182 | // Add the locations to the static list 183 | Locations.Add(home); 184 | Locations.Add(townSquare); 185 | Locations.Add(guardPost); 186 | Locations.Add(alchemistHut); 187 | Locations.Add(alchemistsGarden); 188 | Locations.Add(farmhouse); 189 | Locations.Add(farmersField); 190 | Locations.Add(bridge); 191 | Locations.Add(spiderField); 192 | } 193 | 194 | public static Item ItemByID(int id) 195 | { 196 | foreach(Item item in Items) 197 | { 198 | if(item.ID == id) 199 | { 200 | return item; 201 | } 202 | } 203 | 204 | return null; 205 | } 206 | 207 | public static Monster MonsterByID(int id) 208 | { 209 | foreach(Monster monster in Monsters) 210 | { 211 | if(monster.ID == id) 212 | { 213 | return monster; 214 | } 215 | } 216 | 217 | return null; 218 | } 219 | 220 | public static Quest QuestByID(int id) 221 | { 222 | foreach(Quest quest in Quests) 223 | { 224 | if(quest.ID == id) 225 | { 226 | return quest; 227 | } 228 | } 229 | 230 | return null; 231 | } 232 | 233 | public static Location LocationByID(int id) 234 | { 235 | foreach(Location location in Locations) 236 | { 237 | if(location.ID == id) 238 | { 239 | return location; 240 | } 241 | } 242 | 243 | return null; 244 | } 245 | } 246 | } 247 | -------------------------------------------------------------------------------- /SuperAdventure/SuperAdventure.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.23107.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SuperAdventure", "SuperAdventure\SuperAdventure.csproj", "{FE7A0834-305D-4416-9E95-A8D986E9B881}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Engine", "Engine\Engine.csproj", "{4166EF61-D200-4A0D-9B05-AFEE45C2C8B7}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {FE7A0834-305D-4416-9E95-A8D986E9B881}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {FE7A0834-305D-4416-9E95-A8D986E9B881}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {FE7A0834-305D-4416-9E95-A8D986E9B881}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {FE7A0834-305D-4416-9E95-A8D986E9B881}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {4166EF61-D200-4A0D-9B05-AFEE45C2C8B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {4166EF61-D200-4A0D-9B05-AFEE45C2C8B7}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {4166EF61-D200-4A0D-9B05-AFEE45C2C8B7}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {4166EF61-D200-4A0D-9B05-AFEE45C2C8B7}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /SuperAdventure/SuperAdventure/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /SuperAdventure/SuperAdventure/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 SuperAdventure 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 SuperAdventure()); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /SuperAdventure/SuperAdventure/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("SuperAdventure")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("SuperAdventure")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("fe7a0834-305d-4416-9e95-a8d986e9b881")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /SuperAdventure/SuperAdventure/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace SuperAdventure.Properties 12 | { 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources 26 | { 27 | 28 | private static global::System.Resources.ResourceManager resourceMan; 29 | 30 | private static global::System.Globalization.CultureInfo resourceCulture; 31 | 32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 33 | internal Resources() 34 | { 35 | } 36 | 37 | /// 38 | /// Returns the cached ResourceManager instance used by this class. 39 | /// 40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 41 | internal static global::System.Resources.ResourceManager ResourceManager 42 | { 43 | get 44 | { 45 | if ((resourceMan == null)) 46 | { 47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SuperAdventure.Properties.Resources", typeof(Resources).Assembly); 48 | resourceMan = temp; 49 | } 50 | return resourceMan; 51 | } 52 | } 53 | 54 | /// 55 | /// Overrides the current thread's CurrentUICulture property for all 56 | /// resource lookups using this strongly typed resource class. 57 | /// 58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 59 | internal static global::System.Globalization.CultureInfo Culture 60 | { 61 | get 62 | { 63 | return resourceCulture; 64 | } 65 | set 66 | { 67 | resourceCulture = value; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /SuperAdventure/SuperAdventure/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 | -------------------------------------------------------------------------------- /SuperAdventure/SuperAdventure/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace SuperAdventure.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /SuperAdventure/SuperAdventure/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SuperAdventure/SuperAdventure/SuperAdventure.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace SuperAdventure 2 | { 3 | partial class SuperAdventure 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 | this.label1 = new System.Windows.Forms.Label(); 32 | this.label2 = new System.Windows.Forms.Label(); 33 | this.label3 = new System.Windows.Forms.Label(); 34 | this.label4 = new System.Windows.Forms.Label(); 35 | this.lblHitPoints = new System.Windows.Forms.Label(); 36 | this.lblGold = new System.Windows.Forms.Label(); 37 | this.lblExperience = new System.Windows.Forms.Label(); 38 | this.lblLevel = new System.Windows.Forms.Label(); 39 | this.label5 = new System.Windows.Forms.Label(); 40 | this.cboWeapons = new System.Windows.Forms.ComboBox(); 41 | this.cboPotions = new System.Windows.Forms.ComboBox(); 42 | this.btnUseWeapon = new System.Windows.Forms.Button(); 43 | this.btnUsePotion = new System.Windows.Forms.Button(); 44 | this.btnNorth = new System.Windows.Forms.Button(); 45 | this.btnEast = new System.Windows.Forms.Button(); 46 | this.btnSouth = new System.Windows.Forms.Button(); 47 | this.btnWest = new System.Windows.Forms.Button(); 48 | this.btnTrade = new System.Windows.Forms.Button(); 49 | this.rtbLocation = new System.Windows.Forms.RichTextBox(); 50 | this.rtbMessages = new System.Windows.Forms.RichTextBox(); 51 | this.dgvInventory = new System.Windows.Forms.DataGridView(); 52 | this.dgvQuests = new System.Windows.Forms.DataGridView(); 53 | ((System.ComponentModel.ISupportInitialize)(this.dgvInventory)).BeginInit(); 54 | ((System.ComponentModel.ISupportInitialize)(this.dgvQuests)).BeginInit(); 55 | this.SuspendLayout(); 56 | // 57 | // label1 58 | // 59 | this.label1.AutoSize = true; 60 | this.label1.Location = new System.Drawing.Point(18, 20); 61 | this.label1.Name = "label1"; 62 | this.label1.Size = new System.Drawing.Size(55, 13); 63 | this.label1.TabIndex = 0; 64 | this.label1.Text = "Hit Points:"; 65 | // 66 | // label2 67 | // 68 | this.label2.AutoSize = true; 69 | this.label2.Location = new System.Drawing.Point(18, 46); 70 | this.label2.Name = "label2"; 71 | this.label2.Size = new System.Drawing.Size(32, 13); 72 | this.label2.TabIndex = 1; 73 | this.label2.Text = "Gold:"; 74 | // 75 | // label3 76 | // 77 | this.label3.AutoSize = true; 78 | this.label3.Location = new System.Drawing.Point(18, 74); 79 | this.label3.Name = "label3"; 80 | this.label3.Size = new System.Drawing.Size(63, 13); 81 | this.label3.TabIndex = 2; 82 | this.label3.Text = "Experience:"; 83 | // 84 | // label4 85 | // 86 | this.label4.AutoSize = true; 87 | this.label4.Location = new System.Drawing.Point(18, 100); 88 | this.label4.Name = "label4"; 89 | this.label4.Size = new System.Drawing.Size(36, 13); 90 | this.label4.TabIndex = 3; 91 | this.label4.Text = "Level:"; 92 | // 93 | // lblHitPoints 94 | // 95 | this.lblHitPoints.AutoSize = true; 96 | this.lblHitPoints.Location = new System.Drawing.Point(110, 19); 97 | this.lblHitPoints.Name = "lblHitPoints"; 98 | this.lblHitPoints.Size = new System.Drawing.Size(13, 13); 99 | this.lblHitPoints.TabIndex = 4; 100 | this.lblHitPoints.Text = "0"; 101 | // 102 | // lblGold 103 | // 104 | this.lblGold.AutoSize = true; 105 | this.lblGold.Location = new System.Drawing.Point(110, 45); 106 | this.lblGold.Name = "lblGold"; 107 | this.lblGold.Size = new System.Drawing.Size(13, 13); 108 | this.lblGold.TabIndex = 5; 109 | this.lblGold.Text = "0"; 110 | // 111 | // lblExperience 112 | // 113 | this.lblExperience.AutoSize = true; 114 | this.lblExperience.Location = new System.Drawing.Point(110, 73); 115 | this.lblExperience.Name = "lblExperience"; 116 | this.lblExperience.Size = new System.Drawing.Size(13, 13); 117 | this.lblExperience.TabIndex = 6; 118 | this.lblExperience.Text = "0"; 119 | // 120 | // lblLevel 121 | // 122 | this.lblLevel.AutoSize = true; 123 | this.lblLevel.Location = new System.Drawing.Point(110, 99); 124 | this.lblLevel.Name = "lblLevel"; 125 | this.lblLevel.Size = new System.Drawing.Size(13, 13); 126 | this.lblLevel.TabIndex = 7; 127 | this.lblLevel.Text = "0"; 128 | // 129 | // label5 130 | // 131 | this.label5.AutoSize = true; 132 | this.label5.Location = new System.Drawing.Point(617, 531); 133 | this.label5.Name = "label5"; 134 | this.label5.Size = new System.Drawing.Size(70, 13); 135 | this.label5.TabIndex = 8; 136 | this.label5.Text = "Select Action"; 137 | // 138 | // cboWeapons 139 | // 140 | this.cboWeapons.FormattingEnabled = true; 141 | this.cboWeapons.Location = new System.Drawing.Point(369, 559); 142 | this.cboWeapons.Name = "cboWeapons"; 143 | this.cboWeapons.Size = new System.Drawing.Size(121, 21); 144 | this.cboWeapons.TabIndex = 9; 145 | // 146 | // cboPotions 147 | // 148 | this.cboPotions.FormattingEnabled = true; 149 | this.cboPotions.Location = new System.Drawing.Point(369, 593); 150 | this.cboPotions.Name = "cboPotions"; 151 | this.cboPotions.Size = new System.Drawing.Size(121, 21); 152 | this.cboPotions.TabIndex = 10; 153 | // 154 | // btnUseWeapon 155 | // 156 | this.btnUseWeapon.Location = new System.Drawing.Point(620, 559); 157 | this.btnUseWeapon.Name = "btnUseWeapon"; 158 | this.btnUseWeapon.Size = new System.Drawing.Size(75, 23); 159 | this.btnUseWeapon.TabIndex = 11; 160 | this.btnUseWeapon.Text = "Use"; 161 | this.btnUseWeapon.UseVisualStyleBackColor = true; 162 | this.btnUseWeapon.Click += new System.EventHandler(this.btnUseWeapon_Click); 163 | // 164 | // btnUsePotion 165 | // 166 | this.btnUsePotion.Location = new System.Drawing.Point(620, 593); 167 | this.btnUsePotion.Name = "btnUsePotion"; 168 | this.btnUsePotion.Size = new System.Drawing.Size(75, 23); 169 | this.btnUsePotion.TabIndex = 12; 170 | this.btnUsePotion.Text = "Use"; 171 | this.btnUsePotion.UseVisualStyleBackColor = true; 172 | this.btnUsePotion.Click += new System.EventHandler(this.btnUsePotion_Click); 173 | // 174 | // btnNorth 175 | // 176 | this.btnNorth.Location = new System.Drawing.Point(493, 433); 177 | this.btnNorth.Name = "btnNorth"; 178 | this.btnNorth.Size = new System.Drawing.Size(75, 23); 179 | this.btnNorth.TabIndex = 13; 180 | this.btnNorth.Text = "North"; 181 | this.btnNorth.UseVisualStyleBackColor = true; 182 | this.btnNorth.Click += new System.EventHandler(this.btnNorth_Click); 183 | // 184 | // btnEast 185 | // 186 | this.btnEast.Location = new System.Drawing.Point(573, 457); 187 | this.btnEast.Name = "btnEast"; 188 | this.btnEast.Size = new System.Drawing.Size(75, 23); 189 | this.btnEast.TabIndex = 14; 190 | this.btnEast.Text = "East"; 191 | this.btnEast.UseVisualStyleBackColor = true; 192 | this.btnEast.Click += new System.EventHandler(this.btnEast_Click); 193 | // 194 | // btnSouth 195 | // 196 | this.btnSouth.Location = new System.Drawing.Point(493, 487); 197 | this.btnSouth.Name = "btnSouth"; 198 | this.btnSouth.Size = new System.Drawing.Size(75, 23); 199 | this.btnSouth.TabIndex = 15; 200 | this.btnSouth.Text = "South"; 201 | this.btnSouth.UseVisualStyleBackColor = true; 202 | this.btnSouth.Click += new System.EventHandler(this.btnSouth_Click); 203 | // 204 | // btnWest 205 | // 206 | this.btnWest.Location = new System.Drawing.Point(412, 457); 207 | this.btnWest.Name = "btnWest"; 208 | this.btnWest.Size = new System.Drawing.Size(75, 23); 209 | this.btnWest.TabIndex = 16; 210 | this.btnWest.Text = "West"; 211 | this.btnWest.UseVisualStyleBackColor = true; 212 | this.btnWest.Click += new System.EventHandler(this.btnWest_Click); 213 | // 214 | // rtbLocation 215 | // 216 | this.rtbLocation.Location = new System.Drawing.Point(347, 19); 217 | this.rtbLocation.Name = "rtbLocation"; 218 | this.rtbLocation.ReadOnly = true; 219 | this.rtbLocation.Size = new System.Drawing.Size(360, 105); 220 | this.rtbLocation.TabIndex = 17; 221 | this.rtbLocation.Text = ""; 222 | // 223 | // rtbMessages 224 | // 225 | this.rtbMessages.Location = new System.Drawing.Point(347, 130); 226 | this.rtbMessages.Name = "rtbMessages"; 227 | this.rtbMessages.ReadOnly = true; 228 | this.rtbMessages.Size = new System.Drawing.Size(360, 286); 229 | this.rtbMessages.TabIndex = 18; 230 | this.rtbMessages.Text = ""; 231 | // 232 | // dgvInventory 233 | // 234 | this.dgvInventory.AllowUserToAddRows = false; 235 | this.dgvInventory.AllowUserToDeleteRows = false; 236 | this.dgvInventory.AllowUserToResizeRows = false; 237 | this.dgvInventory.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; 238 | this.dgvInventory.EditMode = System.Windows.Forms.DataGridViewEditMode.EditProgrammatically; 239 | this.dgvInventory.Enabled = false; 240 | this.dgvInventory.Location = new System.Drawing.Point(16, 130); 241 | this.dgvInventory.MultiSelect = false; 242 | this.dgvInventory.Name = "dgvInventory"; 243 | this.dgvInventory.ReadOnly = true; 244 | this.dgvInventory.RowHeadersVisible = false; 245 | this.dgvInventory.Size = new System.Drawing.Size(312, 309); 246 | this.dgvInventory.TabIndex = 19; 247 | // 248 | // dgvQuests 249 | // 250 | this.dgvQuests.AllowUserToAddRows = false; 251 | this.dgvQuests.AllowUserToDeleteRows = false; 252 | this.dgvQuests.AllowUserToResizeRows = false; 253 | this.dgvQuests.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; 254 | this.dgvQuests.EditMode = System.Windows.Forms.DataGridViewEditMode.EditProgrammatically; 255 | this.dgvQuests.Enabled = false; 256 | this.dgvQuests.Location = new System.Drawing.Point(16, 446); 257 | this.dgvQuests.MultiSelect = false; 258 | this.dgvQuests.Name = "dgvQuests"; 259 | this.dgvQuests.RowHeadersVisible = false; 260 | this.dgvQuests.Size = new System.Drawing.Size(312, 189); 261 | this.dgvQuests.TabIndex = 20; 262 | // 263 | // btnTrade 264 | // 265 | this.btnTrade.Location = new System.Drawing.Point(493, 620); 266 | this.btnTrade.Name = "btnTrade"; 267 | this.btnTrade.Size = new System.Drawing.Size(75, 23); 268 | this.btnTrade.TabIndex = 21; 269 | this.btnTrade.Text = "Trade"; 270 | this.btnTrade.UseVisualStyleBackColor = true; 271 | this.btnTrade.Click += 272 | new System.EventHandler(this.btnTrade_Click); 273 | // 274 | // SuperAdventure 275 | // 276 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 277 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 278 | this.ClientSize = new System.Drawing.Size(719, 651); 279 | this.Controls.Add(this.dgvQuests); 280 | this.Controls.Add(this.dgvInventory); 281 | this.Controls.Add(this.rtbMessages); 282 | this.Controls.Add(this.rtbLocation); 283 | this.Controls.Add(this.btnWest); 284 | this.Controls.Add(this.btnSouth); 285 | this.Controls.Add(this.btnEast); 286 | this.Controls.Add(this.btnNorth); 287 | this.Controls.Add(this.btnUsePotion); 288 | this.Controls.Add(this.btnUseWeapon); 289 | this.Controls.Add(this.btnTrade); 290 | this.Controls.Add(this.cboPotions); 291 | this.Controls.Add(this.cboWeapons); 292 | this.Controls.Add(this.label5); 293 | this.Controls.Add(this.lblLevel); 294 | this.Controls.Add(this.lblExperience); 295 | this.Controls.Add(this.lblGold); 296 | this.Controls.Add(this.lblHitPoints); 297 | this.Controls.Add(this.label4); 298 | this.Controls.Add(this.label3); 299 | this.Controls.Add(this.label2); 300 | this.Controls.Add(this.label1); 301 | this.Name = "SuperAdventure"; 302 | this.Text = "My Game"; 303 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.SuperAdventure_FormClosing); 304 | ((System.ComponentModel.ISupportInitialize)(this.dgvInventory)).EndInit(); 305 | ((System.ComponentModel.ISupportInitialize)(this.dgvQuests)).EndInit(); 306 | this.ResumeLayout(false); 307 | this.PerformLayout(); 308 | 309 | } 310 | 311 | #endregion 312 | 313 | private System.Windows.Forms.Label label1; 314 | private System.Windows.Forms.Label label2; 315 | private System.Windows.Forms.Label label3; 316 | private System.Windows.Forms.Label label4; 317 | private System.Windows.Forms.Label lblHitPoints; 318 | private System.Windows.Forms.Label lblGold; 319 | private System.Windows.Forms.Label lblExperience; 320 | private System.Windows.Forms.Label lblLevel; 321 | private System.Windows.Forms.Label label5; 322 | private System.Windows.Forms.ComboBox cboWeapons; 323 | private System.Windows.Forms.ComboBox cboPotions; 324 | private System.Windows.Forms.Button btnUseWeapon; 325 | private System.Windows.Forms.Button btnUsePotion; 326 | private System.Windows.Forms.Button btnNorth; 327 | private System.Windows.Forms.Button btnEast; 328 | private System.Windows.Forms.Button btnSouth; 329 | private System.Windows.Forms.Button btnWest; 330 | private System.Windows.Forms.Button btnTrade; 331 | private System.Windows.Forms.RichTextBox rtbLocation; 332 | private System.Windows.Forms.RichTextBox rtbMessages; 333 | private System.Windows.Forms.DataGridView dgvInventory; 334 | private System.Windows.Forms.DataGridView dgvQuests; 335 | } 336 | } 337 | 338 | -------------------------------------------------------------------------------- /SuperAdventure/SuperAdventure/SuperAdventure.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.IO; 11 | 12 | using Engine; 13 | 14 | namespace SuperAdventure 15 | { 16 | public partial class SuperAdventure : Form 17 | { 18 | private const string PLAYER_DATA_FILE_NAME = "PlayerData.xml"; 19 | 20 | private Player _player; 21 | 22 | public SuperAdventure() 23 | { 24 | InitializeComponent(); 25 | 26 | if (File.Exists(PLAYER_DATA_FILE_NAME)) 27 | { 28 | _player = Player.CreatePlayerFromXmlString(File.ReadAllText(PLAYER_DATA_FILE_NAME)); 29 | } 30 | else 31 | { 32 | _player = Player.CreateDefaultPlayer(); 33 | } 34 | 35 | lblHitPoints.DataBindings.Add("Text", _player, "CurrentHitPoints"); 36 | lblGold.DataBindings.Add("Text", _player, "Gold"); 37 | lblExperience.DataBindings.Add("Text", _player, "ExperiencePoints"); 38 | lblLevel.DataBindings.Add("Text", _player, "Level"); 39 | 40 | dgvInventory.RowHeadersVisible = false; 41 | dgvInventory.AutoGenerateColumns = false; 42 | 43 | dgvInventory.DataSource = _player.Inventory; 44 | 45 | dgvInventory.Columns.Add(new DataGridViewTextBoxColumn 46 | { 47 | HeaderText = "Name", 48 | Width = 197, 49 | DataPropertyName = "Description" 50 | }); 51 | 52 | dgvInventory.Columns.Add(new DataGridViewTextBoxColumn 53 | { 54 | HeaderText = "Quantity", 55 | DataPropertyName = "Quantity" 56 | }); 57 | 58 | dgvQuests.RowHeadersVisible = false; 59 | dgvQuests.AutoGenerateColumns = false; 60 | 61 | dgvQuests.DataSource = _player.Quests; 62 | 63 | dgvQuests.Columns.Add(new DataGridViewTextBoxColumn 64 | { 65 | HeaderText = "Name", 66 | Width = 197, 67 | DataPropertyName = "Name" 68 | }); 69 | 70 | dgvQuests.Columns.Add(new DataGridViewTextBoxColumn 71 | { 72 | HeaderText = "Done?", 73 | DataPropertyName = "IsCompleted" 74 | }); 75 | 76 | cboWeapons.DataSource = _player.Weapons; 77 | cboWeapons.DisplayMember = "Name"; 78 | cboWeapons.ValueMember = "Id"; 79 | 80 | if (_player.CurrentWeapon != null) 81 | { 82 | cboWeapons.SelectedItem = _player.CurrentWeapon; 83 | } 84 | 85 | cboWeapons.SelectedIndexChanged += cboWeapons_SelectedIndexChanged; 86 | 87 | cboPotions.DataSource = _player.Potions; 88 | cboPotions.DisplayMember = "Name"; 89 | cboPotions.ValueMember = "Id"; 90 | 91 | _player.PropertyChanged += PlayerOnPropertyChanged; 92 | _player.OnMessage += DisplayMessage; 93 | 94 | _player.MoveTo(_player.CurrentLocation); 95 | } 96 | 97 | private void DisplayMessage(object sender, MessageEventArgs messageEventArgs) 98 | { 99 | rtbMessages.Text += messageEventArgs.Message + Environment.NewLine; 100 | 101 | if (messageEventArgs.AddExtraNewLine) 102 | { 103 | rtbMessages.Text += Environment.NewLine; 104 | } 105 | 106 | rtbMessages.SelectionStart = rtbMessages.Text.Length; 107 | rtbMessages.ScrollToCaret(); 108 | } 109 | 110 | private void PlayerOnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs) 111 | { 112 | if (propertyChangedEventArgs.PropertyName == "Weapons") 113 | { 114 | cboWeapons.DataSource = _player.Weapons; 115 | 116 | if (!_player.Weapons.Any()) 117 | { 118 | cboWeapons.Visible = false; 119 | btnUseWeapon.Visible = false; 120 | } 121 | } 122 | 123 | if (propertyChangedEventArgs.PropertyName == "Potions") 124 | { 125 | cboPotions.DataSource = _player.Potions; 126 | 127 | if (!_player.Potions.Any()) 128 | { 129 | cboPotions.Visible = false; 130 | btnUsePotion.Visible = false; 131 | } 132 | } 133 | 134 | if (propertyChangedEventArgs.PropertyName == "CurrentLocation") 135 | { 136 | btnTrade.Visible = (_player.CurrentLocation.VendorWorkingHere != null); 137 | 138 | // Show/hide available movement buttons 139 | btnNorth.Visible = (_player.CurrentLocation.LocationToNorth != null); 140 | btnEast.Visible = (_player.CurrentLocation.LocationToEast != null); 141 | btnSouth.Visible = (_player.CurrentLocation.LocationToSouth != null); 142 | btnWest.Visible = (_player.CurrentLocation.LocationToWest != null); 143 | 144 | // Display current location name and description 145 | rtbLocation.Text = _player.CurrentLocation.Name + Environment.NewLine; 146 | rtbLocation.Text += _player.CurrentLocation.Description + Environment.NewLine; 147 | 148 | if (_player.CurrentLocation.MonsterLivingHere == null) 149 | { 150 | cboWeapons.Visible = false; 151 | cboPotions.Visible = false; 152 | btnUseWeapon.Visible = false; 153 | btnUsePotion.Visible = false; 154 | } 155 | else 156 | { 157 | cboWeapons.Visible = _player.Weapons.Any(); 158 | cboPotions.Visible = _player.Potions.Any(); 159 | btnUseWeapon.Visible = _player.Weapons.Any(); 160 | btnUsePotion.Visible = _player.Potions.Any(); 161 | } 162 | } 163 | } 164 | 165 | private void btnTrade_Click(object sender, EventArgs e) 166 | { 167 | TradingScreen tradingScreen = new TradingScreen(_player); 168 | tradingScreen.StartPosition = FormStartPosition.CenterParent; 169 | tradingScreen.ShowDialog(this); 170 | } 171 | 172 | private void btnNorth_Click(object sender, EventArgs e) 173 | { 174 | _player.MoveNorth(); 175 | } 176 | 177 | private void btnEast_Click(object sender, EventArgs e) 178 | { 179 | _player.MoveEast(); 180 | } 181 | 182 | private void btnSouth_Click(object sender, EventArgs e) 183 | { 184 | _player.MoveSouth(); 185 | } 186 | 187 | private void btnWest_Click(object sender, EventArgs e) 188 | { 189 | _player.MoveWest(); 190 | } 191 | 192 | private void btnUseWeapon_Click(object sender, EventArgs e) 193 | { 194 | // Get the currently selected weapon from the cboWeapons ComboBox 195 | Weapon currentWeapon = (Weapon)cboWeapons.SelectedItem; 196 | 197 | _player.UseWeapon(currentWeapon); 198 | } 199 | 200 | private void btnUsePotion_Click(object sender, EventArgs e) 201 | { 202 | // Get the currently selected potion from the combobox 203 | HealingPotion potion = (HealingPotion)cboPotions.SelectedItem; 204 | 205 | _player.UsePotion(potion); 206 | } 207 | 208 | private void SuperAdventure_FormClosing(object sender, FormClosingEventArgs e) 209 | { 210 | File.WriteAllText(PLAYER_DATA_FILE_NAME, _player.ToXmlString()); 211 | } 212 | 213 | private void cboWeapons_SelectedIndexChanged(object sender, EventArgs e) 214 | { 215 | _player.CurrentWeapon = (Weapon)cboWeapons.SelectedItem; 216 | } 217 | } 218 | } -------------------------------------------------------------------------------- /SuperAdventure/SuperAdventure/SuperAdventure.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {FE7A0834-305D-4416-9E95-A8D986E9B881} 8 | WinExe 9 | Properties 10 | SuperAdventure 11 | SuperAdventure 12 | v4.5.2 13 | 512 14 | true 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | Form 51 | 52 | 53 | SuperAdventure.cs 54 | 55 | 56 | 57 | 58 | Form 59 | 60 | 61 | TradingScreen.cs 62 | 63 | 64 | ResXFileCodeGenerator 65 | Resources.Designer.cs 66 | Designer 67 | 68 | 69 | True 70 | Resources.resx 71 | 72 | 73 | SuperAdventure.cs 74 | 75 | 76 | TradingScreen.cs 77 | 78 | 79 | SettingsSingleFileGenerator 80 | Settings.Designer.cs 81 | 82 | 83 | True 84 | Settings.settings 85 | True 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | {4166ef61-d200-4a0d-9b05-afee45c2c8b7} 94 | Engine 95 | 96 | 97 | 98 | 105 | -------------------------------------------------------------------------------- /SuperAdventure/SuperAdventure/SuperAdventure.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 | -------------------------------------------------------------------------------- /SuperAdventure/SuperAdventure/TradingScreen.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace SuperAdventure 2 | { 3 | partial class TradingScreen 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 | this.lblMyInventory = new System.Windows.Forms.Label(); 32 | this.lblVendorInventory = new System.Windows.Forms.Label(); 33 | this.dgvMyItems = new System.Windows.Forms.DataGridView(); 34 | this.dgvVendorItems = new System.Windows.Forms.DataGridView(); 35 | this.btnClose = new System.Windows.Forms.Button(); 36 | ((System.ComponentModel.ISupportInitialize)(this.dgvMyItems)).BeginInit(); 37 | ((System.ComponentModel.ISupportInitialize)(this.dgvVendorItems)).BeginInit(); 38 | this.SuspendLayout(); 39 | // 40 | // lblMyInventory 41 | // 42 | this.lblMyInventory.AutoSize = true; 43 | this.lblMyInventory.Location = new System.Drawing.Point(99, 13); 44 | this.lblMyInventory.Name = "lblMyInventory"; 45 | this.lblMyInventory.Size = new System.Drawing.Size(68, 13); 46 | this.lblMyInventory.TabIndex = 0; 47 | this.lblMyInventory.Text = "My Inventory"; 48 | // 49 | // lblVendorInventory 50 | // 51 | this.lblVendorInventory.AutoSize = true; 52 | this.lblVendorInventory.Location = new System.Drawing.Point(349, 13); 53 | this.lblVendorInventory.Name = "lblVendorInventory"; 54 | this.lblVendorInventory.Size = new System.Drawing.Size(95, 13); 55 | this.lblVendorInventory.TabIndex = 1; 56 | this.lblVendorInventory.Text = "Vendor\'s Inventory"; 57 | // 58 | // dgvMyItems 59 | // 60 | this.dgvMyItems.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; 61 | this.dgvMyItems.Location = new System.Drawing.Point(13, 43); 62 | this.dgvMyItems.Name = "dgvMyItems"; 63 | this.dgvMyItems.Size = new System.Drawing.Size(240, 216); 64 | this.dgvMyItems.TabIndex = 2; 65 | // 66 | // dgvVendorItems 67 | // 68 | this.dgvVendorItems.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; 69 | this.dgvVendorItems.Location = new System.Drawing.Point(276, 43); 70 | this.dgvVendorItems.Name = "dgvVendorItems"; 71 | this.dgvVendorItems.Size = new System.Drawing.Size(240, 216); 72 | this.dgvVendorItems.TabIndex = 3; 73 | // 74 | // btnClose 75 | // 76 | this.btnClose.Location = new System.Drawing.Point(441, 274); 77 | this.btnClose.Name = "btnClose"; 78 | this.btnClose.Size = new System.Drawing.Size(75, 23); 79 | this.btnClose.TabIndex = 4; 80 | this.btnClose.Text = "Close"; 81 | this.btnClose.UseVisualStyleBackColor = true; 82 | this.btnClose.Click += new System.EventHandler(this.btnClose_Click); 83 | // 84 | // TradingScreen 85 | // 86 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 87 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 88 | this.ClientSize = new System.Drawing.Size(528, 310); 89 | this.Controls.Add(this.btnClose); 90 | this.Controls.Add(this.dgvVendorItems); 91 | this.Controls.Add(this.dgvMyItems); 92 | this.Controls.Add(this.lblVendorInventory); 93 | this.Controls.Add(this.lblMyInventory); 94 | this.Name = "TradingScreen"; 95 | this.Text = "Trader"; 96 | ((System.ComponentModel.ISupportInitialize)(this.dgvMyItems)).EndInit(); 97 | ((System.ComponentModel.ISupportInitialize)(this.dgvVendorItems)).EndInit(); 98 | this.ResumeLayout(false); 99 | this.PerformLayout(); 100 | 101 | } 102 | 103 | #endregion 104 | 105 | private System.Windows.Forms.Label lblMyInventory; 106 | private System.Windows.Forms.Label lblVendorInventory; 107 | private System.Windows.Forms.DataGridView dgvMyItems; 108 | private System.Windows.Forms.DataGridView dgvVendorItems; 109 | private System.Windows.Forms.Button btnClose; 110 | } 111 | } -------------------------------------------------------------------------------- /SuperAdventure/SuperAdventure/TradingScreen.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 Engine; 11 | 12 | namespace SuperAdventure 13 | { 14 | public partial class TradingScreen : Form 15 | { 16 | public Player CurrentPlayer { get; set; } 17 | 18 | private Player _currentPlayer; 19 | 20 | public TradingScreen(Player player) 21 | { 22 | _currentPlayer = player; 23 | 24 | InitializeComponent(); 25 | 26 | // Style, to display numeric column values 27 | DataGridViewCellStyle rightAlignedCellStyle = new DataGridViewCellStyle(); 28 | rightAlignedCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight; 29 | 30 | // Populate the datagrid for the player's inventory 31 | dgvMyItems.RowHeadersVisible = false; 32 | dgvMyItems.AutoGenerateColumns = false; 33 | 34 | // This hidden column holds the item ID, so we know which item to sell 35 | dgvMyItems.Columns.Add(new DataGridViewTextBoxColumn 36 | { 37 | DataPropertyName = "ItemID", 38 | Visible = false 39 | }); 40 | 41 | dgvMyItems.Columns.Add(new DataGridViewTextBoxColumn 42 | { 43 | HeaderText = "Name", 44 | Width = 100, 45 | DataPropertyName = "Description" 46 | }); 47 | 48 | dgvMyItems.Columns.Add(new DataGridViewTextBoxColumn 49 | { 50 | HeaderText = "Qty", 51 | Width = 30, 52 | DefaultCellStyle = rightAlignedCellStyle, 53 | DataPropertyName = "Quantity" 54 | }); 55 | 56 | dgvMyItems.Columns.Add(new DataGridViewTextBoxColumn 57 | { 58 | HeaderText = "Price", 59 | Width = 35, 60 | DefaultCellStyle = rightAlignedCellStyle, 61 | DataPropertyName = "Price" 62 | }); 63 | 64 | dgvMyItems.Columns.Add(new DataGridViewButtonColumn 65 | { 66 | Text = "Sell 1", 67 | UseColumnTextForButtonValue = true, 68 | Width = 50, 69 | DataPropertyName = "ItemID" 70 | }); 71 | // Bind the player's inventory to the datagridview 72 | dgvMyItems.DataSource = _currentPlayer.Inventory; 73 | 74 | // When the user clicks on a row, call this function 75 | dgvMyItems.CellClick += dgvMyItems_CellClick; 76 | 77 | 78 | // Populate the datagrid for the vendor's inventory 79 | dgvVendorItems.RowHeadersVisible = false; 80 | dgvVendorItems.AutoGenerateColumns = false; 81 | 82 | // This hidden column holds the item ID, so we know which item to sell 83 | dgvVendorItems.Columns.Add(new DataGridViewTextBoxColumn 84 | { 85 | DataPropertyName = "ItemID", 86 | Visible = false 87 | }); 88 | 89 | dgvVendorItems.Columns.Add(new DataGridViewTextBoxColumn 90 | { 91 | HeaderText = "Name", 92 | Width = 100, 93 | DataPropertyName = "Description" 94 | }); 95 | 96 | dgvVendorItems.Columns.Add(new DataGridViewTextBoxColumn 97 | { 98 | HeaderText = "Price", 99 | Width = 35, 100 | DefaultCellStyle = rightAlignedCellStyle, 101 | DataPropertyName = "Price" 102 | }); 103 | 104 | dgvVendorItems.Columns.Add(new DataGridViewButtonColumn 105 | { 106 | Text = "Buy 1", 107 | UseColumnTextForButtonValue = true, 108 | Width = 50, 109 | DataPropertyName = "ItemID" 110 | }); 111 | 112 | // Bind the vendor's inventory to the datagridview 113 | dgvVendorItems.DataSource = _currentPlayer.CurrentLocation.VendorWorkingHere.Inventory; 114 | 115 | // When the user clicks on a row, call this function 116 | dgvVendorItems.CellClick += dgvVendorItems_CellClick; 117 | } 118 | 119 | private void dgvMyItems_CellClick(object sender, DataGridViewCellEventArgs e) 120 | { 121 | // The first column of a datagridview has a ColumnIndex = 0 122 | // This is known as a "zero-based" array/collection/list. 123 | // You start counting with 0. 124 | // 125 | // The 5th column (ColumnIndex = 4) is the column with the button. 126 | // So, if the player clicked the button column, we will sell an item from that row. 127 | if (e.ColumnIndex == 4) 128 | { 129 | // This gets the ID value of the item, from the hidden 1st column 130 | // Remember, ColumnIndex = 0, for the first column 131 | var itemID = dgvMyItems.Rows[e.RowIndex].Cells[0].Value; 132 | 133 | // Get the Item object for the selected item row 134 | Item itemBeingSold = World.ItemByID(Convert.ToInt32(itemID)); 135 | 136 | if (itemBeingSold.Price == World.UNSELLABLE_ITEM_PRICE) 137 | { 138 | MessageBox.Show("You cannot sell the " + itemBeingSold.Name); 139 | } 140 | else 141 | { 142 | // Remove one of these items from the player's inventory 143 | _currentPlayer.RemoveItemFromInventory(itemBeingSold); 144 | 145 | // Give the player the gold for the item being sold. 146 | _currentPlayer.Gold += itemBeingSold.Price; 147 | } 148 | } 149 | } 150 | 151 | private void dgvVendorItems_CellClick(object sender, DataGridViewCellEventArgs e) 152 | { 153 | // The 4th column (ColumnIndex = 3) has the "Buy 1" button. 154 | if (e.ColumnIndex == 3) 155 | { 156 | // This gets the ID value of the item, from the hidden 1st column 157 | var itemID = dgvVendorItems.Rows[e.RowIndex].Cells[0].Value; 158 | 159 | // Get the Item object for the selected item row 160 | Item itemBeingBought = World.ItemByID(Convert.ToInt32(itemID)); 161 | 162 | // Check if the player has enough gold to buy the item 163 | if (_currentPlayer.Gold >= itemBeingBought.Price) 164 | { 165 | // Add one of the items to the player's inventory 166 | _currentPlayer.AddItemToInventory(itemBeingBought); 167 | 168 | // Remove the gold to pay for the item 169 | _currentPlayer.Gold -= itemBeingBought.Price; 170 | } 171 | else 172 | { 173 | MessageBox.Show("You do not have enough gold to buy the " + itemBeingBought.Name); 174 | } 175 | } 176 | } 177 | 178 | private void btnClose_Click(object sender, EventArgs e) 179 | { 180 | Close(); 181 | } 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /SuperAdventure/SuperAdventure/TradingScreen.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 | --------------------------------------------------------------------------------