This time, we're going to try to get combat working. It'll be fairly awful combat for now, but we're focusing on getting to a starting point.
Almost all of this will be in Program.cs with the classes we've already created.
First we need to make sure a player character exists:
Everything else belongs in the loop, though we'll have to make minor changes to the Dungeon class as well. Let's do that quickly.
We'll need a random number generator. The next change needs another small change to something else, the Monster class:
Back to the Dungeon class, we need to change the Encounter method to return a Monster instead of a string.
First, we get a random monster in much the same way that we did in the previous version of this method, but we just save it to a variable. Next, assuming we find a monster and the current room exists, we do a few things I'll go into in a moment, but first you should go ahead and add the return null that will be reached if the current room or generated monster is null. Back to the contents of the if, we're going to generate a number between 1 and the monster level of the current room and save this as the level of the monster we're making. Then we return... something you have not seen previously: This with syntax makes a copy of a record with the changes you indicate. We're making the generated monster generate at a higher level, with higher stats and life based on its level. This will have broken our code back in Program, but that's exactly what we're going to go rewrite next! (Also, in case it was never previously explained, != means "is not equal to")
We now just save off the monster we encounter into a variable, and if we did encounter one (meaning it is not null) we display that monster's name.
There is a huge amount more code here, but all of it is stuff we've done before, up until we reach line 105's break statement. This exits the current loop, meaning our program's main loop is stopped and the program ends. Starting the game again will require running the game again. You can do something about this, but I'll leave that to you. Several parts here could be made into methods to simplify reading the basic logic of the program but again, you should be the one to try to feel your way around that. You'll also notice that this combat system is awful. You will probably lose to the first enemy, and can't really do anything about that. You certainly won't survive the four battles required to level up. You might consider raising the starting stats of your character right after you make the "character" variable to the point where you can succeed, but you likely will become unable to fail. Thinking about how to improve that is another thing you ought to do.
Now we'll move on to saving your game. For now, we'll save at the end of every loop.
We add a call to Save, and the stub of the Save and Load methods we'll be defining soon.
Back up near the top, we'll sort out our save file location and name. We'll put the save file in a folder named after our project, inside of the My Documents, My Games folder. We're going to use this for the Save and the Load, so we need to create them very early.
We'll call the Load method here, and pass in our file path.
We change the save and load to take the path as a parameter. The Load method works basically the way our previous XML methods worked. We're calling a FromXml method that doesn't exist yet, but we'll work on that soon. The Save method, on the other hand, is a good example of how you build an XDocument: An XElement has a name and some number of values; we pass in a Position element and the result of calling ToXml on the PlayerCharacter class.
Speaking of which:
The ToXml method was simple! We just make an element for each property, and save their values directly.
Once again, nothing you haven't used before. Let's look over Program.cs once more to see if we've missed anything.
Right, we forgot that our FromXml method does not take nullable values. We could allow it to, but I think we should stop the problem here.
Now for the moment of truth: everything looks perfect, we have no errors hilighted, so we try running it. Immediately we encounter a monster, so we initiate an attack and... it looks like our life isn't going down? Okay, so we know we have a bug in the combat in Program.cs, but let's see if the fight ever ends: attack over and over. Looks like the fight does end, but now we've thrown an exception... It looks like it can't find the folder we're trying to save in. Two bugs even though the code looked so correct! Let's go fix them, one by one. First, combat:
It's possible you noticed this before. It was a simple fix, we just forgot to actually apply the taken damage.
The Directory class has a variety of tools for dealing with folders, so we check if it exists, and if not we create it. Now does it work?
It does! The final part of this tutorial will briefly introduce a bunch of features that you can look into later, and important things to read about. What you have now, though, is enough to make a game!