Ну оно работает

This commit is contained in:
Tornado Tech
2024-05-03 20:27:12 +10:00
parent 765d226a9d
commit a0a2e8fabf
16 changed files with 123 additions and 203 deletions

View File

@@ -0,0 +1,16 @@
using Robust.Shared.Prototypes;
namespace Content.Server._CP14.Magic;
[Prototype("CPMagicEffect")]
public sealed partial class CPMagicEffectPrototype : IPrototype
{
[IdDataField]
public string ID { get; } = string.Empty;
[DataField]
public ComponentRegistry Components = new();
[DataField]
public float Complexity = 1f;
}

View File

@@ -0,0 +1,15 @@
using Robust.Shared.Prototypes;
namespace Content.Server._CP14.Magic;
[RegisterComponent]
public sealed partial class CPMagicSpellContainerComponent : Component
{
public readonly EntProtoId BaseSpellEffectEntity = "CPBaseSpellEntity";
[DataField, ViewVariables(VVAccess.ReadWrite)]
public List<ProtoId<CPMagicEffectPrototype>> Effects = new();
[DataField, ViewVariables(VVAccess.ReadWrite)]
public float MaximumCompleteness = 1f;
}

View File

@@ -0,0 +1,64 @@
using Content.Server.Popups;
using Content.Shared.Verbs;
using Robust.Shared.Prototypes;
namespace Content.Server._CP14.Magic;
public sealed class CPMagicSpellContainerSystem : EntitySystem
{
[Dependency] private readonly IPrototypeManager _prototype = default!;
[Dependency] private readonly PopupSystem _popup = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<CPMagicSpellContainerComponent, GetVerbsEvent<AlternativeVerb>>(OnGetVerb);
}
private void OnGetVerb(Entity<CPMagicSpellContainerComponent> container, ref GetVerbsEvent<AlternativeVerb> args)
{
var user = args.User;
args.Verbs.Add(new AlternativeVerb
{
Text = "cast",
Disabled = container.Comp.Effects.Count == 0,
Priority = 10,
Act = () =>
{
Cast(container, user);
}
});
}
public void Cast(Entity<CPMagicSpellContainerComponent> container, EntityUid caster)
{
var effectPrototypes = new List<CPMagicEffectPrototype>();
var complexity = 0f;
foreach (var effectId in container.Comp.Effects)
{
if (!_prototype.TryIndex(effectId, out var prototype))
{
_popup.PopupEntity("Fuck!", container);
return;
}
complexity += prototype.Complexity;
effectPrototypes.Add(prototype);
}
if (complexity > container.Comp.MaximumCompleteness)
{
_popup.PopupEntity("Too much complicated", container);
return;
}
var entity = Spawn(container.Comp.BaseSpellEffectEntity, Transform(container).Coordinates);
foreach (var effect in effectPrototypes)
{
EntityManager.AddComponents(entity, effect.Components);
}
}
}

View File

@@ -1,10 +0,0 @@
using Robust.Shared.Prototypes;
namespace Content.Server._CP14.Magic.Container;
[RegisterComponent]
public sealed partial class MagicSpellContainerComponent : Component
{
[DataField]
public List<ProtoId<MagicSpellPrototype>> Spells = new();
}

View File

@@ -1,11 +0,0 @@
namespace Content.Server._CP14.Magic.Container;
public sealed class MagickSpellContainerSystem : EntitySystem
{
[Dependency] private readonly MagicSpellSystem _magicSpell = default!;
public void CastSpell(Entity<MagicSpellContainerComponent> container)
{
_magicSpell.Cast(container, container.Comp.Spells);
}
}

View File

@@ -1,20 +0,0 @@
namespace Content.Server._CP14.Magic;
[Serializable, DataDefinition]
public abstract partial class MagicSpell
{
protected readonly IEntityManager EntityManager;
public MagicSpell()
{
EntityManager = IoCManager.Resolve<IEntityManager>();
}
[DataField]
public virtual int BaseCost { get; set; } = 10;
public virtual void Modify(MagicSpellContext context)
{
context.Cost += BaseCost;
}
}

View File

@@ -1,14 +0,0 @@
using Robust.Shared.Map;
namespace Content.Server._CP14.Magic;
public sealed class MagicSpellContext
{
public EntityUid Caster;
public MapCoordinates SourcePoint;
public MapCoordinates TargetPoint;
public int MaxCost = 100;
public int Cost;
}

View File

@@ -1,13 +0,0 @@
using Robust.Shared.Prototypes;
namespace Content.Server._CP14.Magic;
[Prototype("magicSpell")]
public sealed class MagicSpellPrototype : IPrototype
{
[IdDataField]
public string ID { get; } = string.Empty;
[DataField]
public required MagicSpell Action;
}

