Lesson Objectives
At the end of this lesson, you will know…
- Nothing new. We’re just finishing the program, using the same things you learned in the previous lessons.
Now we’ll write the functions the player will use when fighting monsters.
We have two things they can do (besides click on one of the direction buttons, to run away from the battle): use a weapon on the monster or use a healing potion on themselves – if they have one in their inventory.
Here is the pseudo-code for the two functions:
Use a weapon function
- Get the currently selected weapon from the cboWeapons ComboBox
- Determine the amount of damage the player does to the monster
- Apply the damage to the monster’s CurrentHitPoints
- Display message
- If the monster is dead (zero hit points remaining)
- Display a victory message
- Give player experience points for killing the monster
- Display message
- Give player gold for killing the monster
- Display message
- Get loot items from the monster
- Display message for each loot item
- Add item to player’s inventory
- Refresh player data on UI
- Gold and ExperiencePoints
- Inventory list and ComboBoxes
- “Move” player to current location
- This will heal the player and create a new monster
- If the monster is still alive
- Determine the amount of damage the monster does to the player
- Display message
- Subtract damage from player’s CurrentHitPoints
- Refresh player data in UI
- If player is dead (zero hit points remaining)
- Display message
- Move player to “Home” location
Use a potion function
- Get currently selected potion from cboPotions ComboBox
- Add healing amount to player’s CurrentHitPoints
- CurrentHitPoints cannot exceed player’s MaximumHitPoints
- Remove the potion from the player’s inventory
- Display message
- Monster gets their turn to attack
- Determine the amount of damage the monster does to the player
- Display message
- Subtract damage from player’s CurrentHitPoints
- Refresh player data in UI
- If player is dead (zero hit points remaining)
- Display message
- Move player to “Home” location
- Refresh player data in UI
These are much simpler functions than the MoveTo() function.
We’ll be able to use some of the smaller functions we created during the refactoring lesson – for example, the AddItemToInventory() function, from the Player class, if the player defeats the monster and receives loot items.
Adding functions for monster battles
Step 1: Start Visual Studio Express 2013 for Desktop, and open the solution.
Step 2: Right-click on the SuperAdventure.cs form in the SuperAdventure project, to start working with the code for the UI.
To add the ability to use weapons and potions in combat, you can add in the code below, or replace the code for SuperAdventure.cs with the code here: https://gist.github.com/ScottLilly/b20787650f2ab2a78362
For the btnUseWeapon_Click function, add this:
private void btnUseWeapon_Click(object sender, EventArgs e)
{
// Get the currently selected weapon from the cboWeapons ComboBox
Weapon currentWeapon = (Weapon)cboWeapons.SelectedItem;
// Determine the amount of damage to do to the monster
int damageToMonster = RandomNumberGenerator.NumberBetween(currentWeapon.MinimumDamage, currentWeapon.MaximumDamage);
// Apply the damage to the monster's CurrentHitPoints
_currentMonster.CurrentHitPoints -= damageToMonster;
// Display message
rtbMessages.Text += "You hit the " + _currentMonster.Name + " for " + damageToMonster.ToString() + " points." + Environment.NewLine;
// Check if the monster is dead
if(_currentMonster.CurrentHitPoints <= 0)
{
// Monster is dead
rtbMessages.Text += Environment.NewLine;
rtbMessages.Text += "You defeated the " + _currentMonster.Name + Environment.NewLine;
// Give player experience points for killing the monster
_player.ExperiencePoints += _currentMonster.RewardExperiencePoints;
rtbMessages.Text += "You receive " + _currentMonster.RewardExperiencePoints.ToString() + " experience points" + Environment.NewLine;
// Give player gold for killing the monster
_player.Gold += _currentMonster.RewardGold;
rtbMessages.Text += "You receive " + _currentMonster.RewardGold.ToString() + " gold" + Environment.NewLine;
// Get random loot items from the monster
List<InventoryItem> lootedItems = new List<InventoryItem>();
// Add items to the lootedItems list, comparing a random number to the drop percentage
foreach(LootItem lootItem in _currentMonster.LootTable)
{
if(RandomNumberGenerator.NumberBetween(1, 100) <= lootItem.DropPercentage)
{
lootedItems.Add(new InventoryItem(lootItem.Details, 1));
}
}
// If no items were randomly selected, then add the default loot item(s).
if(lootedItems.Count == 0)
{
foreach(LootItem lootItem in _currentMonster.LootTable)
{
if(lootItem.IsDefaultItem)
{
lootedItems.Add(new InventoryItem(lootItem.Details, 1));
}
}
}
// Add the looted items to the player's inventory
foreach(InventoryItem inventoryItem in lootedItems)
{
_player.AddItemToInventory(inventoryItem.Details);
if(inventoryItem.Quantity == 1)
{
rtbMessages.Text += "You loot " + inventoryItem.Quantity.ToString() + " " + inventoryItem.Details.Name +Environment.NewLine;
}
else
{
rtbMessages.Text += "You loot " + inventoryItem.Quantity.ToString() + " " + inventoryItem.Details.NamePlural + Environment.NewLine;
}
}
// Refresh player information and inventory controls
lblHitPoints.Text = _player.CurrentHitPoints.ToString();
lblGold.Text = _player.Gold.ToString();
lblExperience.Text = _player.ExperiencePoints.ToString();
lblLevel.Text = _player.Level.ToString();
UpdateInventoryListInUI();
UpdateWeaponListInUI();
UpdatePotionListInUI();
// Add a blank line to the messages box, just for appearance.
rtbMessages.Text += Environment.NewLine;
// Move player to current location (to heal player and create a new monster to fight)
MoveTo(_player.CurrentLocation);
}
else
{
// Monster is still alive
// Determine the amount of damage the monster does to the player
int damageToPlayer = RandomNumberGenerator.NumberBetween(0, _currentMonster.MaximumDamage);
// Display message
rtbMessages.Text += "The " + _currentMonster.Name + " did " + damageToPlayer.ToString() + " points of damage." + Environment.NewLine;
// Subtract damage from player
_player.CurrentHitPoints -= damageToPlayer;
// Refresh player data in UI
lblHitPoints.Text = _player.CurrentHitPoints.ToString();
if(_player.CurrentHitPoints <= 0)
{
// Display message
rtbMessages.Text += "The " + _currentMonster.Name + " killed you." + Environment.NewLine;
// Move player to "Home"
MoveTo(World.LocationByID(World.LOCATION_ID_HOME));
}
}
}
Then, for the btnUsePotion_Click function, add this:
private void btnUsePotion_Click(object sender, EventArgs e)
{
// Get the currently selected potion from the combobox
HealingPotion potion = (HealingPotion)cboPotions.SelectedItem;
// Add healing amount to the player's current hit points
_player.CurrentHitPoints = (_player.CurrentHitPoints + potion.AmountToHeal);
// CurrentHitPoints cannot exceed player's MaximumHitPoints
if(_player.CurrentHitPoints > _player.MaximumHitPoints)
{
_player.CurrentHitPoints = _player.MaximumHitPoints;
}
// Remove the potion from the player's inventory
foreach(InventoryItem ii in _player.Inventory)
{
if(ii.Details.ID == potion.ID)
{
ii.Quantity--;
break;
}
}
// Display message
rtbMessages.Text += "You drink a " + potion.Name + Environment.NewLine;
// Monster gets their turn to attack
// Determine the amount of damage the monster does to the player
int damageToPlayer = RandomNumberGenerator.NumberBetween(0, _currentMonster.MaximumDamage);
// Display message
rtbMessages.Text += "The " + _currentMonster.Name + " did " + damageToPlayer.ToString() + " points of damage." + Environment.NewLine;
// Subtract damage from player
_player.CurrentHitPoints -= damageToPlayer;
if(_player.CurrentHitPoints <= 0)
{
// Display message
rtbMessages.Text += "The " + _currentMonster.Name + " killed you." + Environment.NewLine;
// Move player to "Home"
MoveTo(World.LocationByID(World.LOCATION_ID_HOME));
}
// Refresh player data in UI
lblHitPoints.Text = _player.CurrentHitPoints.ToString();
UpdateInventoryListInUI();
UpdatePotionListInUI();
}
There isn’t really anything new in these two functions. Just more “if”s and “foreach”s to handle the player’s actions in battle.
Summary
Now you have a working game. The player can move around in the world, get quests, battle monsters, receive loot, and complete quests.
These new functions could use some refactoring, since they are long and do several things. I’ll leave that to you to figure out what refactoring you’d do.
Source code for this lesson
Next lesson: Lesson 17.1 – Running the game on another computer
Previous lesson: Lesson 16.2 – Refactoring the player movement function
All lessons: Learn C# by Building a Simple RPG Index
So, while I think everything was copied right (I even went through the whole tutorial again to try and figure this out) at the end of this lesson, I am able to build into the form application, and everything works out correctly, except for the fact that I cannot move from the starting area. I believe that it might be an issue with how btnNorth (at least that’s the one that isn’t working at this point) interacts with the rest of the program. Help would be greatly appreciated and you’d be helping a young engineer get a head-start in college!
Thank you for the tutorials! They’re absolutely phenomenal and I hope that you might release higher level tutorials some time in the future.
Hi Chris,
It does sound like your “North” button may not be connected to the rest of the code. When you added the button to the screen, did you double-click on it, to create the “btnNorth_Click” function, or did you only create that function by pasting in the source code to the SuperAdventure.cs class? If you did not double-click the North button, then there would not be an “event handler” for it, to tell the program what function to run when the button is clicked. The simplest way to fix that would be to delete the functions that handle the buttons clicks, go to the Design page for SuperAdventure.cs (double-click on the SuperAdventure.cs file in the Solution Explorer, then double-click on each of the buttons. That will create the empty functions in the code to handle the click events. Then you’ll need to paste the code for the function into the empty functions.
If that isn’t the problem, I wrote a post the other day on how to use the debugger (How to Use the Visual Studio 2013 Debugger). If you read that, and set a breakpoint on the btn_North function, you’ll be able to see if the function is called when the player clicks on the button. You’ll also be able to use the F10 key to follow through the rest of the program as it is running. That may help you discover the source of the problem.
Awesome! Seems to be working now, it generated a new method stub for all of the buttons under btn(fill in the space here)_Click_1. This would probably be a common problem for those debugging problems by rebuilding the whole solution via copy and paste. Thanks!
Cool. I’m glad to hear you got it working.
Got one question.
I added the Club as a drop for spiders and when i loot it, and choose to use it, it changes back to rusty sword, when i change location, and seems it tries to switch over to sword when attacking :/
This happens because when the player moves to a new location, the MoveTo() function (in SuperAdventure.cs) calls the UpdateWeaponListInUI() function, which repopulates the dropdown. Since we don’t store the player’s currently selected weapon, the dropdown selects the first option.
I’ll work on a new lesson this weekend to show how to have the dropdown show the player’s current weapon. We’ll add a CurrentWeapon property to the Player class, and an “event handler” for when the player selects a new weapon in the dropdown. In the event handler code, we’ll save the new weapon to the player’s CurrentWeapon property. Then, in the UpdateWeaponListInUI() function, we’ll see what the player’s CurrentWeapon is and display it in the dropdown.
Awesome.
I did manage to get it to work with good help from a friend of mine.
But it seems to try and switch every time i use a weapon.
Ill show how i did it when i get to my pc again.
Cheers for the reply, and cant wait for the new lesson. 🙂
The lesson is here: Lesson 19.5 – Changing dropdown default values
Please let me know if you have any questions, or any problems with it.
Hi Scott,
This has been a brilliant learning tool. I cannot find anywhere in the code where we give the play a starting weapon. I’ve lifted ‘player.Inventory.Add(new InventoryItem(World.ItemByID(World.ITEM_ID_RUSTY_SWORD), 1));’ from Lesson 19 and have looked for something similar but haven’t been able to find anything. I’ve not yet been able to work out how to reword this to add it to the inventory.
Thanks Peter,
I’m sorry it’s taken me so long to respond. I’m getting ready to move back to the US, and it’s been crazy-busy lately.
If you look at Lesson 19.4 https://www.scottlilly.com/learn-c-by-building-a-simple-rpg-index/lesson-19-4-saving-and-%20%20loading-the-player-information/, you’ll see some new constructors for the Player class. They handle recreating the player from a saved game (or from nothing, for the first time playing the game). In that case, the item is only added for a new game (in the CreateDefaultPlayer() method), since the player’s default weapon would be re-added from the saved game (in the CreatePlayerFromXmlString() method).
Actually nevermind, I just dumped ‘_player.Inventory.Add(new InventoryItem(World.ItemByID(World.ITEM_ID_RUSTY_SWORD), 1));’ in the Player initialization.
I’m going to go read everything else you’ve written now!
Hi,
Not sure if you still check this but I seem to be having a problem with hitting the enemy, the value always seems to be 0 yet the monster can hit me.
Any ideas on what the problem could be?
Thanks in advance,
Graeme
Never mind I fixed it, I had:
int MinimumDamage = minimumDamage;
int MaximumDamage = maximumDamage;
in the Weapon class instead of just:
MinimumDamage = minimumDamage;
MaximumDamage = maximumDamage;
Duh!
Thanks for the great guide though, helped me a lot! 🙂
Cool. I’m sorry I wasn’t able to respond, I’m currently packing up and getting ready to move a few thousands miles. 🙂 If you have any other questions, I’m probably going to be completely offline for the next week (more or less).
Hi im really enjoyn the tuto so far. but i have a question i hope you can attend.
when you create an object and in some other place i cant remember you use:
Classname objectName = (Classname).andsomemorestuff
i dont understand when to use this (i mean the class name in parenthesis when you create an object)
thanks, looking forward to end the game!
Thank you Pablo.
I think you’re asking about “casting” a variable. also called “type conversion”. This is for when you want to treat a variable that is one datatype like a different datatype, or convert between datatypes. You can read more about this at https://msdn.microsoft.com/en-us/library/ms173105.aspx. You may also want to look at the Convert class here: https://msdn.microsoft.com/en-us/library/system.convert%28v=vs.110%29.aspx
hi, i realy like your helpful Tutorial and i already learned alot but i cant seem to find the solution to the problem im having since lesson 16.1. Visual Studio is saying that there are no errors in the game but when run it it just shows a blank Form in (i think) standard size :(.
i fixed it by making a new programm and copy pasting my stuff in it, maybe i deleted something by accident?
The values for the UI controls (labels, buttons, datagrids, etc.) are located in the SuperAdventure.Designer.cs file. If you moved/renamed/copied/etc. SuperAdventure.cs, and didn’t also get the Designer.cs file, that might have caused the problem.
How do you fix, that. Do you have to move everything to a new programm?
Usually, when you do refactoring, you do not move everything to a new program. Instead, you make small changes to your current program.
When you get to lesson 20, you’ll see how I make more small changes to the program, making one feature better each time.
I mean how do you fix it when the UI does have anything on it nothing works it has all the buttons and other items but otherwise its blank
If the buttons are in the UI, and the code for the buttons does not work, there is probably a problem in the Designer.cs file for that UI form. That is the file where the buttons connect to the functions.
Do you have a place where you can upload your solution? Then I can look at the exact problem and tell you how to make it work? If you do not have a place, you can create a free account on Dropbox to upload your files. Please upload all the files (including the sub-folders under your solutions folder), share the folder, and send me the “share” link.
Hey Scott,
Thanks so much for the tutorial. I’m totally new to programming and C# and this has been a huge help as I begin the learning process.
I am having one problem though. I cannot seem to get the use weapon button to do anything. I have checked the code for it, it’s exactly as you have it written, and logically it seems like it should work. But it doesn’t do anything. Do you have any idea why this could be?
You’re welcome, Nick.
If the btnUseWeapon_Click() function is in SuperAdventure.cs, the most likely problem is that the line connecting the button’s “Click” event to the method has been deleted. Try doing this:
1. Open the SuperAdventure.cs form, in design mode, in Visual Studio.
2. Click once on the “Use” button for the weapon, to set focus on it.
3. In the Lower-right corner of Visual Studio, in the “Properties” box, click on the lightning bolt symbol (see the image below).
4. See if the “Click” event has the value “btnUseWeapon_Click” (the name of the function to run when the user clicks on that button). If that value is missing, follow the next steps. If the value is there, let me know and we’ll try to figure out what else might be causing the problem.
5. If the “btnUseWeapon_Click” was missing, double-click on the “SuperAdventure.Designer.cs” file (in the Solution Explorer), to edit it.
6. Scroll down until you see the section for “btnUseWeapon”. Add in this line of code:
this.btnUseWeapon.Click += new System.EventHandler(this.btnUseWeapon_Click);7. Save everything, run the game, and see if the button works now.
Please let me know if that doesn’t fix it, and we’ll dig deeper.
I know this is from a while ago, but I was having issues where the North button was disabled, not clickable, and grayed out.
Through messing around I found that my Form was not enabled. I changed the value to True, and everything works like a charm.
I don’t remember changing that value, but this might be a good first place to look for everyone else.
Great tutorial so far! Thanks!
Thanks for sharing the tip, in case someone else is having the same problem.
Hey there, awesome tutorial
i seem to have the same problem that Graeme with the damage that the player deals to the enemy but my weapon class is same as the one you have, as well as all the other classes.
Thanks. Can you upload your solution (and all the files/directories under it) to some place like Dropbox? Then I should be able to find out exactly where the problem is.
Or, if you want to look for the problem yourself, you can see how to do some debugging (for a different problem, but the same concept) in this video on C# debugging in Visual Studio.
Hey I ran into another problem I tried starting the game after all of this lesson and its saying that its “stopped at exception” there no other errors or anything and I don’t know what to do.
If you click on “Build”, instead of the green arrow to run the program, do you see any errors in the bottom section of Visual Studio?
I didn’t get any errors when I tried that.
Can you upload your whole solution (including the files/folder underneath it) to Dropbox, or some other sharing site, and send me the link? Then I can look at it.
Thanks so much for these tutorials, I’ve learnt so much from them. At the moment, when we kill a monster we just re-enter the location, heal and spawn a new monster to fight. How could we do it that we still heal, but the monster doesn’t come back? It would be really cool if we could make it that, for example, there were 3 rats in one room, each with the ability to attack the player, and would only respawn when the player purposely re-enters. Perhaps the player could choose which enemy to attack if there is more than one enemy, for example if the room contains a snake and a giant spider. Sorry for the newbie question, would this be difficult to do?
You’re welcome! To leave the player at the same location, you could modify the UseWeapon function that attacks the monster. Find these lines:
// Move player to current location (to heal player and create a new monster to fight)MoveTo(CurrentLocation);
and replace them with this:
// Completely heal the player_player.CurrentHitPoints = _player.MaximumHitPoints;
You may also need to modify the code that makes the “Use” weapon button visible – since you will still have a monster at that location, but it will be dead.
You could add multiple monsters at a location, but there are several changes you would need to make: datatype (so you could add multiple monsters at a location)
1. Change the Location MonsterLivingHere property from a Monster datatype to a List
2. Change the World class, where you set MonsterLivingHere to work with the List version (probably using the “Add” function on the list property)
3. Add a new combobox near the “Use” weapon button, to display which monster he player will attack. You will need to some extra work here to populate this with the monsters at the location, and remove them from the combobox when one is killed.
4. Change the code in the “Use” weapon function to allow each monster to attack the player.
It can be done, but there are many steps to make that change. If you do try it, I suggest you use version control, like Subversion (I have a post here on how to install and use Subversion). Make small changes, one step at a time. After each change, test the program, to ensure it is still working. If it is, check the code into Subversion. This way, if your change breaks something, you can revert the code to how it was before the change.
That’s brilliant, thank you so much. I’ve tried the first thing and that works, I think I’ll do your other tutorials first before attempting to add multiple monsters. I’ll look forward to trying this when I get there and I’ll let you know how it goes.
I’d also really like to add images to each monster. Could I do it like this:
1) in the Monster.cs class add:
public string Image { get; set; }
public Monster(int id, string name, int maximumDamage, int rewardExperiencePoints, int rewardGold, int currentHitPoints, int maximumHitPoints, string image)
: base(currentHitPoints, maximumHitPoints)
{
…
Image = image;
…
}
2) add the file location in the World.cs section of the Monsters:
e.g.
Monster giantSpider = new Monster(MONSTER_ID_GIANT_SPIDER, “Giant spider”, 20, 5, 40, 10, 10, c:\\My Documents\SuperAdventure-master\Images\Spider.jpg);
3) Add pictureBox1 in the [Design] section and then
pictureBox1.Image = Image.FromFile(_currentMonster);
(At the moment this shows a lot of red, maybe there’s something wrong with that?)
A problem I see with this is that when I change computer etc. the images will need to be in the same place. How can you have it that they are automatically found within the folder?
Thanks once more for your tutorials, they really are great. It makes it so much easier to get started with programming, learning by doing and working with code that you know will work. (A lot of things online that I found previously don’t seem to work). I hope you don’t mind me running this idea past you, I wanted to check the syntax and logic of it before spending a lot of time on it.(Two months ago I didn’t know the first thing about programming!) Thanks a bunch :-).
Cool! I did not test out the first change on my computer, so you might find other small changes you will need to make. But that should get you close.
I am about to go to an all-day class, so I will point you to this page (Embedding Image Resources in a Project) to see how to include an image in your project – even if you run it on another computer. “Embedding a resource” means that Visual Studio will include that file with your program, when you run “build”.
Great thanks! I hope your day class went well. I couldn’t get the embedding thing working, in the end I managed to include images without embedding by:
string temp = Environment.CurrentDirectory;
PictureBox1.Image = Image.FromFile(temp + _currentMonster.ImageFile);
All monsters, locations and player levels now have associated images, which update automatically. Thanks for your help with this 🙂
I’d like to make it that the game shows a MessageBox when all Quests are completed.
How could I do that? (I know how to show a MessageBox, I’m just not sure how to access an “if all quests are completed function”)
(Also in my version my Quest list only updates when I return to the Location that the Quest is stored in. Do you know why?)
Thank you so much!
You’re welcome. My answer to your other question shows where the quest completion logic is located (and why the player must return to the original quest location). You could add some more code there, to see if all the quests are completed. If they are, then show the MessageBox.
If you have questions after looking at that, please let me know.
I’ve created a place that can only be entered if all quests have been completed, that can not be left. Upon entry the MessageBox will appear saying that the game has been completed.
I’m still not sure why Quest completed true only gets activated when I re-enter the place where that the quest was given though…
The way I designed the game, all the quests are given to the player by someone at a location. They want the player to get them some items, and return the items to them. So, the player must return to the original quest location, in order to “turn in the quest” and complete it.
Look at the MoveTo function, for this comment:
// See if the player already has the quest, and if they've completed itThat is where we start to check if there is a quest at that location that can be completed. If so, we check if the player has all the items. If they do, we complete the quest.
You could move that logic to the function where the player uses their weapon against a monster. When they defeat the monster, and collect the monster’s loot, we could check if the player has everything needed to complete any of their quests. The code where the player collects the loot starts after this comment:
// Add the looted items to the player's inventoryGreat! Thanks, that works! Just had to make sure that the newLocation.QuestAvailableHere != null instead went through _player.CurrentLocation.QuestAvailableHere . Brilliant, thank you!
Cool!
Thank you! I’ve heard that pointers make programs much more efficient. How could we do that here? (I’m not really sure how pointers work in C#)
Usually, pointers are used in C and C++, not C#. They are used to access a variable, by its location in memory. With C#, we access the variable “by reference” or “by value”, and normally do not directly use pointers. Using pointers can make a program faster, or more efficient, but they also make it easier to make some types of mistakes.
I usually follow the rule to not try to optimize a program until you discover that it needs optimization. Wait until you have a problem, before you start doing special optimizations. You always want to write the program to run as fast, and efficient, as you know how. But don’t put extra effort into making a program 10 milliseconds faster, if it is already faster than the users need.
that’s good to know, thanks 🙂
Would you mind giving an example of when we’ve accessed “by reference” and when we’ve accessed “by value”, please? It will just make it a little clearer for me. Thanks so much!
The final lesson for adding a vendor (the lesson I am working on now) has an explanation of passing variables by reference and by value. If I do not post that by this weekend, I will make a separate (quick) post to explain how that works.
that’s great, thank you!
I’m still working on the last vendor lesson, so here is a quick post on the differences between a reference type variable and a value type variable.
Hi! Firstly, I want to thank you for this tutorial, It helped me much to understand things.
But I’m stuck. I think I’ve done everything properly, even all the numbers of the lines are correct everywhere. But testing it in Visual Studio or running the executable it throws an exception at / crashes around 3-4 moves, and the buttons doesn’t seem to work as they intended to. My solution is here with all folders ‘Release’ folder included.
I’ve translated almost everything to my language, but I hope you can still help me. 🙂
Thanks in advance!
You’re welcome, Frank.
There are a few small things to fix in RPG762.cs. I think these will make the program work.
Add this at line 27:
_jatekos.Inventory.Add(new InventoryTargy(Vilag.ItemByID(Vilag.ITEM_ID_RUSTY_SWORD), 1));That will give the player a starting weapon. If the player does not have a weapon, the program will hide the weapons combobox and “Hasznal/Use” button when it executes the UpdateWeaponListInUI() function.
Change lines 69 and 70 to this:
button1.Visible = (ujHely.HelyKeletFele != null);button2.Visible = (ujHely.HelyDelFele != null);
The button names were reversed. So, the player saw the “Kelet/East” button, but the location was at the “Del/South”. If you clicked the Kelet button, there was no Hely/Location object, so the program had an error.
Change lines 257 and 258 to this:
cboFegyverek.DataSource = fegyverek;cboFegyverek.DisplayMember = "Nev";
Or, change Targy’s “Nev” property to include the accent. The DisplayMember must exactly match the property name.
Please tell me if that does not fix everything.
Thanks! It fixed everything. 🙂
Great!
Hey Scott! Great tutorial!
I was given this tutorial by a teacher, as he wanted me to learn more about OOP, and it’s done a great job. He gave me one little challenge, though. I had to make it in WPF. I’ve run into some trouble sometimes, but the most pressing one is that I can’t seem to get quests.
Would you mind looking it through?
If it helps, I can upload my solution folder to DropBox, and send you a link – Any help would be appreciated, and I’m fairly certain I’ve misplaced something in code.
Thank you! Yes, upload it and send me the link. I will see if I can help you find the problem.
Thanks again! Here’s the link
There’s been some changes to the code you’ve written in your tutorials, and some work-arounds on things that couldn’t work together, but with this, I’m fairly certain I missed a line of code or a segment, and that I’ve now come too far to actually see it.
Try and run the code, and if you discover any more bugs, please let me know! I’d love to have the chance to figure it out myself!
Hi Marco,
For the quests, I saw two things in MainWindow.xaml.cs.
Line 105: Should be “if(playerAlreadyHasQuest)”. You want the first section to run if the player already has the quest, and the “else” section to run if they do not. SO, this line should not have a “!”
Line 164: This has an extra “}” that needs to be removed from here, and added to line 140. This is causing a problem with your “else”.
Those changes should fix it so the Quest grid fills up. I think there are some more things you will want to do to the Quest grid, but I will let you try them on your own first. If you have problems, you might find clues in steps 2 and 7 of Lesson 20.3
Please tell me if you get that working, or if you want a little more help.
Thank you so much! I got it working, and started filling up the game with more mobs, locations, quests and items. I’ve also thought about what kind of stories I could come up with while using the same engine, but then I’d have to make some modifications to the UI as well, like, adding a new TextBlock to add stories, so people would get to know the quest givers more, or to learn more about the current location they’re standing in, instead of just a few lines in the Messages TextBlock.
The truth is that I’m having more fun adding in the world, than actually writing the code, as I have a few problems with just understanding the logic, but I feel like I’m getting it, albeit slowly.
You’re welcome! Sometimes it takes a little time to learn a programming technique. But, every time you see it, it is written a little stronger in your brain. Eventually, you can easily understand it.
It is still the same way for me, after 35 years of programming. When I learn something new, I need to work with it a few times before I truly understand it.