From 2cfdc4a52fac01492db6be7b6ef1bedf9e778bab Mon Sep 17 00:00:00 2001
From: Ed <96445749+TheShuEd@users.noreply.github.com>
Date: Sat, 8 Jun 2024 18:46:09 +0300
Subject: [PATCH] Solution normalizer (#227)
* dropper
* add stabilizer
* fuck, now
* Update CP14SolutionNormalizerComponent.cs
---
.../CP14SolutionNormalizerComponent.cs | 40 +++++++++++
.../Alchemy/CP14SolutionNormalizerSystem.cs | 67 ++++++++++++++++++
.../EntitySystems/SharedInjectorSystem.cs | 2 +-
.../Entities/Objects/Specific/chemistry.yml | 2 +
.../Objects/Specific/Alchemy/tools.yml | 54 +++++++++++++-
.../Structures/Specific/Alchemy/heater.yml | 1 +
.../Specific/Alchemy/normalizer.yml | 54 ++++++++++++++
.../Specific/Alchemy/dropper.rsi/dropper.png | Bin 0 -> 257 bytes
.../Specific/Alchemy/dropper.rsi/liq-1.png | Bin 0 -> 117 bytes
.../Specific/Alchemy/dropper.rsi/liq-2.png | Bin 0 -> 119 bytes
.../Specific/Alchemy/dropper.rsi/meta.json | 20 ++++++
.../Specific/Alchemy/normalizer.rsi/base.png | Bin 0 -> 726 bytes
.../Specific/Alchemy/normalizer.rsi/liq-1.png | Bin 0 -> 146 bytes
.../Specific/Alchemy/normalizer.rsi/liq-2.png | Bin 0 -> 158 bytes
.../Specific/Alchemy/normalizer.rsi/liq-3.png | Bin 0 -> 167 bytes
.../Specific/Alchemy/normalizer.rsi/liq-4.png | Bin 0 -> 197 bytes
.../Specific/Alchemy/normalizer.rsi/liq-5.png | Bin 0 -> 227 bytes
.../Specific/Alchemy/normalizer.rsi/meta.json | 51 +++++++++++++
.../Alchemy/normalizer.rsi/rotate_back.png | Bin 0 -> 527 bytes
.../Alchemy/normalizer.rsi/rotate_front.png | Bin 0 -> 413 bytes
20 files changed, 288 insertions(+), 3 deletions(-)
create mode 100644 Content.Server/_CP14/Alchemy/CP14SolutionNormalizerComponent.cs
create mode 100644 Content.Server/_CP14/Alchemy/CP14SolutionNormalizerSystem.cs
create mode 100644 Resources/Prototypes/_CP14/Entities/Structures/Specific/Alchemy/normalizer.yml
create mode 100644 Resources/Textures/_CP14/Objects/Specific/Alchemy/dropper.rsi/dropper.png
create mode 100644 Resources/Textures/_CP14/Objects/Specific/Alchemy/dropper.rsi/liq-1.png
create mode 100644 Resources/Textures/_CP14/Objects/Specific/Alchemy/dropper.rsi/liq-2.png
create mode 100644 Resources/Textures/_CP14/Objects/Specific/Alchemy/dropper.rsi/meta.json
create mode 100644 Resources/Textures/_CP14/Structures/Specific/Alchemy/normalizer.rsi/base.png
create mode 100644 Resources/Textures/_CP14/Structures/Specific/Alchemy/normalizer.rsi/liq-1.png
create mode 100644 Resources/Textures/_CP14/Structures/Specific/Alchemy/normalizer.rsi/liq-2.png
create mode 100644 Resources/Textures/_CP14/Structures/Specific/Alchemy/normalizer.rsi/liq-3.png
create mode 100644 Resources/Textures/_CP14/Structures/Specific/Alchemy/normalizer.rsi/liq-4.png
create mode 100644 Resources/Textures/_CP14/Structures/Specific/Alchemy/normalizer.rsi/liq-5.png
create mode 100644 Resources/Textures/_CP14/Structures/Specific/Alchemy/normalizer.rsi/meta.json
create mode 100644 Resources/Textures/_CP14/Structures/Specific/Alchemy/normalizer.rsi/rotate_back.png
create mode 100644 Resources/Textures/_CP14/Structures/Specific/Alchemy/normalizer.rsi/rotate_front.png
diff --git a/Content.Server/_CP14/Alchemy/CP14SolutionNormalizerComponent.cs b/Content.Server/_CP14/Alchemy/CP14SolutionNormalizerComponent.cs
new file mode 100644
index 0000000000..680b8905f2
--- /dev/null
+++ b/Content.Server/_CP14/Alchemy/CP14SolutionNormalizerComponent.cs
@@ -0,0 +1,40 @@
+
+using Content.Shared.FixedPoint;
+using Robust.Shared.Audio;
+
+namespace Content.Server._CP14.Alchemy;
+
+///
+/// gradually rounds down all reagents in the specified solution
+///
+[RegisterComponent, Access(typeof(CP14SolutionNormalizerSystem))]
+public sealed partial class CP14SolutionNormalizerComponent : Component
+{
+ [DataField(required: true)]
+ public string Solution = string.Empty;
+
+ ///
+ /// will round down any reagent in solution until it is divisible by this value
+ ///
+ [DataField]
+ public float Factor = 0.25f;
+
+ ///
+ /// the reagent will flow gradually by the specified number until it becomes normalized
+ ///
+ [DataField]
+ public FixedPoint2 LeakageQuantity = 0.05f;
+
+ [DataField]
+ public TimeSpan UpdateFrequency = TimeSpan.FromSeconds(4f);
+
+ [DataField]
+ public TimeSpan NextUpdateTime = TimeSpan.Zero;
+
+ [DataField]
+ public SoundSpecifier NormalizeSound = new SoundPathSpecifier("/Audio/Ambience/Objects/drain.ogg")
+ {
+ Params = AudioParams.Default.WithVariation(0.03f)
+ };
+}
+
diff --git a/Content.Server/_CP14/Alchemy/CP14SolutionNormalizerSystem.cs b/Content.Server/_CP14/Alchemy/CP14SolutionNormalizerSystem.cs
new file mode 100644
index 0000000000..b8c4305a2c
--- /dev/null
+++ b/Content.Server/_CP14/Alchemy/CP14SolutionNormalizerSystem.cs
@@ -0,0 +1,67 @@
+using Content.Shared.Chemistry.Components.SolutionManager;
+using Content.Shared.Chemistry.EntitySystems;
+using Content.Shared.Chemistry.Reagent;
+using Content.Shared.FixedPoint;
+using Robust.Shared.Audio.Systems;
+using Robust.Shared.Timing;
+
+namespace Content.Server._CP14.Alchemy;
+
+public sealed partial class CP14SolutionNormalizerSystem : EntitySystem
+{
+ [Dependency] private readonly SharedAudioSystem _audio = default!;
+ [Dependency] private readonly IGameTiming _timing = default!;
+ [Dependency] private readonly SharedSolutionContainerSystem _solutionContainer = default!;
+
+ public override void Update(float frameTime)
+ {
+ base.Update(frameTime);
+
+ var query = EntityQueryEnumerator();
+
+ while (query.MoveNext(out var uid, out var normalizer, out var containerManager))
+ {
+ if (_timing.CurTime <= normalizer.NextUpdateTime)
+ continue;
+
+ normalizer.NextUpdateTime = _timing.CurTime + normalizer.UpdateFrequency;
+
+ var solutionManager = new Entity(uid, containerManager);
+
+ if (!_solutionContainer.TryGetSolution(solutionManager,
+ normalizer.Solution,
+ out var solutionEnt,
+ out var solution))
+ continue;
+
+ if (solution.Volume == 0)
+ continue;
+
+ Dictionary affect = new();
+ foreach (var (id, quantity) in solution.Contents)
+ {
+ FixedPoint2 roundedQuantity = Math.Floor((float) quantity / normalizer.Factor) * normalizer.Factor;
+
+ var leakQuantity = quantity - roundedQuantity;
+
+ if (leakQuantity == 0) continue;
+
+ if (quantity - normalizer.LeakageQuantity < roundedQuantity)
+ affect.Add(id, leakQuantity);
+ else
+ affect.Add(id, normalizer.LeakageQuantity);
+ }
+
+ if (affect.Count > 0)
+ {
+ //Telegraphy
+ _audio.PlayPvs(normalizer.NormalizeSound, uid);
+
+ foreach (var (id, count) in affect)
+ {
+ _solutionContainer.RemoveReagent(solutionEnt.Value, id, count);
+ }
+ }
+ }
+ }
+}
diff --git a/Content.Shared/Chemistry/EntitySystems/SharedInjectorSystem.cs b/Content.Shared/Chemistry/EntitySystems/SharedInjectorSystem.cs
index 1620344652..e282d8c375 100644
--- a/Content.Shared/Chemistry/EntitySystems/SharedInjectorSystem.cs
+++ b/Content.Shared/Chemistry/EntitySystems/SharedInjectorSystem.cs
@@ -16,7 +16,7 @@ public abstract class SharedInjectorSystem : EntitySystem
///
/// Default transfer amounts for the set-transfer verb.
///
- public static readonly FixedPoint2[] TransferAmounts = { 1, 5, 10, 15 };
+ public static readonly FixedPoint2[] TransferAmounts = {0.25f, 1, 5, 10, 15};//{ 1, 5, 10, 15 }; // CP14 0.25 needed
[Dependency] protected readonly SharedPopupSystem Popup = default!;
[Dependency] protected readonly SharedSolutionContainerSystem SolutionContainers = default!;
diff --git a/Resources/Prototypes/Entities/Objects/Specific/chemistry.yml b/Resources/Prototypes/Entities/Objects/Specific/chemistry.yml
index dd15a90baa..9a41b21d13 100644
--- a/Resources/Prototypes/Entities/Objects/Specific/chemistry.yml
+++ b/Resources/Prototypes/Entities/Objects/Specific/chemistry.yml
@@ -264,6 +264,7 @@
name: dropper
parent: BaseItem
description: Used to transfer small amounts of chemical solution between containers.
+ noSpawn: true
id: Dropper
components:
- type: Sprite
@@ -307,6 +308,7 @@
name: borgdropper
parent: Dropper
description: Used to transfer small amounts of chemical solution between containers. Extended for use by medical borgs.
+ noSpawn: true
id: BorgDropper
components:
- type: Sprite
diff --git a/Resources/Prototypes/_CP14/Entities/Objects/Specific/Alchemy/tools.yml b/Resources/Prototypes/_CP14/Entities/Objects/Specific/Alchemy/tools.yml
index 2f52f61057..084713d834 100644
--- a/Resources/Prototypes/_CP14/Entities/Objects/Specific/Alchemy/tools.yml
+++ b/Resources/Prototypes/_CP14/Entities/Objects/Specific/Alchemy/tools.yml
@@ -46,7 +46,7 @@
ignoreMobs: true
minTransferAmount: 10
maxTransferAmount: 100
- transferAmount: 50
+ transferAmount: 15
toggleState: 1 # draw
- type: UserInterface
interfaces:
@@ -153,4 +153,54 @@
- 0,0,1,1
- type: CP14Mortar
solution: mortar
- containerId: storagebase
\ No newline at end of file
+ containerId: storagebase
+
+- type: entity
+ parent: BaseItem
+ id: CP14Dropper
+ name: dropper
+ description: Small dropper for managing very small values of liquids
+ components:
+ - type: MixableSolution
+ solution: vial
+ - type: FitsInDispenser
+ solution: vial
+ - type: RefillableSolution
+ solution: vial
+ - type: DrainableSolution
+ solution: vial
+ - type: ExaminableSolution
+ solution: vial
+ - type: DrawableSolution
+ solution: vial
+ - type: InjectableSolution
+ solution: vial
+ - type: SolutionItemStatus
+ solution: vial
+ - type: SolutionContainerManager
+ solutions:
+ vial:
+ maxVol: 2
+ - type: UserInterface
+ interfaces:
+ enum.TransferAmountUiKey.Key:
+ type: TransferAmountBoundUserInterface
+ - type: Appearance
+ - type: Injector
+ solutionName: vial
+ injectOnly: false
+ ignoreMobs: true
+ minTransferAmount: 0.25
+ maxTransferAmount: 1
+ transferAmount: 0.25
+ toggleState: 1 # draw
+ - type: Sprite
+ sprite: _CP14/Objects/Specific/Alchemy/dropper.rsi
+ layers:
+ - state: dropper
+ - state: liq-1
+ map: ["enum.SolutionContainerLayers.Fill"]
+ visible: false
+ - type: SolutionContainerVisuals
+ maxFillLevels: 2
+ fillBaseName: liq-
\ No newline at end of file
diff --git a/Resources/Prototypes/_CP14/Entities/Structures/Specific/Alchemy/heater.yml b/Resources/Prototypes/_CP14/Entities/Structures/Specific/Alchemy/heater.yml
index 6f6b2bbfa1..2a8544e3a9 100644
--- a/Resources/Prototypes/_CP14/Entities/Structures/Specific/Alchemy/heater.yml
+++ b/Resources/Prototypes/_CP14/Entities/Structures/Specific/Alchemy/heater.yml
@@ -3,6 +3,7 @@
parent: BaseStructure
abstract: true
components:
+ - type: InteractionOutline
- type: Fixtures
fixtures:
fix1:
diff --git a/Resources/Prototypes/_CP14/Entities/Structures/Specific/Alchemy/normalizer.yml b/Resources/Prototypes/_CP14/Entities/Structures/Specific/Alchemy/normalizer.yml
new file mode 100644
index 0000000000..a2e6ef6983
--- /dev/null
+++ b/Resources/Prototypes/_CP14/Entities/Structures/Specific/Alchemy/normalizer.yml
@@ -0,0 +1,54 @@
+- type: entity
+ id: CP14AlchemyNormalizer
+ parent: BaseStructureDynamic
+ name: solution stabilizer
+ description: An alchemical device that removes fine precipitates from solutions, and stabilizes it for further work
+ placement:
+ mode: PlaceFree
+ components:
+ # TODO: energy consuming (magic or fireplace)
+ - type: InteractionOutline
+ - type: Sprite
+ drawdepth: Items
+ noRot: true
+ offset: 0, 0.2
+ sprite: _CP14/Structures/Specific/Alchemy/normalizer.rsi
+ layers:
+ - state: rotate_back
+ - state: liq-1
+ map: ["enum.SolutionContainerLayers.Fill"]
+ visible: false
+ - state: base
+ - state: rotate_front
+ state: base
+ - type: Fixtures
+ fixtures:
+ fix1:
+ shape:
+ !type:PhysShapeAabb
+ bounds: "-0.25,-0.25,0.25,0.25"
+ density: 125
+ mask:
+ - TabletopMachineMask
+ - type: SolutionContainerManager
+ solutions:
+ normalizer:
+ maxVol: 50
+ - type: DrainableSolution
+ solution: normalizer
+ - type: ExaminableSolution
+ solution: normalizer
+ - type: MixableSolution
+ solution: normalizer
+ - type: RefillableSolution
+ solution: normalizer
+ - type: DrawableSolution
+ solution: normalizer
+ - type: DumpableSolution
+ solution: normalizer
+ - type: CP14SolutionNormalizer
+ solution: normalizer
+ - type: Appearance
+ - type: SolutionContainerVisuals
+ maxFillLevels: 5
+ fillBaseName: liq-
\ No newline at end of file
diff --git a/Resources/Textures/_CP14/Objects/Specific/Alchemy/dropper.rsi/dropper.png b/Resources/Textures/_CP14/Objects/Specific/Alchemy/dropper.rsi/dropper.png
new file mode 100644
index 0000000000000000000000000000000000000000..e1026b1205ca439f060ce8943fef2b4d0d34c4a5
GIT binary patch
literal 257
zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}yFFbTLn2z=
zURuq?6ew`)<9_iYp<*8o>50u&P&?e@XdvyYHd!I9x&MLn4+gsy{=~4&x%{gO1oTs{
zDsU%#)Zv)+^Qz>&nT?E!EdowQOg`;7uK)ScGH33cA`HKTHbuQRWAK{aeE#0+m)qE9
ze6e<({HEpPhbq(NV6R1e2)NNnpc6aaUS7m8^dl?&+^XclcFnwt`Ee+Jl
N;OXk;vd$@?2>{~uBa;9C
literal 0
HcmV?d00001
diff --git a/Resources/Textures/_CP14/Objects/Specific/Alchemy/dropper.rsi/liq-2.png b/Resources/Textures/_CP14/Objects/Specific/Alchemy/dropper.rsi/liq-2.png
new file mode 100644
index 0000000000000000000000000000000000000000..929d6b17eb6d9e3fc251cd7e12f57479d49e5cc4
GIT binary patch
literal 119
zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}hMq2tArY-_
z&ny&VP~c%XxIp<*eRC$W)&ZA<8(Yo)3o;ydf34)k-QBC!*%}|e&u}1^J)4(>NpW?|
QMxbT}Pgg&ebxsLQ0B8Osf&c&j
literal 0
HcmV?d00001
diff --git a/Resources/Textures/_CP14/Objects/Specific/Alchemy/dropper.rsi/meta.json b/Resources/Textures/_CP14/Objects/Specific/Alchemy/dropper.rsi/meta.json
new file mode 100644
index 0000000000..7e21d2df46
--- /dev/null
+++ b/Resources/Textures/_CP14/Objects/Specific/Alchemy/dropper.rsi/meta.json
@@ -0,0 +1,20 @@
+{
+ "version": 1,
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "license": "All rights reserved for the CrystallPunk14 project only",
+ "copyright": "Created by TheShuEd (Github) for CrystallPunk14",
+ "states": [
+ {
+ "name": "dropper"
+ },
+ {
+ "name": "liq-1"
+ },
+ {
+ "name": "liq-2"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Resources/Textures/_CP14/Structures/Specific/Alchemy/normalizer.rsi/base.png b/Resources/Textures/_CP14/Structures/Specific/Alchemy/normalizer.rsi/base.png
new file mode 100644
index 0000000000000000000000000000000000000000..425e9e3efde995845a09df0c863c452b5756031e
GIT binary patch
literal 726
zcmV;{0xA88P)Px%kV!;AR9J=WR!?YBaUB0t#`f0UR2;rop#u>%BhcBYL(n>`(=gCc83YgNu%y^Q
zc4%}eSa=wLrw%U`Gh!Pgowmz@4xQ%ol3PfS5^G8i=N#&CVF&%m^SPeC2aX8*z=QX`
z|307h`+dLf_ka#M=-?mYgxZ9a^{u#)|N5mN+p!2B#L4gC1^{I9#hBEuXBj&Hn9mzV
z)Ci#xu(G}tmlLPc8PRhP764$W%f)k?(I6K>BjO~D00KF=&QgZXQikUsETq#JQ5r)F
z4Q(L9cAFTs+f>Y#QhL^mkNNw4lxt2CFvK#~NZhdqDCSG4Y`z#97|@R^5p8d0-|Jb%
z4(*x#whADKM!&pL@{?Ymg=zr+kPZa|pWE7C3oa+XdHuZFT2xK=`rfT!IXP)Sa{1g=
zq(cGWs2n9wjbZ%ljmp#K-_X~48ok<6;P0G8GQu>(n4Luk3p?1){l?yY88g#^u-$yu
zvOd)oBqI!FrUwB4!op4yIf(&)hY!v*Jhw$aMl1l49ssDly~GZ{Xps7t245>s^#C_H
zyO|LS$cTj_3CMji!hpnale3#NwW+6|H0}>&^TilG1Ovo2w^m(>sZnQL#E+{!f9-QT
z(l!Bot51e;;n4;F#B38h0NCS;f;5KMIlxfQX_tW9t_BxBzwiR^E_J!;vpzNIY>K^-
zdKn-&Z4*#k-fE+Hbk!3ufyON$CnF)IZNipw`svw3CAX_->UcSU+-@}VK&v~%<;RPP
z9E#3)-c=#@b88XU^!*rfm=y)DMw5tVe>QB-T_OBe9@W2Ow;hfO0QlV2`f_V^hX^hw
z003{IQB^fnA4Y^=%weurEmd3M>o3*BZNWV6sz|q~gZ~nL0O5oe0pBPA%m4rY07*qo
IM6N<$g37T>NB{r;
literal 0
HcmV?d00001
diff --git a/Resources/Textures/_CP14/Structures/Specific/Alchemy/normalizer.rsi/liq-1.png b/Resources/Textures/_CP14/Structures/Specific/Alchemy/normalizer.rsi/liq-1.png
new file mode 100644
index 0000000000000000000000000000000000000000..05fb50034cdd69b1d5a6e96e498b4dc5a1a366db
GIT binary patch
literal 146
zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}KAtX)ArY-_
z&u!#9V8G)Ncr&Gaw)1a(#oQ+*h8AkBESXIIr|x2&D+yE@ARzd-``oJVdET1}Z+@BV8G*YQ8-2My?u*qYtQl>A%-d}ZYycr!_j%<@y@O@uOe(ZuNLJV84-F+REy?V~fo9SmFpSe2So^#;=
P&@u*3S3j3^P6hg
literal 0
HcmV?d00001
diff --git a/Resources/Textures/_CP14/Structures/Specific/Alchemy/normalizer.rsi/liq-5.png b/Resources/Textures/_CP14/Structures/Specific/Alchemy/normalizer.rsi/liq-5.png
new file mode 100644
index 0000000000000000000000000000000000000000..020c8d59a05d5225a110e55982f84d1d3c934b14
GIT binary patch
literal 227
zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}b3I)gLn2z=
zUU|#OtjNRm;QA%mBZhbCJ1ksPf|u-{Vtp~`!4i>Ae}p{s>S7t5&-uME!8aiE?McO!
zt9RC2&r>jdz3M{gnpLOHSUp?6r<~c9g<(R_tJbu_t=Hs!zhGL&I&VuY>+%`?4lWal
z=h>MkU6NS*vU-{Dk1!dAqH_m}{-2xKGq>Prg?di6M0MS4`)i!H-@Ch9zB@H2ukf7Z
acXPX$ccMZ2gTd3)&t;ucLK6V>U0<~T
literal 0
HcmV?d00001
diff --git a/Resources/Textures/_CP14/Structures/Specific/Alchemy/normalizer.rsi/meta.json b/Resources/Textures/_CP14/Structures/Specific/Alchemy/normalizer.rsi/meta.json
new file mode 100644
index 0000000000..d45fe7fd2e
--- /dev/null
+++ b/Resources/Textures/_CP14/Structures/Specific/Alchemy/normalizer.rsi/meta.json
@@ -0,0 +1,51 @@
+{
+ "version": 1,
+ "license": "All rights reserved for the CrystallPunk14 project only",
+ "copyright": "Created by TheShuEd for CrystallPunk14",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "states": [
+ {
+ "name": "base"
+ },
+ {
+ "name": "liq-1"
+ },
+ {
+ "name": "liq-2"
+ },
+ {
+ "name": "liq-3"
+ },
+ {
+ "name": "liq-4"
+ },
+ {
+ "name": "liq-5"
+ },
+ {
+ "name": "rotate_back",
+ "delays": [
+ [
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2
+ ]
+ ]
+ },
+ {
+ "name": "rotate_front",
+ "delays": [
+ [
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2
+ ]
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Resources/Textures/_CP14/Structures/Specific/Alchemy/normalizer.rsi/rotate_back.png b/Resources/Textures/_CP14/Structures/Specific/Alchemy/normalizer.rsi/rotate_back.png
new file mode 100644
index 0000000000000000000000000000000000000000..8db70515768f4011d640e8943e4d9a6895422e0d
GIT binary patch
literal 527
zcmV+q0`UEbP)Px$$w@>(RCt{2+OcZFKo|$`&$eS*eSuOsO2JX+;M6IQCvdm;0QD*C6WHCoAY{ti
z&MpBdgy7&LcqVJO4kdE2r`{!(NYejr3E{$hxl8VjpNvri-SD|f(R
zwWh^ty*q!kpHff2^?Vceqiopg^6Td1?)Er8LdydeW17v|C7E{2&KjlRd<0T!E#1`LD70N>(U?JT%Z-|Jb9N_;
zx(Qv*+>^fM!(P|u3Xx)U+T7~2PX3n@2SyJY;_PZ5hr+#Hc7EuU)$EH_(PZnk-<&>}u{+5Uv&
zSX;whmmf=ipEDy>irP020N|J+Cc#R53y2+XXn%lidc0EK0?7RX0000O^aF4k=e=}}
REQ|mE002ovPDHLkV1f!-?-&38
literal 0
HcmV?d00001
diff --git a/Resources/Textures/_CP14/Structures/Specific/Alchemy/normalizer.rsi/rotate_front.png b/Resources/Textures/_CP14/Structures/Specific/Alchemy/normalizer.rsi/rotate_front.png
new file mode 100644
index 0000000000000000000000000000000000000000..48b27ceeb5963d4000d37528063ab1b0722e840d
GIT binary patch
literal 413
zcmV;O0b>4%P)Px$S4l)cRCt{2+C56dKoke?QMMK@-~rO4&k+XZ1nJ`mk~T$Bx(ATh+Y5nIsVr73
z1qmz*LATgyA-mej*okiAo8;wVcK^RFFrP1zVaOXH00000ERh9DbGCQR+1L=4n{8S|
zzAhr4B@k!Sf?1&S)#b&{v%I|thssL`<&sc&tjmn+l^9K%Ly{
zd(&z#UEMxD$5URV0AMlcI$FBUzXu`dI*D|hK@UO){r7hcm^#V}I%+2$0000000000
zfZk<+(%kuaXo2&-0GJpf^4xt|^;^7%d|g&`dU!jfi&>Y->t@e24wAB}+1u