Energy crystal (#243)

* init magic container system

* charging and discharging

* add energy regenerator

* thaumaturgy glasses, scanning energy

* add energy quartz prorotypes and sprites

* light power controller

* commit special for _des

* simple normalizer crystal slot

* YEEEEEEE BOIII, examined crystalls inside things

* кристал теперь видно, когда он вставлен в стабилизатор

* TryUseCharge приборами

* hello deserty, how are you doing?

* rename regenerator to EnergyDraw, allow draw from slot

* normalizer жрет magic energy файналли

* Update normalizer.yml

* visual polishing

* Update crystal.yml
This commit is contained in:
Ed
2024-06-13 22:55:20 +03:00
committed by GitHub
parent d1af83c72a
commit 0211a50581
39 changed files with 794 additions and 10 deletions

View File

@@ -1,3 +1,7 @@
using Content.Server._CP14.MagicEnergy;
using Content.Server.Audio;
using Content.Shared._CP14.MagicEnergy.Components;
using Content.Shared.Audio;
using Content.Shared.Chemistry.Components.SolutionManager;
using Content.Shared.Chemistry.EntitySystems;
using Content.Shared.Chemistry.Reagent;
@@ -12,18 +16,35 @@ public sealed partial class CP14SolutionNormalizerSystem : EntitySystem
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly SharedSolutionContainerSystem _solutionContainer = default!;
[Dependency] private readonly CP14MagicEnergyCrystalSlotSystem _magicSlot = default!;
[Dependency] private readonly AmbientSoundSystem _ambient = default!;
public override void Initialize()
{
SubscribeLocalEvent<CP14SolutionNormalizerComponent,CP14SlotCrystalPowerChangedEvent>(OnSlotPowerChanged);
}
private void OnSlotPowerChanged(Entity<CP14SolutionNormalizerComponent> ent, ref CP14SlotCrystalPowerChangedEvent args)
{
if (TryComp<AmbientSoundComponent>(ent, out var ambient))
{
_ambient.SetAmbience(ent, args.Powered);
}
}
public override void Update(float frameTime)
{
base.Update(frameTime);
var query = EntityQueryEnumerator<CP14SolutionNormalizerComponent, SolutionContainerManagerComponent>();
while (query.MoveNext(out var uid, out var normalizer, out var containerManager))
{
if (_timing.CurTime <= normalizer.NextUpdateTime)
continue;
if (!_magicSlot.HasEnergy(uid, 1))
continue;
normalizer.NextUpdateTime = _timing.CurTime + normalizer.UpdateFrequency;
var solutionManager = new Entity<SolutionContainerManagerComponent?>(uid, containerManager);

View File

@@ -0,0 +1,150 @@
using System.Diagnostics.CodeAnalysis;
using Content.Shared._CP14.MagicEnergy;
using Content.Shared._CP14.MagicEnergy.Components;
using Content.Shared.Containers.ItemSlots;
using Content.Shared.Examine;
using Content.Shared.FixedPoint;
using Content.Shared.Popups;
using Robust.Shared.Containers;
namespace Content.Server._CP14.MagicEnergy;
public sealed partial class CP14MagicEnergyCrystalSlotSystem : SharedCP14MagicEnergyCrystalSlotSystem
{
[Dependency] private readonly ItemSlotsSystem _itemSlots = default!;
[Dependency] private readonly CP14MagicEnergySystem _magicEnergy = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] private readonly SharedContainerSystem _container = default!;
public override void Initialize()
{
SubscribeLocalEvent<CP14MagicEnergyCrystalComponent, CP14MagicEnergyLevelChangeEvent>(OnEnergyChanged);
SubscribeLocalEvent<CP14MagicEnergyCrystalSlotComponent, ExaminedEvent>(OnExamined);
SubscribeLocalEvent<CP14MagicEnergyCrystalSlotComponent, CP14SlotCrystalChangedEvent>(OnCrystalChanged);
}
private void OnCrystalChanged(Entity<CP14MagicEnergyCrystalSlotComponent> ent, ref CP14SlotCrystalChangedEvent args)
{
var realPowered = TryGetEnergyCrystalFromSlot(ent, out var energyEnt, out var energyComp);
if (energyComp != null)
realPowered = energyComp.Energy > 0;
if (ent.Comp.Powered != realPowered)
{
ent.Comp.Powered = realPowered;
_appearance.SetData(ent, CP14MagicSlotVisuals.Powered, realPowered);
RaiseLocalEvent(ent, new CP14SlotCrystalPowerChangedEvent(realPowered));
}
}
private void OnEnergyChanged(Entity<CP14MagicEnergyCrystalComponent> crystal, ref CP14MagicEnergyLevelChangeEvent args)
{
if (_container.TryGetContainingContainer(crystal, out var container)
&& TryComp(container.Owner, out CP14MagicEnergyCrystalSlotComponent? slot)
&& _itemSlots.TryGetSlot(container.Owner, slot.SlotId, out var itemSlot))
{
if (itemSlot.Item == crystal)
{
RaiseLocalEvent(container.Owner, new CP14SlotCrystalChangedEvent(false));
}
}
}
private void OnExamined(Entity<CP14MagicEnergyCrystalSlotComponent> ent, ref ExaminedEvent args)
{
if (!TryGetEnergyCrystalFromSlot(ent, out var crystalUid, out var crystalComp, ent.Comp))
return;
var scanEvent = new CP14MagicEnergyScanEvent();
RaiseLocalEvent(args.Examiner, scanEvent);
if (!scanEvent.CanScan)
return;
args.PushMarkup(_magicEnergy.GetEnergyExaminedText(crystalUid.Value, crystalComp));
}
public bool TryGetEnergyCrystalFromSlot(EntityUid uid,
[NotNullWhen(true)] out CP14MagicEnergyContainerComponent? energyComp,
CP14MagicEnergyCrystalSlotComponent? component = null)
{
return TryGetEnergyCrystalFromSlot(uid, out _, out energyComp, component);
}
public bool TryGetEnergyCrystalFromSlot(EntityUid uid,
[NotNullWhen(true)] out EntityUid? energyEnt,
[NotNullWhen(true)] out CP14MagicEnergyContainerComponent? energyComp,
CP14MagicEnergyCrystalSlotComponent? component = null)
{
if (!Resolve(uid, ref component, false))
{
energyEnt = null;
energyComp = null;
return false;
}
if (_itemSlots.TryGetSlot(uid, component.SlotId, out ItemSlot? slot))
{
energyEnt = slot.Item;
return TryComp(slot.Item, out energyComp);
}
energyEnt = null;
energyComp = null;
return false;
}
public bool HasEnergy(EntityUid uid,
FixedPoint2 energy,
CP14MagicEnergyCrystalSlotComponent? component = null,
EntityUid? user = null)
{
if (!TryGetEnergyCrystalFromSlot(uid, out var energyEnt, out var energyComp, component))
{
if (user != null)
_popup.PopupEntity(Loc.GetString("cp14-magic-energy-no-crystal"), uid,user.Value);
return false;
}
if (energyComp.Energy < energy)
{
if (user != null)
_popup.PopupEntity(Loc.GetString("cp14-magic-energy-insufficient"), uid, user.Value);
return false;
}
return true;
}
public bool TryUseEnergy(EntityUid uid,
FixedPoint2 energy,
CP14MagicEnergyCrystalSlotComponent? component = null,
EntityUid? user = null,
bool safe = false)
{
if (!TryGetEnergyCrystalFromSlot(uid, out var energyEnt, out var energyComp, component))
{
if (user != null)
_popup.PopupEntity(Loc.GetString("cp14-magic-energy-no-crystal"), uid,user.Value);
return false;
}
if (_magicEnergy.TryConsumeEnergy(energyEnt.Value, energy, energyComp, safe))
{
if (user != null)
_popup.PopupEntity(
Loc.GetString(safe ? "cp14-magic-energy-insufficient" : "cp14-magic-energy-insufficient-unsafe"),
uid,
user.Value);
return false;
}
return true;
}
}

View File

@@ -0,0 +1,152 @@
using Content.Server._CP14.MagicEnergy.Components;
using Content.Shared._CP14.MagicEnergy;
using Content.Shared._CP14.MagicEnergy.Components;
using Content.Shared.Examine;
using Content.Shared.FixedPoint;
using Content.Shared.Inventory;
using Robust.Server.GameObjects;
using Robust.Shared.Timing;
namespace Content.Server._CP14.MagicEnergy;
public sealed partial class CP14MagicEnergySystem : SharedCP14MagicEnergySystem
{
[Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly PointLightSystem _light = default!;
[Dependency] private readonly CP14MagicEnergyCrystalSlotSystem _magicSlot = default!;
public override void Initialize()
{
SubscribeLocalEvent<CP14MagicEnergyDrawComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<CP14MagicEnergyPointLightControllerComponent, CP14MagicEnergyLevelChangeEvent>(OnEnergyChange);
SubscribeLocalEvent<CP14MagicEnergyExaminableComponent, ExaminedEvent>(OnExamined);
SubscribeLocalEvent<CP14MagicEnergyScannerComponent, CP14MagicEnergyScanEvent>(OnMagicScanAttempt);
SubscribeLocalEvent<CP14MagicEnergyScannerComponent, InventoryRelayedEvent<CP14MagicEnergyScanEvent>>((e, c, ev) => OnMagicScanAttempt(e, c, ev.Args));
}
private void OnEnergyChange(Entity<CP14MagicEnergyPointLightControllerComponent> ent, ref CP14MagicEnergyLevelChangeEvent args)
{
if (!TryComp<PointLightComponent>(ent, out var light))
return;
var lightEnergy = MathHelper.Lerp(ent.Comp.MinEnergy, ent.Comp.MaxEnergy, (float)(args.NewValue / args.MaxValue));
_light.SetEnergy(ent, lightEnergy, light);
}
private void OnMapInit(Entity<CP14MagicEnergyDrawComponent> ent, ref MapInitEvent args)
{
ent.Comp.NextUpdateTime = _gameTiming.CurTime + TimeSpan.FromSeconds(ent.Comp.Delay);
}
private void OnMagicScanAttempt(EntityUid uid, CP14MagicEnergyScannerComponent component, CP14MagicEnergyScanEvent args)
{
args.CanScan = true;
}
private void OnExamined(Entity<CP14MagicEnergyExaminableComponent> ent, ref ExaminedEvent args)
{
if (!TryComp<CP14MagicEnergyContainerComponent>(ent, out var magicContainer))
return;
var scanEvent = new CP14MagicEnergyScanEvent();
RaiseLocalEvent(args.Examiner, scanEvent);
if (!scanEvent.CanScan)
return;
args.PushMarkup(GetEnergyExaminedText(ent, magicContainer));
}
public override void Update(float frameTime)
{
base.Update(frameTime);
var query = EntityQueryEnumerator<CP14MagicEnergyDrawComponent, CP14MagicEnergyContainerComponent>();
while (query.MoveNext(out var uid, out var draw, out var magicContainer))
{
if (draw.NextUpdateTime >= _gameTiming.CurTime)
continue;
draw.NextUpdateTime = _gameTiming.CurTime + TimeSpan.FromSeconds(draw.Delay);
ChangeEnergy(uid, magicContainer, draw.Energy, safe: draw.Safe);
}
var query2 = EntityQueryEnumerator<CP14MagicEnergyDrawComponent, CP14MagicEnergyCrystalSlotComponent>();
while (query2.MoveNext(out var uid, out var draw, out var slot))
{
if (!draw.Enable)
continue;
if (draw.NextUpdateTime >= _gameTiming.CurTime)
continue;
draw.NextUpdateTime = _gameTiming.CurTime + TimeSpan.FromSeconds(draw.Delay);
if (!_magicSlot.TryGetEnergyCrystalFromSlot(uid, out var energyEnt, out var energyComp))
continue;
ChangeEnergy(energyEnt.Value, energyComp, draw.Energy, draw.Safe);
}
}
public bool TryConsumeEnergy(EntityUid uid, FixedPoint2 energy, CP14MagicEnergyContainerComponent? component = null, bool safe = false)
{
if (!Resolve(uid, ref component))
return false;
if (energy <= 0)
return true;
// Attempting to absorb more energy than is contained in the carrier will still waste all the energy
if (component.Energy < energy)
{
ChangeEnergy(uid, component, -component.Energy);
return false;
}
ChangeEnergy(uid, component, -energy, safe);
return true;
}
public void ChangeEnergy(EntityUid uid, CP14MagicEnergyContainerComponent component, FixedPoint2 energy, bool safe = false)
{
if (!safe)
{
//Overload
if (component.Energy + energy > component.MaxEnergy)
{
RaiseLocalEvent(uid, new CP14MagicEnergyOverloadEvent()
{
OverloadEnergy = (component.Energy + energy) - component.MaxEnergy,
});
}
//Burn out
if (component.Energy + energy < 0)
{
RaiseLocalEvent(uid, new CP14MagicEnergyBurnOutEvent()
{
BurnOutEnergy = -energy - component.Energy
});
}
}
var oldEnergy = component.Energy;
var newEnergy = Math.Clamp((float)component.Energy + (float)energy, 0, (float)component.MaxEnergy);
component.Energy = newEnergy;
if (oldEnergy != newEnergy)
{
RaiseLocalEvent(uid, new CP14MagicEnergyLevelChangeEvent()
{
OldValue = component.Energy,
NewValue = newEnergy,
MaxValue = component.MaxEnergy,
});
}
}
}

View File

@@ -0,0 +1,34 @@
using Content.Shared.FixedPoint;
namespace Content.Server._CP14.MagicEnergy.Components;
/// <summary>
/// Allows you to restore or deplete the magical energy in the item
/// </summary>
[RegisterComponent, Access(typeof(CP14MagicEnergySystem))]
public sealed partial class CP14MagicEnergyDrawComponent : Component
{
[DataField]
public bool Enable = true;
[DataField]
public FixedPoint2 Energy = 1f;
/// <summary>
/// If not safe, restoring or drawing power across boundaries call dangerous events, that may destroy crystals
/// </summary>
[DataField]
public bool Safe = true;
/// <summary>
/// how often objects will try to change magic energy. In Seconds
/// </summary>
[DataField]
public float Delay = 5f;
/// <summary>
/// the time of the next magic energy change
/// </summary>
[DataField]
public TimeSpan NextUpdateTime { get; set; } = TimeSpan.Zero;
}

View File

@@ -1,3 +1,4 @@
using Content.Shared._CP14.MagicEnergy;
using Content.Shared.Chemistry;
using Content.Shared.Damage;
using Content.Shared.Electrocution;
@@ -36,6 +37,7 @@ public partial class InventorySystem
SubscribeLocalEvent<InventoryComponent, GetEyeProtectionEvent>(RelayInventoryEvent);
SubscribeLocalEvent<InventoryComponent, GetBlurEvent>(RelayInventoryEvent);
SubscribeLocalEvent<InventoryComponent, SolutionScanEvent>(RelayInventoryEvent);
SubscribeLocalEvent<InventoryComponent, CP14MagicEnergyScanEvent>(RelayInventoryEvent); //CP14 Magic scanning
// ComponentActivatedClientSystems
SubscribeLocalEvent<InventoryComponent, RefreshEquipmentHudEvent<ShowJobIconsComponent>>(RelayInventoryEvent);

View File

@@ -0,0 +1,16 @@
using Content.Shared.FixedPoint;
namespace Content.Shared._CP14.MagicEnergy.Components;
/// <summary>
/// Allows an item to store magical energy within itself.
/// </summary>
[RegisterComponent, Access(typeof(SharedCP14MagicEnergySystem))]
public sealed partial class CP14MagicEnergyContainerComponent : Component
{
[DataField]
public FixedPoint2 Energy = 0f;
[DataField]
public FixedPoint2 MaxEnergy = 100f;
}

View File

@@ -0,0 +1,9 @@
namespace Content.Shared._CP14.MagicEnergy.Components;
/// <summary>
/// allows the object to be inserted into CP14MagicEnergyCrystalSlot
/// </summary>
[RegisterComponent, Access(typeof(SharedCP14MagicEnergyCrystalSlotSystem))]
public sealed partial class CP14MagicEnergyCrystalComponent : Component
{
}

View File

@@ -0,0 +1,47 @@
using Robust.Shared.Serialization;
namespace Content.Shared._CP14.MagicEnergy.Components;
/// <summary>
/// Allows you to examine how much energy is in that object
/// </summary>
[RegisterComponent, Access(typeof(SharedCP14MagicEnergyCrystalSlotSystem))]
public sealed partial class CP14MagicEnergyCrystalSlotComponent : Component
{
[DataField(required: true)]
public string SlotId = string.Empty;
public bool Powered = false;
}
[Serializable, NetSerializable]
public enum CP14MagicSlotVisuals : byte
{
Inserted,
Powered
}
/// <summary>
/// Is called when the state of the crystal is changed: it is pulled out, inserted, or the amount of energy in it has changed.
/// </summary>
public sealed class CP14SlotCrystalChangedEvent : EntityEventArgs
{
public readonly bool Ejected;
public CP14SlotCrystalChangedEvent(bool ejected)
{
Ejected = ejected;
}
}
/// <summary>
/// Is called when the power status of the device changes.
/// </summary>
public sealed class CP14SlotCrystalPowerChangedEvent : EntityEventArgs
{
public readonly bool Powered;
public CP14SlotCrystalPowerChangedEvent(bool powered)
{
Powered = powered;
}
}

View File

@@ -0,0 +1,9 @@
namespace Content.Shared._CP14.MagicEnergy.Components;
/// <summary>
/// Allows you to examine how much energy is in that object
/// </summary>
[RegisterComponent, Access(typeof(SharedCP14MagicEnergySystem))]
public sealed partial class CP14MagicEnergyExaminableComponent : Component
{
}

View File

@@ -0,0 +1,16 @@
using Content.Shared.Inventory;
namespace Content.Shared._CP14.MagicEnergy.Components;
/// <summary>
/// Controls the strength of the PointLight component, depending on the amount of mana in the object
/// </summary>
[RegisterComponent, Access(typeof(SharedCP14MagicEnergySystem))]
public sealed partial class CP14MagicEnergyPointLightControllerComponent : Component
{
[DataField]
public float MaxEnergy = 1f;
[DataField]
public float MinEnergy = 0f;
}

View File

@@ -0,0 +1,11 @@
using Content.Shared.Inventory;
namespace Content.Shared._CP14.MagicEnergy.Components;
/// <summary>
/// Allows you to see how much magic energy is stored in objects
/// </summary>
[RegisterComponent, Access(typeof(SharedCP14MagicEnergySystem))]
public sealed partial class CP14MagicEnergyScannerComponent : Component
{
}

View File

@@ -0,0 +1,42 @@
using Content.Shared._CP14.MagicEnergy.Components;
using Content.Shared.Containers.ItemSlots;
using Robust.Shared.Containers;
namespace Content.Shared._CP14.MagicEnergy;
public partial class SharedCP14MagicEnergyCrystalSlotSystem : EntitySystem
{
[Dependency] private readonly ItemSlotsSystem _itemSlots = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<CP14MagicEnergyCrystalSlotComponent, EntInsertedIntoContainerMessage>(OnCrystalInserted);
SubscribeLocalEvent<CP14MagicEnergyCrystalSlotComponent, EntRemovedFromContainerMessage>(OnCrystalRemoved);
}
private void OnCrystalRemoved(Entity<CP14MagicEnergyCrystalSlotComponent> slot, ref EntRemovedFromContainerMessage args)
{
if (args.Container.ID != slot.Comp.SlotId)
return;
_appearance.SetData(slot, CP14MagicSlotVisuals.Inserted, false);
_appearance.SetData(slot, CP14MagicSlotVisuals.Powered, false);
RaiseLocalEvent(slot, new CP14SlotCrystalChangedEvent(true));
}
private void OnCrystalInserted(Entity<CP14MagicEnergyCrystalSlotComponent> slot, ref EntInsertedIntoContainerMessage args)
{
if (!slot.Comp.Initialized)
return;
if (args.Container.ID != slot.Comp.SlotId)
return;
_appearance.SetData(slot, CP14MagicSlotVisuals.Inserted, true);
RaiseLocalEvent(slot, new CP14SlotCrystalChangedEvent(false));
}
}

View File

@@ -0,0 +1,57 @@
using Content.Shared._CP14.MagicEnergy.Components;
using Content.Shared.Examine;
using Content.Shared.FixedPoint;
using Content.Shared.Inventory;
namespace Content.Shared._CP14.MagicEnergy;
public partial class SharedCP14MagicEnergySystem : EntitySystem
{
public string GetEnergyExaminedText(EntityUid uid, CP14MagicEnergyContainerComponent ent)
{
var power = (int)((ent.Energy / ent.MaxEnergy) * 100);
var color = "#3fc488";
if (power < 66)
color = "#f2a93a";
if (power < 33)
color = "#c23030";
return Loc.GetString("cp14-magic-energy-scan-result",
("item", MetaData(uid).EntityName),
("power", power),
("color", color));
}
}
/// <summary>
/// It's triggered when the energy change in MagicEnergyContainer
/// </summary>
public sealed class CP14MagicEnergyLevelChangeEvent : EntityEventArgs
{
public FixedPoint2 OldValue;
public FixedPoint2 NewValue;
public FixedPoint2 MaxValue;
}
/// <summary>
/// It's triggered when more energy enters the MagicEnergyContainer than it can hold.
/// </summary>
public sealed class CP14MagicEnergyOverloadEvent : EntityEventArgs
{
public FixedPoint2 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 FixedPoint2 BurnOutEnergy;
}
public sealed class CP14MagicEnergyScanEvent : EntityEventArgs, IInventoryRelayEvent
{
public bool CanScan;
public SlotFlags TargetSlots { get; } = SlotFlags.EYES;
}

Binary file not shown.

View File

@@ -21,4 +21,9 @@
- files: ["weatherWindy.ogg"]
license: "CC-BY-4.0"
copyright: 'by Benboncan of Freesound.org. Mixed from stereo to mono.'
source: "https://freesound.org/people/Benboncan/sounds/134699/"
source: "https://freesound.org/people/Benboncan/sounds/134699/"
- files: ["ambiAlchemy.ogg"]
license: "CC-BY-4.0"
copyright: 'by be-steele of Freesound.org.'
source: "https://freesound.org/people/be-steele/sounds/130753/"

Binary file not shown.

View File

@@ -31,4 +31,14 @@
- files: ["shovel_dig1.ogg", "shovel_dig2.ogg", "shovel_dig3.ogg", "shovel_dig4.ogg", "shovel_dig5.ogg"]
license: "CC0-1.0"
copyright: 'by Ali_6868 of Freesound.org. Cropped and mixed from stereo to mono.'
source: "https://freesound.org/people/Ali_6868/sounds/384361/"
source: "https://freesound.org/people/Ali_6868/sounds/384361/"
- files: ["crystal_eject.ogg", "crystal_insert.ogg"]
license: "CC-BY-4.0"
copyright: 'by Joachim_Berger of Freesound.org. Cropped by TheShuEd.'
source: "https://freesound.org/people/Joachim_Berger/sounds/660526/"
- files: ["normalizer_working.ogg"]
license: "CC0-1.0"
copyright: 'by craigsmith of Freesound.org. Cropped by TheShuEd.'
source: "https://freesound.org/people/craigsmith/sounds/438604/"

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,7 @@
cp14-magic-energy-scan-result = The {$item} is filled with [color={$color}]{$power}%[/color] magical energy
cp14-magic-energy-crystal-slot-name = Energy crystal
cp14-magic-energy-no-crystal = No energy crystal!
cp14-magic-energy-insufficient = Not enough energy!
cp14-magic-energy-insufficient-unsafe = Crystal cracks from lack of energy!

View File

@@ -0,0 +1,7 @@
cp14-magic-energy-scan-result = {$item} заполнен магической энергией на [color={$color}]{$power}%[/color]
cp14-magic-energy-crystal-slot-name = Энергокристалл
cp14-magic-energy-no-crystal = Отсутствует энергокристалл!
cp14-magic-energy-insufficient = Не достаточно энергии!
cp14-magic-energy-insufficient-unsafe = Кристалл трескается от нехватки энергии!

View File

@@ -60,3 +60,22 @@
sprite: _CP14/Clothing/Eyes/alchemy_glasses.rsi
- type: SolutionScanner
- type: entity
parent: CP14ClothingEyesBase
id: CP14ClothingEyesThaumaturgyGlasses
name: thaumaturgy glasses
description: Goggles that allow you to scan magical items and creatures to clearly see the amount of energy left in them.
components:
- type: Foldable
canFoldInsideContainer: true
unfoldVerbText: fold-flip-verb
foldVerbText: fold-flip-verb
- type: FoldableClothing
foldedEquippedPrefix: flipped
foldedHeldPrefix: flipped
- type: Sprite
sprite: _CP14/Clothing/Eyes/alchemy_glasses.rsi #TODO sprite
- type: Clothing
sprite: _CP14/Clothing/Eyes/alchemy_glasses.rsi
- type: CP14MagicEnergyScanner

View File

@@ -157,8 +157,8 @@
- type: entity
id: CP14QuartzShard
parent: BaseItem
name: quartz shard
description: a shard of once luminous crystal. Unfortunately, careless handling destroyed much of the potential.
name: rough quartz
description: a natural crystal that is a natural storage of magical energy. Its color reflects the quality of the crystal - the higher the emission spectrum, the higher the level of energy leakage.
components:
- type: Tag
tags:

View File

@@ -0,0 +1,78 @@
- type: entity
id: CP14EnergyCrystalBase
parent: BaseItem
abstract: true
description: Processed quartz crystals are excellent repositories of magical energy. And special connectors allow you to conveniently insert them into magical devices, turning them into energy batteries.
components:
- type: CP14MagicEnergyCrystal
- type: Item
size: Tiny
- type: Sprite
sprite: _CP14/Objects/Specific/Thaumaturgy/crystal.rsi
- type: CP14MagicEnergyContainer
- type: CP14MagicEnergyExaminable
- type: CP14MagicEnergyPointLightController
- type: entity
id: CP14EnergyCrystalSmall
parent: CP14EnergyCrystalBase
name: small energy crystal
suffix: Full
components:
- type: Sprite
layers:
- state: small1
shader: unshaded
map: ["random"]
- state: small_connector
- type: RandomSprite
available:
- random:
small1: ""
small2: ""
small3: ""
- type: CP14MagicEnergyContainer
energy: 30
maxEnergy: 30
- type: entity
id: CP14EnergyCrystalSmallEmpty
parent: CP14EnergyCrystalSmall
suffix: Empty
components:
- type: CP14MagicEnergyContainer
energy: 0
- type: entity
id: CP14EnergyCrystalMedium
parent: CP14EnergyCrystalBase
name: energy crystal
suffix: Full
components:
- type: PointLight
radius: 1.2
- type: Sprite
layers:
- state: medium1
shader: unshaded
map: ["random"]
- state: medium_connector
- type: RandomSprite
available:
- random:
medium1: ""
medium2: ""
medium3: ""
- type: CP14MagicEnergyContainer
energy: 100
maxEnergy: 100
- type: entity
id: CP14EnergyCrystalMediumEmpty
parent: CP14EnergyCrystalMedium
suffix: Empty
components:
- type: CP14MagicEnergyContainer
energy: 0

View File

@@ -1,7 +1,7 @@
- type: entity
id: CP14AlchemyNormalizer
parent: BaseStructureDynamic
name: solution stabilizer
name: solution normalizer
description: An alchemical device that removes fine precipitates from solutions, and stabilizes it for further work
placement:
mode: PlaceFree
@@ -14,13 +14,31 @@
offset: 0, 0.2
sprite: _CP14/Structures/Specific/Alchemy/normalizer.rsi
layers:
- state: rotate_back
- state: rotate_back_stop
map: ["poweredBack"]
- state: liq-1
map: ["enum.SolutionContainerLayers.Fill"]
visible: false
- state: base
- state: rotate_front
state: base
- state: rotate_front_stop
map: ["poweredFront"]
- state: crystal
shader: unshaded
map: ["crystal"]
visible: false
- type: GenericVisualizer
visuals:
enum.CP14MagicSlotVisuals.Inserted:
crystal:
True: { visible: true }
False: { visible: false }
enum.CP14MagicSlotVisuals.Powered:
poweredFront:
True: { state: rotate_front }
False: { state: rotate_front_stop }
poweredBack:
True: { state: rotate_back }
False: { state: rotate_back_stop }
- type: Fixtures
fixtures:
fix1:
@@ -48,7 +66,37 @@
solution: normalizer
- type: CP14SolutionNormalizer
solution: normalizer
- type: AmbientSound
enabled: false
range: 6
volume: -3
sound:
path: /Audio/_CP14/Ambience/normalizer_working.ogg
- type: Appearance
- type: SolutionContainerVisuals
maxFillLevels: 5
fillBaseName: liq-
fillBaseName: liq-
- type: CP14MagicEnergyDraw
energy: -0.2
delay: 1
- type: CP14MagicEnergyCrystalSlot
slotId: crystal_slot
- type: ContainerContainer
containers:
crystal_slot: !type:ContainerSlot
- type: ItemSlots
slots:
crystal_slot:
insertSound:
path: /Audio/_CP14/Items/crystal_insert.ogg
params:
variation: 0.05
ejectSound:
path: /Audio/_CP14/Items/crystal_eject.ogg
params:
variation: 0.05
ejectOnInteract: true
name: cp14-magic-energy-crystal-slot-name
whitelist:
components:
- CP14MagicEnergyCrystal

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 276 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 267 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 B

View File

@@ -0,0 +1,35 @@
{
"version": 1,
"size": {
"x": 32,
"y": 32
},
"license": "CC-BY-SA-3.0",
"copyright": "Created by TheShuEd (Github) for CrystallPunk14",
"states": [
{
"name": "small1"
},
{
"name": "small2"
},
{
"name": "small3"
},
{
"name": "small_connector"
},
{
"name": "medium1"
},
{
"name": "medium2"
},
{
"name": "medium3"
},
{
"name": "medium_connector"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 275 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 726 B

After

Width:  |  Height:  |  Size: 731 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 B

View File

@@ -25,6 +25,15 @@
{
"name": "liq-5"
},
{
"name": "crystal"
},
{
"name": "rotate_back_stop"
},
{
"name": "rotate_front_stop"
},
{
"name": "rotate_back",
"delays": [

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 B