using System; using System.Collections.Generic; using System.Linq; using CryptonymThunder.Code.Resources; using GameCore.Attributes; using GameCore.Combat; using GameCore.ECS.Interfaces; using GameCore.Input; using GameCore.Inventory; using GameCore.Movement; using GameCore.Physics; using GameCore.Player; using Godot; namespace CryptonymThunder.Code.Factories; public class ComponentFactory { private readonly Dictionary> _factories = new(); private readonly EffectFactory _effectFactory = new(); public ComponentFactory() { Register(CreateAttributeComponent); Register(CreateWeaponComponent); Register(CreateProjectileComponent); Register(_ => new PositionComponent()); Register(_ => new VelocityComponent()); Register(_ => new InputStateComponent()); Register(_ => new PlayerComponent()); Register(_ => new RotationComponent()); Register(_ => new CharacterStateComponent()); Register(_ => new InventoryComponent()); Register(CreatePickupComponent); } public IComponent Create(Resource resource) { return _factories.TryGetValue(resource.GetType(), out var factory) ? factory(resource) : null; } private void Register(Func factory) where TResource : Resource { _factories[typeof(TResource)] = res => factory((TResource)res); } private static AttributeComponent CreateAttributeComponent(AttributeComponentResource resource) { var component = new AttributeComponent(); foreach (var (attribute, value) in resource.BaseValues) { component.SetBaseValue(attribute, value); } return component; } private WeaponComponent CreateWeaponComponent(WeaponComponentResource resource) { if (resource.WeaponData == null) return null; var weaponData = resource.WeaponData; var onFireEffects = weaponData.OnFireEffects.Select(_effectFactory.Create).ToList(); var onHitEffects = weaponData.OnHitEffects.Select(_effectFactory.Create).ToList(); return new WeaponComponent { FireRate = resource.WeaponData.FireRate, OnFireEffects = onFireEffects, OnHitEffects = onHitEffects, }; } private ProjectileComponent CreateProjectileComponent(ProjectileComponentResource resource) { return new ProjectileComponent { Lifetime = resource.Lifetime, }; } private PickupComponent CreatePickupComponent(PickupComponentResource resource) { return new PickupComponent { ItemId = resource.ItemId, Quantity = resource.Quantity, IsInstantUse = resource.IsInstantUse }; } }