Sign in to follow this  
raidzero

C# Game Set Bonuses

Recommended Posts

raidzero    112
So I'm just adding some more content to my text based game, how would I go about adding set bonuses?
Say if my hero has equipone and equiptwo then hero gains 10 defense bonus

This is currently how my shop works. You can only own one of each item.
[code] case "EquipOne":
case "EquipOne":
checkitem = hero.CheckItems(equipone);
if (checkitem == false)
{
if (hero.Gold >= 1)
{
hero.Gold -= 1;
hero.items.Add(equipone);
hero.Defense += 10;
Console.WriteLine("Thank you, anything else you want?");
Console.ReadLine();
}
else
{
Console.WriteLine("You currently have {0} gold, how do you expect to pay me?", hero.Gold);
}
}
else
{
Console.WriteLine("You already own one");
}
break;[/code]

But how would I go about checking if the hero has requirements to gain a set bonus? Could I do something like this?
[code] public static void CheckSet(Hero hero)
{
if (items.Contains() && items.Contains())
{
hero.Defense += 10;
}
else
{

}
}[/code]

Then I would have it call this method whenever buying or selling a piece of this set. I just need to figure out the if()

Share this post


Link to post
Share on other sites
ApochPiQ    23003
Sure, you could do that. You just need a container object for "items" and then you can check it to see if it holds various special gear.

Are you familiar with container classes? If so, have you already selected one for storing items?

Share this post


Link to post
Share on other sites
raidzero    112
[quote name='ApochPiQ' timestamp='1311488380' post='4839496']
Sure, you could do that. You just need a container object for "items" and then you can check it to see if it holds various special gear.

Are you familiar with container classes? If so, have you already selected one for storing items?
[/quote]

I'm not too familiar with container classes as I just started learning programming language a week ago. But I kind of figured it out, but then approached it a different way.
I am completely stumped on this problem. I went through debugging it, but I can't find the problem. When you go to save the game it saves whether you have or don't have hasEquipOne and hasEquipTwo as a bool.
By default bonusDefense is 0. Then I go an load the game it reads that hasEquipOne is true then proceeds to CheckEquips. Since hasEquipOne is true hero.bonusDefense is increased by 10 though when I go to check my hero's stats bonusDefense is 0.

Options.cs - related to Loading
[code] public void Load(Hero hero)
{
Hero myhero;
myhero = new Hero();
bool done = false;
string item;
StreamReader file = new StreamReader(@"C:\Users\Key\Documents\Visual Studio 2010\Projects\TextBasedGame\Saves\PlayerData.dat");

hero.Id = file.ReadLine();
hero.Level = int.Parse(file.ReadLine());
hero.CurrentHealth = int.Parse(file.ReadLine());
hero.MaxHealth = int.Parse(file.ReadLine());
hero.CurrentMagic = int.Parse(file.ReadLine());
hero.MaxMagic = int.Parse(file.ReadLine());
hero.baseStrength = int.Parse(file.ReadLine());
hero.baseDefense = int.Parse(file.ReadLine());
hero.Exp = int.Parse(file.ReadLine());
hero.Gold = int.Parse(file.ReadLine());
hero.PhysicalDamage = int.Parse(file.ReadLine());
Store.hasEquipOne = bool.Parse(file.ReadLine());
Store.hasEquipTwo = bool.Parse(file.ReadLine());

while (done == false)
{
item = file.ReadLine();

if (item != null)
{
hero.items.Add(item);
}
else
{
done = true;
}
}
file.Close();
Stats.CheckEquips(myhero);
Stats.CheckSet(myhero);
Console.WriteLine("Game Loaded");
Console.ReadLine();
}[/code]

Hero.cs
[code]using System;
using System.Collections.Generic;

