Reputation: 12768
This is minor, I know, but let's say that I have a class Character and a class Ability (mostly because that's what I'm working on). Class Character has six abilities (so typical D&D...). basically:
public class Character
{
public Character()
{
this.Str = new Ability("Strength", "Str");
this.Dex = new Ability("Dexterity", "Dex");
this.Con = new Ability("Constitution", "Con");
this.Int = new Ability("Intelligence", "Int");
this.Wis = new Ability("Wisdom", "Wis");
this.Cha = new Ability("Charisma", "Cha");
}
#region Abilities
public Ability Str { get; set; }
public Ability Dex { get; set; }
public Ability Con { get; set; }
public Ability Int { get; set; }
public Ability Wis { get; set; }
public Ability Cha { get; set; }
#endregion
}
and
public class Ability
{
public Ability()
{
Score = 10;
}
public Ability(string Name, string Abbr)
: this()
{
this.Name = Name;
this.Abbr = Abbr;
}
public string Name { get; set; }
public string Abbr { get; set; }
public int Score { get; set; }
public int Mod
{
get
{
return (Score - 10) / 2;
}
}
}
When actually using these ability properties in future code, I'd like to be able to default to just the score, like so:
//Conan hits someone
int damage = RollDice("2d6") + Conan.Str;
//evil sorcerer attack drains strength
Conan.Str = 0;
rather than:
//Conan hits someone
int damage = RollDie("2d6") + Conan.Str.Score;
//evil sorcerer attack drains strength
Conan.Str.Score = 0;
Now, the first case can be taken care of with an implicit conversion:
public static implicit operator int(Ability a)
{
return a.Score;
}
Can anybody help me with the reverse? Implicit conversion like this:
public static implicit operator Ability(int a)
{
return new Ability(){ Score = a };
}
will replace the entire attribute rather than just the score of the attribute—not the desired result...
Upvotes: 6
Views: 390
Reputation: 4523
First, keep your implicit conversion:
public static implicit operator Ability(int a)
{
return new Ability(){ Score = a };
}
Then in your character class: Add a private Ability attribute for str, and change the getter and the setter of the Str property as follows:
private Ability str;
public Ability Str
{
get
{
return this.str;
}
set
{
if (value.Name == "")
{
this.str.Score = value.Score;
}
else
{
this.str = value;
}
}
}
There you go :)
You could also use:
if(string.IsNullOrWhiteSpace(value.Name))
instead of
if (value.Name == "")
If you are compiling to .NET 4.0 version
EDIT: I gave you a solution that does exactly what you wanted to, but What ja72 wrote is also a good suggestion with operators + and -; you can add his solution to mine (or mine to him, whatever), it will work just fine. You will then be able to write:
Character Jax = new Character(); // Str.Score = 10
Character Conan = new Character(); // Str.Score = 10
Jax.Str = 2000; // Str.Score = 2000;
Conan.Str += 150; // Str.Score = 160
Upvotes: 3
Reputation: 39277
Perhaps you could make Ability
abstract and then derive new classes from Ability
for each of the sub-classes: Strength
, ...
The constructor for the Strength
class would look something like this:
public Strength () : base ("Strength", "Str") { ...}
Now the ability properties off a Character
would be strongly typed and the implicit conversions could turn a value like 5 into a Strength
object with a value of 5. This would also prevent you from accidentally storing a Dexterity
in a Strength
property, for example.
[Assuming the name and abbreviations are in fact fixed for all objects of that type.]
Upvotes: 0
Reputation: 29244
Another option is to replace the properties with delegates like this
public class Character
{
public Character()
{
...
}
#region Abilities
...
#endregion
public Func<int> Strength
{
get { return () => Str.Score; }
set { Str.Score = value(); }
}
}
and use it like this
Character evil = new Character(); //Str.Sccore=10
// fist spell hits
evil.Strength = () => 5; //set Str.Score=5
// second spell hits
evil.Strength = () => 0; //set Str.Score=5
if (evil.Strength() == 0)
{
// dead
}
Upvotes: 1
Reputation: 29244
The best you can do is increment the score by adding these methods to Ability
.
public static Ability operator + (Ability lhs, int score)
{
lhs.Score += score;
return lhs;
}
public static Ability operator - (Ability lhs, int score)
{
lhs.Score -= score;
return lhs;
}
public static implicit operator int(Ability rhs)
{
return rhs.Score;
}
and using them like:
static void Main(string[] args)
{
Character evil = new Character(); //Str.Sccore=10
evil.Str += 10; //cast spell for Str.Sccore=20
evil.Str -= evil.Str; //death with Str.Sccore=0
}
Upvotes: 4