private void doAttacks()
{
IEnumerable<AttackAction> attackActions = CurrentVector.Actions.AttackActions;
foreach (AttackAction action in attackActions)
{
AnimalState attackerState = (AnimalState) _newWorldState.GetOrganismState(action.OrganismID);
if (attackerState == null || !attackerState.IsAlive)
{
continue;
}
AnimalState defenderState = (AnimalState) _newWorldState.GetOrganismState(action.TargetAnimal.ID);
int damageCaused = 0;
Boolean escaped = false;
Boolean killed = false;
if (defenderState == null)
{
// They were killed and eaten before the attack occurred
escaped = true;
}
else
{
// See if they are near enough to attack
// We let them attack if they are at most 1 rectangle away because
// it is hard to get closer than this
if (attackerState.IsWithinRect(1, defenderState))
{
// If the animal is dead, it's just zero damage
if (defenderState.IsAlive)
{
// Figure out the maximum possible attack damage
damageCaused = _random.Next(0, attackerState.AnimalSpecies.MaximumAttackDamagePerUnitRadius*
attackerState.Radius);
// Defense doesn't scale based on distance
DefendAction defendAction =
(DefendAction) CurrentVector.Actions.DefendActions[defenderState.ID];
int defendDiscount = 0;
if (defendAction != null && defendAction.TargetAnimal.ID == attackerState.ID)
{
defendDiscount = _random.Next(0,
defenderState.AnimalSpecies.
MaximumDefendDamagePerUnitRadius*
defenderState.Radius);
}
if (damageCaused > defendDiscount)
{
damageCaused = damageCaused - defendDiscount;
defenderState.CauseDamage(damageCaused);
}
else
{
damageCaused = 0;
}
killed = !defenderState.IsAlive;
defenderState.OrganismEvents.AttackedEvents.Add(new AttackedEventArgs(attackerState));
}
}
}
// Tell the attacker what happened
attackerState.OrganismEvents.AttackCompleted = new AttackCompletedEventArgs(action.ActionID, action,
killed, escaped,
damageCaused);
}
}