Files
crystall-punk-14/Content.Shared/_CP14/MagicEnergy/CP14SharedMagicEnergySystem.cs
Red 4debb114e5 Magic system refactor part 1 (#1709)
* Refactor pacified block logic to action system

Moved pacified block functionality from magic spell components to the new CP14ActionSystem and related components. Removed CP14MagicEffectPacifiedBlockComponent and its logic, and introduced CP14ActionDangerousComponent for handling pacified checks. Updated examine and checks logic to use the new action-based components, improving separation of concerns between magic and action systems.

* finish pacified

* mobtargetstate refactor

* skillpoint cost refactor

* somaticAspect refactor

* material cost refactor

* mana cost now

* stamina cost

* SSD + verbal aspect

* religion

* music tool refactor

* vampire

* get rid of this event

* manacost refac

* Remove magicType field from spell definitions

Eliminated the 'magicType' property from all CP14MagicEffect components in spell YAML files across Electric, Fire, Life, Light, and Water categories. This streamlines spell configuration and may reflect a change in how magic types are handled in the system.

* Remove mana cost reduction effects from skill tiers

Eliminated the ModifyManacost effects from tier 2 and tier 3 skills in electromancy, healing, hydrosophistry, illusion, and pyrokinetic. This change standardizes skill progression and may be part of a balance update to mana cost mechanics.

* comment out T3 tiers

* namespace refactor

* fix hands
2025-08-25 20:40:10 +03:00

235 lines
7.6 KiB
C#

using Content.Shared._CP14.MagicEnergy.Components;
using Content.Shared._CP14.MagicEssence;
using Content.Shared.Alert;
using Content.Shared.Audio;
using Content.Shared.Examine;
using Content.Shared.FixedPoint;
using Content.Shared.Rejuvenate;
using Content.Shared.Rounding;
namespace Content.Shared._CP14.MagicEnergy;
public abstract class CP14SharedMagicEnergySystem : EntitySystem
{
[Dependency] private readonly AlertsSystem _alerts = default!;
[Dependency] private readonly SharedAmbientSoundSystem _ambient = default!;
public override void Initialize()
{
SubscribeLocalEvent<CP14MagicEnergyContainerComponent, ComponentStartup>(OnComponentStartup);
SubscribeLocalEvent<CP14MagicEnergyContainerComponent, ComponentShutdown>(OnComponentShutdown);
SubscribeLocalEvent<CP14MagicEnergyContainerComponent, RejuvenateEvent>(OnRejuvenate);
SubscribeLocalEvent<CP14MagicEnergyExaminableComponent, ExaminedEvent>(OnExamined);
SubscribeLocalEvent<CP14MagicEnergyAmbientSoundComponent, CP14SlotCrystalPowerChangedEvent>(OnSlotPowerChanged);
}
private void OnRejuvenate(Entity<CP14MagicEnergyContainerComponent> ent, ref RejuvenateEvent args)
{
ChangeEnergy((ent, ent.Comp), ent.Comp.MaxEnergy - ent.Comp.Energy, out var deltaEnergy, out var overloadEnergy, true);
}
private void OnComponentStartup(Entity<CP14MagicEnergyContainerComponent> ent, ref ComponentStartup args)
{
UpdateMagicAlert(ent);
}
private void OnComponentShutdown(Entity<CP14MagicEnergyContainerComponent> ent, ref ComponentShutdown args)
{
if (ent.Comp.MagicAlert is null)
return;
_alerts.ClearAlert(ent, ent.Comp.MagicAlert.Value);
}
private void OnExamined(Entity<CP14MagicEnergyExaminableComponent> ent, ref ExaminedEvent args)
{
if (!TryComp<CP14MagicEnergyContainerComponent>(ent, out var magicContainer))
return;
if (!args.IsInDetailsRange)
return;
args.PushMarkup(GetEnergyExaminedText((ent, magicContainer)));
}
private void OnSlotPowerChanged(Entity<CP14MagicEnergyAmbientSoundComponent> ent, ref CP14SlotCrystalPowerChangedEvent args)
{
_ambient.SetAmbience(ent, args.Powered);
}
private void UpdateMagicAlert(Entity<CP14MagicEnergyContainerComponent> ent)
{
if (ent.Comp.MagicAlert is null)
return;
var level = ContentHelpers.RoundToLevels(
MathF.Max(0f, (float) ent.Comp.Energy),
(float) ent.Comp.MaxEnergy,
_alerts.GetMaxSeverity(ent.Comp.MagicAlert.Value));
_alerts.ShowAlert(ent, ent.Comp.MagicAlert.Value, (short) level);
}
public void ChangeEnergy(Entity<CP14MagicEnergyContainerComponent?> ent,
FixedPoint2 energy,
out FixedPoint2 deltaEnergy,
out FixedPoint2 overloadEnergy,
bool safe = false)
{
deltaEnergy = 0;
overloadEnergy = 0;
if (!Resolve(ent, ref ent.Comp, false))
return;
if (!safe)
{
// Overload
if (ent.Comp.Energy + energy > ent.Comp.MaxEnergy && ent.Comp.UnsafeSupport)
{
overloadEnergy = ent.Comp.Energy + energy - ent.Comp.MaxEnergy;
RaiseLocalEvent(ent, new CP14MagicEnergyOverloadEvent(overloadEnergy));
}
// Burn out
if (ent.Comp.Energy + energy < 0 && ent.Comp.UnsafeSupport)
{
overloadEnergy = ent.Comp.Energy + energy;
RaiseLocalEvent(ent, new CP14MagicEnergyBurnOutEvent(-energy - ent.Comp.Energy));
}
}
var oldEnergy = ent.Comp.Energy;
var newEnergy = Math.Clamp((float) ent.Comp.Energy + (float) energy, 0, (float) ent.Comp.MaxEnergy);
deltaEnergy = newEnergy - oldEnergy;
ent.Comp.Energy = newEnergy;
Dirty(ent);
if (oldEnergy != newEnergy)
RaiseLocalEvent(ent, new CP14MagicEnergyLevelChangeEvent(oldEnergy, newEnergy, ent.Comp.MaxEnergy));
UpdateMagicAlert((ent, ent.Comp));
}
/// <summary>
/// Set energy to 0
/// </summary>
public void ClearEnergy(Entity<CP14MagicEnergyContainerComponent?> ent)
{
if (!Resolve(ent, ref ent.Comp, false))
return;
ChangeEnergy(ent, -ent.Comp.Energy, out _, out _);
}
public void TransferEnergy(Entity<CP14MagicEnergyContainerComponent?> sender,
Entity<CP14MagicEnergyContainerComponent?> receiver,
FixedPoint2 energy,
out FixedPoint2 deltaEnergy,
out FixedPoint2 overloadEnergy,
bool safe = false)
{
deltaEnergy = 0;
overloadEnergy = 0;
if (!Resolve(sender, ref sender.Comp) || !Resolve(receiver, ref receiver.Comp))
return;
var transferEnergy = energy;
//We check how much space is left in the container so as not to overload it, but only if it does not support overloading
if (!receiver.Comp.UnsafeSupport || safe)
{
var freeSpace = receiver.Comp.MaxEnergy - receiver.Comp.Energy;
transferEnergy = FixedPoint2.Min(freeSpace, energy);
}
ChangeEnergy(sender, -transferEnergy, out var change, out var overload, safe);
ChangeEnergy(receiver , -(change + overload), out deltaEnergy, out overloadEnergy, safe);
}
public bool HasEnergy(EntityUid uid, FixedPoint2 energy, CP14MagicEnergyContainerComponent? component = null, bool safe = false)
{
if (!Resolve(uid, ref component))
return false;
if (!safe && component.UnsafeSupport)
return true;
return component.Energy >= energy;
}
public string GetEnergyExaminedText(Entity<CP14MagicEnergyContainerComponent> ent)
{
var power = (int) (ent.Comp.Energy / ent.Comp.MaxEnergy * 100);
// TODO: customization for examined
var color = "#3fc488";
if (power < 66)
color = "#f2a93a";
if (power < 33)
color = "#c23030";
return Loc.GetString("cp14-magic-energy-scan-result",
("item", MetaData(ent).EntityName),
("power", power),
("color", color));
}
public void ChangeMaximumEnergy(Entity<CP14MagicEnergyContainerComponent?> ent, FixedPoint2 energy)
{
if (!Resolve(ent, ref ent.Comp, false))
return;
ent.Comp.MaxEnergy += energy;
ChangeEnergy(ent, energy, out _, out _);
}
}
/// <summary>
/// It's triggered when the energy change in MagicEnergyContainer
/// </summary>
public sealed class CP14MagicEnergyLevelChangeEvent : EntityEventArgs
{
public readonly FixedPoint2 OldValue;
public readonly FixedPoint2 NewValue;
public readonly FixedPoint2 MaxValue;
public CP14MagicEnergyLevelChangeEvent(FixedPoint2 oldValue, FixedPoint2 newValue, FixedPoint2 maxValue)
{
OldValue = oldValue;
NewValue = newValue;
MaxValue = maxValue;
}
}
/// <summary>
/// It's triggered when more energy enters the MagicEnergyContainer than it can hold.
/// </summary>
public sealed class CP14MagicEnergyOverloadEvent : EntityEventArgs
{
public readonly FixedPoint2 OverloadEnergy;
public CP14MagicEnergyOverloadEvent(FixedPoint2 overloadEnergy)
{
OverloadEnergy = overloadEnergy;
}
}
/// <summary>
/// It's triggered they something try to get energy out of MagicEnergyContainer that is lacking there.
/// </summary>
public sealed class CP14MagicEnergyBurnOutEvent : EntityEventArgs
{
public readonly FixedPoint2 BurnOutEnergy;
public CP14MagicEnergyBurnOutEvent(FixedPoint2 burnOutEnergy)
{
BurnOutEnergy = burnOutEnergy;
}
}