Files
cryptonhym-thunder/Code/Factories/ComponentFactory.cs

181 lines
6.2 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using CryptonymThunder.Code.Resources;
using GameCore.Attributes;
using GameCore.Combat;
using GameCore.Combat.Interfaces;
using GameCore.ECS.Interfaces;
using GameCore.Input;
using GameCore.Interaction;
using GameCore.Inventory;
using GameCore.Logic;
using GameCore.Movement;
using GameCore.Physics;
using GameCore.Player;
using Godot;
namespace CryptonymThunder.Code.Factories;
public class ComponentFactory
{
private readonly Dictionary<Type, Func<Resource, IComponent>> _factories = new();
private readonly EffectFactory _effectFactory;
private readonly InteractionRequirementFactory _requirementFactory;
private readonly TriggerActionFactory _triggerActionFactory;
public ComponentFactory(EffectFactory effectFactory, InteractionRequirementFactory requirementFactory, TriggerActionFactory triggerActionFactory)
{
_effectFactory = effectFactory;
_requirementFactory = requirementFactory;
_triggerActionFactory = triggerActionFactory;
Register<AttributeComponentResource>(CreateAttributeComponent);
Register<WeaponComponentResource>(CreateWeaponComponent);
Register<ProjectileComponentResource>(CreateProjectileComponent);
Register<PositionComponentResource>(_ => new PositionComponent());
Register<VelocityComponentResource>(_ => new VelocityComponent());
Register<InputStateComponentResource>(_ => new InputStateComponent());
Register<PlayerComponentResource>(_ => new PlayerComponent());
Register<RotationComponentResource>(_ => new RotationComponent());
Register<CharacterStateComponentResource>(_ => new CharacterStateComponent());
Register<InventoryComponentResource>(_ => new InventoryComponent());
Register<PickupComponentResource>(CreatePickupComponent);
Register<EquipmentComponentResource>(_ => new EquipmentComponent());
Register<DoorComponentResource>(CreateDoorComponent);
Register<WorldIdComponentResource>(res => new WorldIdComponent(res.WorldId));
Register<ButtonComponentResource>(CreateButtonComponent);
Register<LogicSequenceComponentResource>(CreateLogicSequenceComponent);
}
public IComponent Create(Resource resource)
{
return _factories.TryGetValue(resource.GetType(), out var factory)
? factory(resource)
: null;
}
private void Register<TResource>(Func<TResource, IComponent> 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 fireCosts = weaponData.FireCosts
.Select(_effectFactory.Create)
.OfType<ICostEffect>()
.ToList();
var onFireEffects = weaponData.OnFireEffects.Select(_effectFactory.Create).ToList();
var onHitEffects = weaponData.OnHitEffects.Select(_effectFactory.Create).ToList();
return new WeaponComponent
{
FireRate = resource.WeaponData.FireRate,
FireCosts = fireCosts,
OnFireEffects = onFireEffects,
OnHitEffects = onHitEffects,
};
}
private ProjectileComponent CreateProjectileComponent(ProjectileComponentResource resource)
{
return new ProjectileComponent
{
Lifetime = resource.Lifetime,
};
}
private PickupComponent CreatePickupComponent(PickupComponentResource resource)
{
var onAcquireEffects = resource.OnAcquireEffects
.Select(_effectFactory.Create)
.ToList();
return new PickupComponent
{
ItemId = resource.ItemId,
Quantity = resource.Quantity,
IsInstantUse = resource.IsInstantUse,
OnAcquireEffects = onAcquireEffects,
};
}
private DoorComponent CreateDoorComponent(DoorComponentResource resource)
{
var component = new DoorComponent
{
CurrentState = resource.InitialState,
IsOneTimeUnlock = resource.IsOneTimeUnlock,
OpenSpeed = resource.OpenSpeed,
};
foreach (var reqResource in resource.Requirements)
{
var requirement = _requirementFactory.Create(reqResource);
if (requirement != null)
{
component.Requirements.Add(requirement);
}
}
return component;
}
private ButtonComponent CreateButtonComponent(ButtonComponentResource resource)
{
var component = new ButtonComponent
{
ChannelId = resource.ChannelId,
IsToggle = resource.IsToggle,
IsOneTimeUse = resource.IsOneTimeUse,
IsPressed = false,
HasBeenUsed = false,
};
foreach (var reqResource in resource.Requirements)
{
var requirement = _requirementFactory.Create(reqResource);
if (requirement != null)
{
component.Requirements.Add(requirement);
}
}
return component;
}
private LogicSequenceComponent CreateLogicSequenceComponent(LogicSequenceComponentResource resource)
{
var component = new LogicSequenceComponent
{
RequiredChannels = resource.RequiredChannels.ToList(),
IsOneTimeTrigger = resource.IsOneTimeTrigger,
};
foreach (var actionResource in resource.OnCompleteActions)
{
var action = _triggerActionFactory.Create(actionResource);
if (action != null)
{
component.OnCompleteActions.Add(action);
}
}
return component;
}
}