View File

@@ -1,60 +0,0 @@
using System.Runtime.CompilerServices;
using Robust.Server.GameObjects;
using Robust.Shared.Prototypes;
namespace Content.Server._CP14.Magic;
public sealed class MagicSpellSystem : EntitySystem
{
[Robust.Shared.IoC.Dependency] private readonly IPrototypeManager _prototype = default!;
[Robust.Shared.IoC.Dependency] private readonly TransformSystem _transform = default!;
public IReadOnlyDictionary<ProtoId<MagicSpellPrototype>, MagicSpellPrototype> Spells => _spells;
private readonly Dictionary<ProtoId<MagicSpellPrototype>, MagicSpellPrototype> _spells = new();
public override void Initialize()
{
base.Initialize();
Enumerate();
_prototype.PrototypesReloaded += OnProtoReload;
}
public void Cast(EntityUid caster, IReadOnlyList<ProtoId<MagicSpellPrototype>> spells)
{
var casterPosition = _transform.GetMapCoordinates(caster);
var context = new MagicSpellContext
{
SourcePoint = casterPosition,
TargetPoint = casterPosition
};
foreach (var spellProto in spells)
{
if (!Spells.TryGetValue(spellProto, out var spell))
continue;
spell.Action.Modify(context);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void Enumerate()
{
var prototypes = _prototype.EnumeratePrototypes<MagicSpellPrototype>();
foreach (var prototype in prototypes)
{
_spells.Add(prototype.ID, prototype);
}
}
private void OnProtoReload(PrototypesReloadedEventArgs args)
{
if (!args.WasModified<MagicSpellPrototype>())
return;
Enumerate();
}
}

View File

@@ -1,44 +0,0 @@
using Content.Shared.Mobs.Components;
using Robust.Server.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Random;
namespace Content.Server._CP14.Magic.Spells;
[Serializable, DataDefinition]
public abstract partial class MagicSpellPointRandomMob : MagicSpell
{
private readonly EntityLookupSystem _entityLookupSystem;
private readonly IRobustRandom _random;
private readonly TransformSystem _transform;
[DataField]
public virtual float Range { get; set; } = 5f;
[DataField]
public override int BaseCost { get; set; } = 50;
public MagicSpellPointRandomMob()
{
_entityLookupSystem = EntityManager.System<EntityLookupSystem>();
_transform = EntityManager.System<TransformSystem>();
_random = IoCManager.Resolve<IRobustRandom>();
}
public override void Modify(MagicSpellContext context)
{
base.Modify(context);
var targets = _entityLookupSystem.GetEntitiesInRange<MobStateComponent>(context.SourcePoint, Range);
if (targets.Count == 0)
return;
var target = _random.Pick(targets);
var coordinates = _transform.GetMapCoordinates(target);
ApplyCoordinates(context, coordinates);
}
public abstract void ApplyCoordinates(MagicSpellContext context, MapCoordinates coordinates);
}

View File

@@ -1,12 +0,0 @@
using Robust.Shared.Map;
namespace Content.Server._CP14.Magic.Spells.SourcePoint;
[Serializable, DataDefinition]
public sealed partial class MagicSpellSourcePointRandomMob : MagicSpellPointRandomMob
{
public override void ApplyCoordinates(MagicSpellContext context, MapCoordinates coordinates)
{
context.SourcePoint = coordinates;
}
}

View File

@@ -1,12 +0,0 @@
using Robust.Shared.Map;
namespace Content.Server._CP14.Magic.Spells.TargetPoint;
[Serializable, DataDefinition]
public sealed partial class MagicSpellTargetPointRandomMob : MagicSpellPointRandomMob
{
public override void ApplyCoordinates(MagicSpellContext context, MapCoordinates coordinates)
{
context.TargetPoint = coordinates;
}
}

View File

@@ -0,0 +1,13 @@
- type: CPMagicEffect
id: CPPointLight
components:
- type: PointLight
radius: 10
energy: 10
color: "#ffffff"
- type: CPMagicEffect
id: CPPaintPointLightRed
components:
- type: PointLight
color: "#ff0000"

View File

@@ -0,0 +1,5 @@
- type: entity
id: CPBaseSpellEntity
name: magic entity
noSpawn: true

View File

@@ -0,0 +1,10 @@
- type: entity
parent: BaseItem
id: CPBaseMagicCharm
name: charm
description: The simplest storage for your spell
components:
- type: CPMagicSpellContainer
effects:
- CPPointLight
- CPPaintPointLightRed

View File

@@ -1,7 +0,0 @@
- type: magicSpell
id: sourcePointRandomMob
action:
!type:MagicSpellSourcePointRandomMob
range: 5
baseCost: 25