Im trying to design Spell class that can modify almost anything, Player, Units, other spells, etc. I figured out two ways of doing it, but none of this seems proper for me. Thats mainly because of Player class that got a lot of parameters and setting spell is a bit troublesome.
First is:
Spell interface that Im adding to each class of spell, which have method: execute.
Pros:
- dont have to pass a lot of parameters, just call proper function of target class of a spell
- To use spell just pick spell Player.GetSpell("Fireball").Execute(targets)
- Big flexibility
Cons:
- A LOT OF CLASSES, like 30 or more. One for each spell type
- Each spell need to be wrote manually
Creating spell
class Fireball : SpellBase, ISpell
{
public void Execute(Player caster, List<Object> target)
{
caster.Mana -= ManaCost;
foreach (var o in target)
{
if (o.GetType() == typeof(Player))
{
var p = (Player)o;
p.Health -= 10;
Console.WriteLine("Player: {0} recieved 10 dmg, now has {1}",
p.Name, p.Health);
}
else if (o.GetType() == typeof(Spell))
{
var s = (Spell)o;
s.Cooldown += 1;
Console.WriteLine("Unit: {0} recieved 10 dmg, now has {1}",
s.Name, s.Health);
}
}
}
}
Construction
spells.Add(new Fireball());
Executing
spells.First().Execute(caster, enemy);
Second approach:
Write one or few classes that can have different functionality depending on parameters set in constructor.
Pros:
- few classes
- loading parameters from file or data base
Cons:
- setting a lot of parameters for different classes(spells and player really dont have much common fields)
- One gigantic method, to handle spell execution
Creating spell
class Spell:SpellBase
{
public SpellData Data { get; set; }
public Spell(SpellData param)
{
Data = param;
}
}
Construction
spells.Add(new Frostball(params));
{
HealthMod = -10
});
Executing
public void CastSpell(Player caster, List<Object> enemy)
{
Caster.Mana -= ManaCost;
foreach (var o in enemy)
{
if (o.GetType() == typeof(Player))
{
var p = (Player)o;
p.Health += spell.Data.HealthMod;
//p.Defence += spell.Data.DefenceMod;
//and a lot of atributes and dependencies
//.
//.
//..........
}
else if (o.GetType() == typeof(Spell))
{
var s = (Unit)o;
s.Cooldown += spell.Data.CooldownMod;
//s.Defence += spell.Data.DefenceMod;
//and a lot of atributes
//.
//.
//..........
}
}
}
So... I need flexibility a lot. Im not saying its not possible to make it with second way but it will make one big Method with a lot of ifs, which I want to avoid, and i know that with time complexity of this will overwhelm me. Also setting parameters of all spells easily from DB would be nice.
Which one approach do you suggest? Maybe change sth or even you have ideas for whole different way of doing this? Please help me :)
Designin's hard... Sorry for english.