namespace TextBasedGame
{
public class Stats
{
public static void PrintStats(Hero hero)
{
Console.Clear();
Console.Write(@"
_____________
Stats Sheet
_____________
Name: {0}
Level: {1}
Hp: {2}/{3}
Mp: {4}/{5}
Attack: {6}
Strength: {7} (+{8})
Defense: {9} (+{10})
Exp: {11}
Gold: {12}
_____________
Equipment
_____________
Items:
", hero.Id, hero.Level, hero.CurrentHealth, hero.MaxHealth, hero.CurrentMagic, hero.MaxMagic, hero.PhysicalDamage, hero.baseStrength, hero.bonusStrength, hero.baseDefense, hero.bonusDefense, hero.Exp, hero.Gold);
foreach (string item in hero.items)
{
Console.WriteLine(item);
}
while (hero.Id == null || hero.Id == "" || hero.Id == " ")
{
Console.Clear();
Console.WriteLine("Choose a name for your hero.");
hero.Id = Console.ReadLine();
}
Console.WriteLine();
Console.ReadLine();
Console.Clear();
}
public static void CheckEquips(Hero hero)
{
if (Store.hasEquipOne == true)
{
hero.bonusDefense += 10;
}
if (Store.hasEqupTwo == true)
{
hero.bonusDefense += 10;
}
else
{
hero.bonusDefense = hero.bonusDefense;
}
}
public static void CheckSet(Hero hero)
{
if (Store.hasEquipOne == true && Store.hasEquipTwo == true)
{
hero.bonusDefense += 10;
}
else
{
hero.bonusDefense = hero.bonusDefense;
}
}
}
}[/code]

Share this post


Link to post
Share on other sites
ApochPiQ    23003
Your CheckEquips function doesn't change the hero you give it, it changes a [i]copy[/i] of that hero - so the original doesn't get the stat adjustments.

There are two ways to fix this: make CheckEquips a member of Hero, and just modify the member values directly; or pass the Hero using "ref" to CheckEquips so that it can modify the hero object you give it.

Share this post


Link to post
Share on other sites
raidzero    112
Thanks ApochiPiQ.

Don't completely understand how to accomplish it, but I tried:

Hero.cs
[code]using System;
using System.Collections.Generic;

namespace TextBasedGame
{
public class Hero : Character
{
public List<string> items;


public Hero()
{
items = new List<string>();
}
public static void Initialize(Hero hero)
{
hero.Level = 1;
hero.CurrentHealth = 100;
hero.MaxHealth = 100;
hero.CurrentMagic = 20;
hero.MaxMagic = 20;
hero.baseStrength = 10;
hero.bonusStrength = 0;
hero.baseDefense = 5;
hero.bonusDefense = 0;
hero.Exp = 0;
hero.Gold = 0;
hero.isAlive = true;
hero.Strength = hero.baseStrength + hero.bonusStrength;
hero.PhysicalDamage = hero.Strength * 3;
hero.Defense = hero.baseDefense + hero.bonusDefense;
}
public bool CheckItems(string item)
{
if (items.Contains(item))
{
return true;
}
else
{
return false;
}
}
public static void CheckLevel(Hero hero)
{
if (hero.Exp >= 0 && hero.Exp < 50)
{
hero.Level = 1;
}
else if (hero.Exp >= 50 && hero.Exp < 250)
{
hero.Level = 2;
}
else if (hero.Exp >= 250 && hero.Exp < 2500)
{
hero.Level = 3;
}
else if (hero.Exp >= 2500 && hero.Exp < 10000)
{
hero.Level = 4;
}
else if (hero.Exp >= 10000)
{
hero.Level = 5;
}
}
public static void CheckEquips(Hero hero)
{
if (Store.hasPandaBeanie == true)
{
hero.bonusDefense += 10;
}
if (Store.hasPandaShield == true)
{
hero.bonusDefense += 10;
}
else
{
hero.bonusDefense = hero.bonusDefense;
}
}
public static void CheckSet(Hero hero)
{
if (Store.hasPandaBeanie == true && Store.hasPandaShield == true)
{
hero.bonusDefense += 10;
}
else
{
hero.bonusDefense = hero.bonusDefense;
}
}
}
}
[/code]

Then I modified this part of Options.cs
[code] file.Close();
Hero.CheckEquips(hero);
Hero.CheckSet(hero);
Console.WriteLine("Game Loaded");
Console.ReadLine();[/code]

But every time I load the game the bonusDefense stack, you gain an extra 10 every time you load the save.

-Edit-
I tried have it save bonusDefense, but the same problem occurs. This time when you save and load...thinking of moving the two Checks in Options.cs to somewhere where it only loads once...but then..what if you buy new equips..

I set hero.bonusDefense = 0; before checking equips and sets..testing some other ways..

The problem now is how do I do these Check so the effects don't stack? Nevermind, answered my own question from what I did above.
Though setting hero.bonusDefense =0; every time is...more work....atleast it works.

Share this post


Link to post
Share on other sites
raidzero    112
Yeah figured that one out..looking for bugs in it for now.
[code] public static void CheckAll(Hero hero)
{
hero.bonusDamage = 0;
hero.bonusDefense = 0;
Hero.CheckLevel(hero);
Hero.CheckEquips(hero);
Hero.CheckSet(hero);
hero.Strength = hero.baseStrength + hero.bonusStrength;
hero.Defense = hero.baseDefense + hero.bonusDefense;
hero.PhysicalDamage = (hero.Strength * 3) + hero.bonusDamage;
}[/code]

But I'm thinking with the current way I have things setup it'll be limiting :\

Share this post


Link to post
Share on other sites
j-locke    945
It looks like what you have written there does accomplish what you want to accomplish right now.

But, yes I do agree. As you add more sets and items with bonuses in this system, you need to check those new ones as well as check each of these older ones.

Share this post


Link to post
Share on other sites
raidzero    112
I need to come up with a better way to store/check for equips...
Right now I have the save options to store all equips as bool, true or false...which is a lot to type out if I plan on add more equipment.
Is there anyway I can make it more efficient? I thought about using my CheckEquips to check for the equip > apply stats > set the bool...any ideas?


Options.cs
[code]using System;
using System.Collections.Generic;
using System.IO;

namespace TextBasedGame
{
public class Options
{
public Options()
{

}

public void Save(Hero hero)
{
while (hero.Id == null || hero.Id == "" || hero.Id == " ")
{
Console.Clear();
Console.WriteLine("Choose a name for your hero.");
hero.Id = Console.ReadLine();
}
if (Directory.Exists(@"C:\Users\Key\Documents\Visual Studio 2010\Projects\TextBasedGame\Saves") == false)
{
Directory.CreateDirectory(@"C:\Users\Key\Documents\Visual Studio 2010\Projects\TextBasedGame\Saves");
}
StreamWriter file = new StreamWriter(@"C:\Users\Key\Documents\Visual Studio 2010\Projects\TextBasedGame\Saves\PlayerData.dat");

file.WriteLine(hero.Id);
file.WriteLine(hero.Level);
file.WriteLine(hero.CurrentHealth);
file.WriteLine(hero.MaxHealth);
file.WriteLine(hero.CurrentMagic);
file.WriteLine(hero.MaxMagic);
file.WriteLine(hero.baseStrength);
file.WriteLine(hero.baseDefense);
file.WriteLine(hero.Exp);
file.WriteLine(hero.Gold);
file.WriteLine(hero.PhysicalDamage);
file.WriteLine(Store.hasPrimary);
file.WriteLine(Store.hasSecondary);
file.WriteLine(Store.hasHeadgear);
file.WriteLine(Store.hasTop);
file.WriteLine(Store.hasBottom);
file.WriteLine(Store.hasShoes);
file.WriteLine(Store.hasGloves);
file.WriteLine(Store.hasMantle);
file.WriteLine(Store.hasPendant);
file.WriteLine(Store.hasRing);
file.WriteLine(Store.hasDevSword);
file.WriteLine(Store.hasDevBeanie);
file.WriteLine(Store.hasDevShirt);
file.WriteLine(Store.hasDevPants);
file.WriteLine(Store.hasDevShoes);
file.WriteLine(Store.hasDevMittens);
file.WriteLine(Store.hasDevCloak);
file.WriteLine(Store.hasDevPendant);
file.WriteLine(Store.hasDevRing);
file.WriteLine(Store.hasPandaBeanie);
file.WriteLine(Store.hasPandaShield);

foreach (string item in hero.items)
{
file.WriteLine(item);
}

file.Close();
Console.WriteLine("Game Saved");
Console.ReadLine();
}

public void Load(Hero hero)
{
bool done = false;
string item;
StreamReader file = new StreamReader(@"C:\Users\Key\Documents\Visual Studio 2010\Projects\TextBasedGame\Saves\PlayerData.dat");

hero.Id = file.ReadLine();
hero.Level = int.Parse(file.ReadLine());
hero.CurrentHealth = int.Parse(file.ReadLine());
hero.MaxHealth = int.Parse(file.ReadLine());
hero.CurrentMagic = int.Parse(file.ReadLine());
hero.MaxMagic = int.Parse(file.ReadLine());
hero.baseStrength = int.Parse(file.ReadLine());
hero.baseDefense = int.Parse(file.ReadLine());
hero.Exp = int.Parse(file.ReadLine());
hero.Gold = int.Parse(file.ReadLine());
hero.PhysicalDamage = int.Parse(file.ReadLine());
Store.hasPrimary = bool.Parse(file.ReadLine());
Store.hasSecondary = bool.Parse(file.ReadLine());
Store.hasHeadgear = bool.Parse(file.ReadLine());
Store.hasTop = bool.Parse(file.ReadLine());
Store.hasBottom = bool.Parse(file.ReadLine());
Store.hasShoes = bool.Parse(file.ReadLine());
Store.hasGloves = bool.Parse(file.ReadLine());
Store.hasMantle = bool.Parse(file.ReadLine());
Store.hasPendant = bool.Parse(file.ReadLine());
Store.hasRing = bool.Parse(file.ReadLine());
Store.hasDevSword = bool.Parse(file.ReadLine());
Store.hasDevBeanie = bool.Parse(file.ReadLine());
Store.hasDevShirt = bool.Parse(file.ReadLine());
Store.hasDevPants = bool.Parse(file.ReadLine());
Store.hasDevShoes = bool.Parse(file.ReadLine());
Store.hasDevMittens = bool.Parse(file.ReadLine());
Store.hasDevCloak = bool.Parse(file.ReadLine());
Store.hasDevPendant = bool.Parse(file.ReadLine());
Store.hasDevRing = bool.Parse(file.ReadLine());
Store.hasPandaBeanie = bool.Parse(file.ReadLine());
Store.hasPandaShield = bool.Parse(file.ReadLine());


while (done == false)
{
item = file.ReadLine();

if (item != null)
{
hero.items.Remove(item);
hero.items.Add(item);
}
else
{
done = true;
}
}
file.Close();
Hero.CheckAll(hero);
Console.WriteLine("Game Loaded");
Console.ReadLine();
}
}
}
[/code]

Share this post


Link to post
Share on other sites
ApochPiQ    23003
The next step would be to transition from using a bool for every item, to using a container of items instead. To get you started: make an enum that contains an ID for every item in your game, then make a container such as a List that holds entries of those IDs. See if you can piece together how to make those tweaks [img]http://public.gamedev.net/public/style_emoticons/default/smile.gif[/img]

Share this post


Link to post
Share on other sites
raidzero    112
Thank you, ApochiPiQ for your reply, really appreciate it.
I'm researching about enums, but can't really get my head around how to apply it to a game.
In my mind I keep wanting to use bools...

[code]
namespace TextBaseGame
{
public enum Equipment
{
EquipOne = 0,
EquipTwo = 1
}
Class Test
{
}
}
[/code]

Then I have this
[code]using System;
using System.Collections.Generic;

namespace TextBasedGame
{
public class Hero : Character
{
public List<string> items;


public Hero()
{
items = new List<string>();
}[/code]

Share this post


Link to post
Share on other sites
beatlefan    198
[quote name='Key' timestamp='1311646489' post='4840337']
Then I have this
[code]using System;
using System.Collections.Generic;

namespace TextBasedGame
{
public class Hero : Character
{
public List<string> items;


public Hero()
{
items = new List<string>();
}[/code]
[/quote]

How about this:
[code]
namespace TextBasedGame
{
public class Hero : Character
{
public List<Equipment> items;


public Hero()
{
items = new List<Equipment>();
}
[/code]

Share this post


Link to post
Share on other sites
raidzero    112
Now I'm a bit lost.
I currently have it like this.

Store.cs
[code] const string devsword = "DevSword";
const string devbeanie = "DevBeanie";
const string devshirt = "DevShirt";
const string devpants = "DevPants";
const string devshoes = "DevShoes";
const string devmittens = "DevMittens";
const string devcloak = "DevCloak";
const string devpendant = "DevPendant";
const string devring = "DevRing";
const string pandabeanie = "PandaBeanie";
const string pandashield = "PandaShield";[/code]

When you purchase an item it adds it to the list.
[code] case "DevBeanie":
case "devbeanie":
checkitem = hero.CheckItems(devbeanie);
if (checkitem == false && hasHeadgear == false)
{
if (hero.Gold >= 1)
{
hero.Gold -= 1;
hero.items.Add(devbeanie);
hasDevBeanie = true;
hasHeadgear = true;
Console.WriteLine("Thank you, anything else you want?");
Console.ReadLine();
}
else
{
Console.WriteLine("You currently have {0} gold, how do you expect to pay me?", hero.Gold);
Console.ReadLine();
}
}
else
{
Console.WriteLine("You already have a headgear");
Console.ReadLine();
}
break;[/code]

How would using enums instead improve what I have now? I can probably get rid of those bools..

Share this post


Link to post
Share on other sites
beatlefan    198
[quote name='Key' timestamp='1311647553' post='4840346']

How would using enums instead improve what I have now? I can probably get rid of those bools..

[/quote]


Truly, I don't think it will make that much of a difference, but it would be a tad easier for you, maybe.

What you can do is something like this:
[code]

public enum Items
{
DevSword,
DevBeanie,
DevShirt,
DevPants,
// and so on
}
[/code]

Then have the player class have a list of Items, and when they buy something add whatever it is to that list
[code]
//buy sword
player.items.add(Items.DevSword);
[/code]
Then to check if the player has the item
[code]
foreach(Item item in player.items)
{
if(item == Item.DevSword)
return true;
else
return false;
}
[/code]


You could also make an Item class since your items have a price, it would be more code though, such as this:
[code]

public enum ItemType
{
DevSword,
DevBeanie,
DevShirt,
DevPants,
// and so on
}

abstract class Item
{
public int Cost { get; protected set; }
public ItemType Item { get; protected set;}

public Item(int cost, ItemType type)
{
Cost = cost;
Item = type;
}
}

class DevSword : Item
{
public DevSword()
: base(1, ItemType.DevSword) // cost and Type
{
}
}

[/code]

Share this post


Link to post
Share on other sites
raidzero    112
Hidden
Lots and lots of extra work to deal with.
So I setup all the equipment in Test class with all the enum..this is where I have trouble understanding/figuring out how can I use them.

Share this post


Link to post
raidzero    112
I've spent all morning trying to figure/get it to work...frustrated now.
Tried adding it in to my current project, but to many errors occurred so I started a new project with only the necessary code.
Though, it's not working out like how I planned it...below I was just moving stuff around and removed some stuff...completely lost now
For the most part I have it like how beatlefan has it.

Hero.cs
[code]using System;
using System.Collections.Generic;

namespace Test
{
public class Hero : Character
{
public List<Items> items;


public Hero()
{
items = new List<Items>();
}
public static void Initialize(Hero hero)
{
hero.Level = 1;
hero.CurrentHealth = 100;
hero.MaxHealth = 100;
hero.CurrentMagic = 20;
hero.MaxMagic = 20;
hero.baseStrength = 10;
hero.bonusStrength = 0;
hero.baseDefense = 5;
hero.bonusDefense = 0;
hero.bonusDamage = 0;
hero.Exp = 0;
hero.Gold = 0;
hero.isAlive = true;
}
public bool CheckItems(Items item, Hero hero)
{
foreach (Item item in hero.items)
{
if (item == Item.DevSword)
return true;
else
return false;
}
}
public static void CheckLevel(Hero hero)
{
if (hero.Exp >= 0 && hero.Exp < 50)
{
hero.Level = 1;
}
else if (hero.Exp >= 50 && hero.Exp < 250)
{
hero.Level = 2;
}
else if (hero.Exp >= 250 && hero.Exp < 2500)
{
hero.Level = 3;
}
else if (hero.Exp >= 2500 && hero.Exp < 10000)
{
hero.Level = 4;
}
else if (hero.Exp >= 10000)
{
hero.Level = 5;
}
}
public static void CheckAll(Hero hero)
{
hero.MaxHealth = 100;
hero.MaxMagic = 20;
hero.bonusStrength = 0;
hero.bonusDamage = 0;
hero.bonusDefense = 0;
Hero.CheckLevel(hero);
hero.Strength = hero.baseStrength + hero.bonusStrength;
hero.Defense = hero.baseDefense + hero.bonusDefense;
hero.PhysicalDamage = (hero.Strength * 3) + hero.bonusDamage;
if (hero.CurrentHealth > hero.MaxHealth)
{
hero.CurrentHealth = hero.MaxHealth;
}
if (hero.CurrentMagic > hero.MaxMagic)
{
hero.CurrentMagic = hero.MaxMagic;
}
}
}
}
[/code]

Share this post


Link to post
Share on other sites
beatlefan    198
In CheckItems do:

[code]
public bool CheckItems(Items hasThisItem, Hero hero)
{
foreach (Item item in hero.items)
{
if (item == hasThisItem) // changed part
return true;
else
return false;
}
}
[/code]

Share this post


Link to post
Share on other sites
raidzero    112
I'm getting:

[code]
Operator '==' cannot be applied to operands of type 'Test.Item' and 'Test.Items'
Cannot convert type 'Test.Items' to 'Test.Item'
[/code]

Share this post


Link to post
Share on other sites
beatlefan    198
[quote name='Key' timestamp='1311715599' post='4840812']
I'm getting:

[code]
Operator '==' cannot be applied to operands of type 'Test.Item' and 'Test.Items'
Cannot convert type 'Test.Items' to 'Test.Item'
[/code]
[/quote]

ahh

okay try this in the if statement
[code]
if(item.itemType == hasThisItem) // or item.Item, or whatever you named it
[/code]

Share this post


Link to post
Share on other sites
ApochPiQ    23003
My guess is that you named your enum Items but you're trying to refer to it as Item. The compiler, being a rather poor English speaker, is complaining that an Items is not an Item (which is, strictly speaking, correct).

Share this post


Link to post
Share on other sites
raidzero    112
I tried all sorts of variations, but didn't solve the problem.
[code] public bool CheckItems(Items hasThisItem, Hero hero)
{
foreach (Items item in hero.items)
{
if (item == hasThisItem)
return true;
else
return false;
}
}[/code]
With this I get:
[code]
'Test.Hero.CheckItems(Test.Items, Test.Hero)': not all code paths return a value
[/code]

Share this post


Link to post
Share on other sites
beatlefan    198
[quote name='Key' timestamp='1311733454' post='4840921']
I tried all sorts of variations, but didn't solve the problem.
[code] public bool CheckItems(Items hasThisItem, Hero hero)
{
foreach (Items item in hero.items)
{
if (item == hasThisItem)
return true;
else
return false;
}
}[/code]
With this I get:
[code]
'Test.Hero.CheckItems(Test.Items, Test.Hero)': not all code paths return a value
[/code]
[/quote]

Try
[code]
public bool CheckItems(Items hasThisItem, Hero hero)
{
foreach (Items item in hero.items)
{
if (item == hasThisItem)
return true;
}
return false;
}[/code]

Share this post


Link to post
Share on other sites
Nypyren    12063
If "Items" is an enum AND hero.items is a List<Items> (instead of Item like you might eventually need), you can use the "Contains" method on the list:

[code]
public bool CheckItems(Items hasThisItem, Hero hero)
{
return hero.items.Contains(hasThisItem);
}
[/code]

(or, in fact, you wouldn't even need the CheckItems method and could just call hero.items.Contains whenever you want to check).


If hero.items is a List<Item> (the class, not the enum) then you can either use the foreach loop from beatlefan's post (1 above this one) or use a LINQ statement that does the same thing:

[code]
return hero.items.Any(item => item.itemType == hasThisItem);
[/code]

On second thought... maybe I shouldn't introduce lambda expressions in the Beginners forums...





In addition, I HIGHLY recommend never having type names that only differ by a single letter. Your best bet would be to have 'class Item' and 'enum ItemType' like beatlefan suggested. Then you can tell them apart at a glance without the possibility of mixing them up!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this