using System; using ZLinq; namespace Nox.Game { public interface ICharacterStatsFactory { EntityStats Create(IEntityDefinition entityDefinition); } public sealed class CharacterStatsFactory : ICharacterStatsFactory { private readonly StarterCharacterSettings baseSettings; private readonly IModifierResolver modifierResolver; public CharacterStatsFactory(StarterCharacterSettings baseSettings, IModifierResolver modifierResolver) { this.baseSettings = baseSettings; this.modifierResolver = modifierResolver ?? throw new ArgumentNullException(nameof(modifierResolver)); } public EntityStats Create(IEntityDefinition entityDefinition) { var attributes = entityDefinition.Attributes; if(attributes.attributes.AsValueEnumerable().Any(a => a.value <= 0)) { throw new ArgumentOutOfRangeException( "attributes cannot be zero or negative.", new ArgumentException() ); } var healthModifiers = modifierResolver.CollectModifiers(entityDefinition, StatType.Health); var manaModifiers = modifierResolver.CollectModifiers(entityDefinition, StatType.Mana); var levelModifiers = modifierResolver.CollectModifiers(entityDefinition, StatType.Level); var experienceModifiers = modifierResolver.CollectModifiers(entityDefinition, StatType.Experience); return new EntityStats { stats = new[] { new Stat(StatType.Health, modifierResolver.Resolve(baseSettings.defaultEntityStats.GetValue(StatType.Health), healthModifiers, entityDefinition)), new Stat(StatType.Mana, modifierResolver.Resolve(baseSettings.defaultEntityStats.GetValue(StatType.Mana), manaModifiers, entityDefinition)), new Stat(StatType.Level, modifierResolver.Resolve(baseSettings.defaultEntityStats.GetValue(StatType.Level), levelModifiers, entityDefinition)), new Stat(StatType.Experience, modifierResolver.Resolve(baseSettings.defaultEntityStats.GetValue(StatType.Experience), experienceModifiers, entityDefinition)) } }; } } }