15 November 2021 by jr101dallas
⇠ Back to PostsDefense
Back on the coding for Offense and Defense. I stopped pretty suddenly in the middle before, so I didn’t have any tests on Defense even though I’d popped in BaseHealth. Also, I’d thrown in BaseDamage in Office and hadn’t put a test on it, so here are those.
[TestMethod]
public void DefaultDefenseIsIComponent()
{
var def = new Defense();
Assert.IsTrue(def is IComponent);
}
[TestMethod]
public void DefaultDefenseBaseAimIsFive()
{
var def = new Defense();
Assert.AreEqual(50, def.BaseHealth);
}
[TestMethod]
public void DefaultOffenseBaseDamageIsFive()
{
var off = new Offense();
Assert.AreEqual(5, off.BaseDamage);
}
Still basic tests, based on current hardcoding. When I start doing more interesting things with the classes, the tests will keep me honest and aware of what I’m changing and whether I meant to change it.
Changes
I’m suddenly feeling like I planned this very badly. I totaly forgot that I’m going to want a CurrentHealth as well as a BaseHealth. That does add another test in DefenseTests. But then I’m ready to actually add the damage dealing logic in Target. It will mean thhat I have at least one test that will fail afterward. Right now, just targeting an Entity is removing it from play. Once I’m finished it will only have a reduction in CurrentHealth unless I change up some numbers.
public void TargetEntity(Entity originEntity, Entity targetEntity)
{
if (!targetEntity.components.TryGetValue(ComponentType.Defense, out var defenseIComponent)) return;
if (!originEntity.components.TryGetValue(ComponentType.Offense, out var offenseIComponent)) return;
int aimMods = 0;
if (originEntity.components.TryGetValue(ComponentType.Inventory, out var inventoryIComponent))
{
aimMods = GetAimModifiers(inventoryIComponent);
}
var defenseComponent = (Defense)defenseIComponent;
var offenseComponent = (Offense)offenseIComponent;
var aimModifier = offenseComponent.BaseAim;
var num = _rand.Next(100);
if (num + aimModifier + aimMods > 50)
{
var removeEntityId = targetEntity.Id;
Console.WriteLine($"Entity {removeEntityId.ToString()} has been removed from play!");
defenseComponent.CurrentHealth -= offenseComponent.BaseDamage;
if(defenseComponent.CurrentHealth <= 0)
_unv.entities.Remove(removeEntityId);
}
}
Of course that means that now I’m really looking hard at what kind of refactoring needs to happen because that thing is way too big. I’m seeing some patterns though and that will making straightening things out much easier.
Has Component
The first refactor I’m looking at is going to be a piece of logic I use a lot.
public bool HasDefense(Entity target, out Defense defCom)
{
bool foundDefense = HasComponent(target, ComponentType.Defense, out var defICom);
defCom = (Defense)defICom;
return foundDefense;
}
public bool HasOffense(Entity origin, out Offense offCom)
{
bool foundOffense = HasComponent(origin, ComponentType.Offense, out var offICom);
offCom = (Offense)offICom;
return foundOffense;
}
public bool HasComponent(Entity entity, ComponentType type, out IComponent component)
{
return entity.components.TryGetValue(type, out component);;
}
That shortens up TargetEntity a bit but better than that, it makes the return statements at the top much more clear.
public void TargetEntity(Entity originEntity, Entity targetEntity)
{
if (!HasDefense(targetEntity, out var defenseComponent)) return;
if (!HasOffense(originEntity, out var offenseComponent)) return;
int aimMods = 0;
if (originEntity.components.TryGetValue(ComponentType.Inventory, out var inventoryIComponent))
{
aimMods = GetAimModifiers(inventoryIComponent);
}
var aimModifier = offenseComponent.BaseAim;
var num = _rand.Next(100);
if (num + aimModifier + aimMods > 50)
{
var removeEntityId = targetEntity.Id;
Console.WriteLine($"Entity {removeEntityId.ToString()} has been removed from play!");
defenseComponent.CurrentHealth -= offenseComponent.BaseDamage;
if(defenseComponent.CurrentHealth <= 0)
_unv.entities.Remove(removeEntityId);
}
}