Click to See Complete Forum and Search --> : How do I??
bixel
September 12th, 2008, 05:36 PM
C# here
StatisticsValue is a struct of values (floats)
class Spell is defining some values that StaticsValue holds, the spell may have 1 or more values but not all of the values StatisticsValue holds.
You cannot assign one float value to a whole structure. Do it like this
StatisticsValue statEffect = new StatisticsValue();
statEffect.SomeVariable = spell.TargetEffectValue;
If you want to multiply every float in a class with a value, try this
foreach(float f in spell)
f = (f * ARCmodifier);
bixel
September 12th, 2008, 07:15 PM
TargetEffectValue is not a single variable - srry I should have clarified that.
from class Spell
/// <summary>
/// Therange of statistics effects of this spell on its target.
/// Like Equipment We can do a lot of things here.
/// HealthPoints
/// MagicPoints
/// Strength
/// Vitality
/// Agility
/// Accuracy
/// Evasion
/// Parry
/// CounterAttack
/// TotalArmor
/// MagicDefense
/// SpellCasting
/// This is a debuff if IsOffensive is true, otherwise it's a buff.
/// This is the Initial reading of the spell effects.
/// Later we will modify it by the Caster's Arcane Level
/// </summary>
private StatisticsValue targetEffectValue = new StatisticsValue();
[ContentSerializerIgnore]
public StatisticsValue TargetEffectValue
{
get { return targetEffectValue; }
}
public static StatisticsValue CalculateSpellDamage(Combatant combatant, Spell spell)
{
// check the parameters
if (combatant == null)
{
throw new ArgumentNullException("combatant");
}
if (spell == null)
{
throw new ArgumentNullException("spell");
}
// get the magical offense from the character's class, gear, and bonuses
// -- note that this includes stat buffs
float arcaneSkill = combatant.Character.Arcane;
//if we are going ot do damage its going to be a variance based off of our Arcane Skill
//Get the Variance
float variance = 0.30f;
//Create the Arcane modifer
float ARCmodifier = 1 + (arcaneSkill / 100);
-----------------------------
I think I am getting closer but...
JonnyPoet
September 13th, 2008, 03:54 PM
Hi bixel !
Please read our forum habits and use codetags. As you dnt your code losts any sort of formatting and is just unreadable. Please edit your code and do a correct Format so its easier to read.
Additional your code is wrong in a lot of places and would never compile
For exampleList<StatisticsValue> statEffect = List<spell.TargetEffectValue>();
At first instantiating a generic List you need to have the Type in yot list definition so the left part is correct but in the right side you cannot define the type using an instance of another class and a parameter of this class.
Additional instantiating needs the 'new keyword so this line should be
List<StatisticsValue> statEffect = new List<StatisticsValue>();
The next one is also not compileable
foreach (float statEffect in spell)
...
This would need to have a list of statEffect contained in a List called spell and statEffect should be a float. But just in the line before you declared it to be a generic List of objects of type StatisticsValue.
So, sorry to say, this seems me to be a totally confusion.
Do it in a clar line
a) define your StatistricsValue class in a clear way. Is Statistics Value itself one Value or a class containing different StatisticValues ? IMHO the second point is correct. So it needs to get a correct name. StatisticsValues !! As earlier you decide yourself to have a clean precise naming in your classnames as easier you will be able to code it.
If you need to multiply any property of a class which could be multiplied then you can do this with different methods
The easiest is to have it in the class itself like (taking part of your example as an example
public class StatisticsValues{
private int _healthPoints;
private int _magicPoints;
private int _strength;
private decimal _agility;
private decimal _vitality;
#region Constructor
public StatisticsValues( int health, int magic, int strength, decimal agility,decimal vitality) {
_healthPoints = health;
_magicPoints = magic;
_strength = strength;
_agility = agility;
_vitality = vitality;
}
#endregion
public int HealthPoints {
get { return _healthPoints; }
set { _healthPoints = value; }
}
public int MagicPoints {
get { return _magicPoints; }
set { _magicPoints = value; }
}
public int Strength {
get { return _strength; }
set { _strength = value; }
}
public decimal Vitality {
get { return _vitality; }
set { _vitality = value; }
}
public decimal Agility {
get { return _agility; }
set { _agility = value; }
}
public StatisticsValues GetVarianceStats(decimal variance) {
StatisticsValues varData = new StatisticsValues((int)(_healthPoints*variance), (int)(_magicPoints*variance), (int)(_strength*variance),_agility*variance,_vitality*variance );
return varData;
}
}
Instead of writing StatisticsValues varData = new StatisticsValues((int)(_healthPoints*variance), (int)(_magicPoints*variance), (int)(_strength*variance),_agility*variance,_vitality*variance );
return varData;
// you can also simplify this to
return new StatisticsValues((int)(_healthPoints*variance), (int)(_magicPoints*variance), (int)(_strength*variance),_agility*variance,_vitality*variance );
I did it the explicit way so you could better see what I'm doing.. Simple creating a new class where all inparams are multiplied.
If you want to use a loop for going through different params of a class and multiplying them you need to know a bit about reflection and this way you can read your class and for example multiplying all properties which are of Type int or of type float or whatever you want to to.
But if you want to have it simple and only need this one class to multiply do it like I showed you.
bixel
September 13th, 2008, 05:03 PM
public StatisticsValues GetVarianceStats(decimal variance)
{
StatisticsValues varData = new StatisticsValues((int)(_healthPoints*variance), (int)(_magicPoints*variance), (int)(_strength*variance),_agility*variance,_vitality*variance );
return varData;
}
oooh thats nifty
I did an overload and it worked on a value by value basis, but the above example is better for doing a modification as a whole.
StatisticsValue moddedEffect = StatisticsValue.MultiplyFloat(statEffect, ARCmodifier);
Looks fine, there is only one point I want to mention which is irritating a bit: Learn to use the standard notation. A local field everytime begins with a lower case letter so it needs to be arcModifier ! Otherwise I was looking for a class named ARCmodifier ! So this gives a wrong impression when you are trained to use the camel style. You will get thinking in that methods and looking for something which isn't here :D
MSDN has documentaion regarding how to use it look
http://msdn.microsoft.com/en-us/library/xzf533w0(VS.71).aspx
If any more questions feel free to ask. and Thx for using Codetags now :thumb:
CyberRascal
September 14th, 2008, 07:19 AM
Hmm, I just have something against hardcoded stuff like that.. Couldn't you just use
public static T MultiplyByFactor<T>(T value, float factor)
{
T modValues = (T)Activator.CreateInstance<T>();
foreach (PropertyInfo propInfo in values.GetType().GetProperties())
{
if (propInfo.PropertyType.IsValueType)
propInfo.SetValue(modValues, propInfo.GetValue(values, null) * factor, null);
}
return modValues as T;
}
Using the code would then look like this:
StatisticValues statValues = new StatisticsValues();
StatisticValues modStatValues = MultiplyByFactor<StatisticValues>(statValues, 1.5666f);
That code should set each property to be multiplied by a certain value. If not all values are floats maybe you will have to use casting to avoid float*int or something like that.
Edit: Hmm, perhaps that method does indeed use alot more resources since it has to instantiate alot of PropertyInfos, and it seems you are trying to produce a game, which probably needs all the resources it can get.. Up to you.
JonnyPoet
September 14th, 2008, 08:15 AM
Hmm, I just have something against hardcoded stuff like that.. Couldn't you just use
...
Thats what I mentioned in post#4 -> using reflection
If he knows how to use reflection he can do it this way. BTW I'm not sure if this doesn't get into troubles if he has other valuetype properties in his class for example bool , DateTime, char, byte? So I would restrict your method a bit more for example to only use PropertyTypes typeof(Int32) ... typeof(float.. whatever he really needs ) excluding all Types which arn't to be handled by math operation.
You also need to add namespace reflection or the propertyInfo will not get compileable.
But basically yes... Thats the advanced approach.. :D
CyberRascal
September 14th, 2008, 08:35 AM
Oh sorry, that's what I get for reading too fast. :p Anyway, you are right, he might get in trouble for that. Now I'm pretty new to programming so I don't know the best practice for that, but I would use attributes to single out the properties which should be converted..
public T MultiplyByFactor<T>(T value, float factor) where T : class
{
T modValues = (T)Activator.CreateInstance<T>();
public class StatisticValues
{
[DoConvertAttribute]
public float Health
{ get; set; }
[DoConvertAttribute]
public int MagicPoints
{
get { return _magicPoints; }
set { _magicPoints = value; }
}
[DoConvertAttribute]
public int Strength
{
get { return _strength; }
set { _strength = value; }
}
}
Perhaps not the best way, but doable. Maybe too advanced aswell, but I think it's better to have a steep learning curve instead of ingraining bad practice...
edit: Explaining why I do certain stuff:
Having T in the method signature:
This is called a generic argument and is used to make methods and classes more powerful, as they can be used with more classes/types than just one.
Casting the property values to IConvertible:
IConvertible provides means to convert value types to other kinds of value types. Converting to float here is necessary to make it possible to multiply. Then converting back to typeof(T) is necessary because the property will only accept values of the same type as in its signature.
JonnyPoet
September 14th, 2008, 02:58 PM
...
Perhaps not the best way, but doable. Maybe too advanced aswell, but I think it's better to have a steep learning curve instead of ingraining bad practice...
I dont fully agree. Looking to the code this seems much to advanced to get this done that way. And if someone has no basic knowlwdge about reflection, he may loose the ground under the feet totally. A learning curve easily can go out of gradient and then the people trying to learn are lost.
JonnyPoet
September 14th, 2008, 04:51 PM
.... Then converting back to typeof(T) is necessary because the property will only accept values of the same type as in its signature.May I correct you for better understanding.
We are not casting back to typeof(T) as this would mean casting any value to class StatisticVvaluues as T in your example is StaticticValues.
Correct you have meant: You are casting back to the same PropertyType which just was read out of the class using propInfo.PropertyType of the class PropertyInfo which is part of the Reflection namespace.
This way the property is filled with the correct values.
Also you should have explained that you have built a new class derived fro the Attribute class which is only a derived instande of it ( its empty as we see ) This is used to sign, which Attribútes to be used so if you for example have some boolean Property or some DateTime Property as I mentioned earlier, you didn't want to change them, so you simple dont set them to this classpublic class StatisticValues {
private float _health;
private int _magicPoints;
private int _strength;
private DateTime _today;
private bool _anotAllowed;
// no DoConvertAttribute here
public bool NotAllowed {
get { return _notAllowed; }
set { _notAllowed = value; }
}
// no DoConvertAttribute here
public DateTime Today {
get { return _today; }
set { _today = value; }
}
[DoConvertAttribute]
public float Health{
get { return _health; }
set { _health = value; }
}
[DoConvertAttribute]
public int MagicPoints {
get { return _magicPoints; }
set { _magicPoints = value; }
}
[DoConvertAttribute]
public int Strength {
get { return _strength; }
set { _strength = value; }
}
}
// and where you want to use the method
In this example The NotAllowed Property as well as the Today Property is transfered with its original values , but all which are 'signed' with class DoConvertAttribute are used to be converted.
Hope this helps to understnd this really good code example.
BTW: You cannot be totally 'new' to programming. :D Therefore the code is too cool:cool:
About CustomAttributes and Reflection I would suggest the questioner to read MSDN references about 'Attribute' class
CyberRascal
September 14th, 2008, 05:48 PM
Oh yes! Thank you, excellently explained. Sorry for making mistakes in explaining, makes it alot harder to understand. And yes, it is true that it's easy to get lost, especially while learning other concepts it was a "bad" example. I actually thought it would be quite simple at first, but there was quite a few complications, so it got more advanced than I thought at first! Will take note to post better (Or atleast correct!) explanation next time. :)
So to poster:
Use Jonnys example if you want to learn other concepts, keeping this one simple. Otherwise I think you can learn much by testing out the code I posted.
PS: Well, not totally new but still new enough to come up with a lot of pretty horrible designs!
JonnyPoet
September 14th, 2008, 06:28 PM
...Will take note to post better (Or atleast correct!) explanation next time. :) The code itself is great as it shows advanced concepts, which are used for getting reuseable code.
So to poster:
Use Jonnys example if you want to learn other concepts, keeping this one simple. Otherwise I think you can learn much by testing out the code I posted.! I woud suggest to try your example and to go through it step by step using the debugger. With your code and the (hopefully) full explanation of how it works he should really have taken the curve this time and learned a lot.
PS: Well, not totally new but still new enough to come up with a lot of pretty horrible designs!:lol: I overlooked and tested your code.
Cannot see any troubles here. My Considerations only have been regarding the obviously just learning poster and your very advanced example. My idea of learning is more a gradient concept: Learn the basics, -learn the basics- learn and understand really all basics. Train them in easy understandable examples. - When you feel fit about all this basic stuff, -> then go on and study design. Going this way someone will find that some of his own ideas are already known design patterns - and will have great win on that - and he will learn about design patterns in general and how to use them in his own designs. Sure he will redesign a lot of his stuff - but this will result in a good deep based knowledge how to do it and how to do it better. - This is based on my own learning experience - and I have seen this working on other people too, so this is 'my way' ;)
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.