diff --git a/Content.Server/Chemistry/ReagentEffects/GenderChange.cs b/Content.Server/Chemistry/ReagentEffects/GenderChange.cs
new file mode 100644
index 0000000000..7c0cc07469
--- /dev/null
+++ b/Content.Server/Chemistry/ReagentEffects/GenderChange.cs
@@ -0,0 +1,49 @@
+using Content.Server.IdentityManagement;
+using Content.Shared._Amour.GrammarSystem;
+using Content.Shared.Chemistry.Reagent;
+using Content.Shared.IdentityManagement.Components;
+using Robust.Shared.Enums;
+using Robust.Shared.Prototypes;
+using Robust.Shared.GameObjects.Components.Localization;
+
+namespace Content.Server.Chemistry.ReagentEffects;
+
+public sealed partial class GenderChange : ReagentEffect
+{
+ ///
+ /// What gender is the consumer changed to? If not set then swap between male/female.
+ ///
+ [DataField("gender")]
+ public Gender? NewGender;
+
+ protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
+ => Loc.GetString("reagent-effect-guidebook-gender-change", ("chance", Probability));
+
+ public override void Effect(ReagentEffectArgs args)
+ {
+ if (args.EntityManager.TryGetComponent(args.SolutionEntity, out var grammar))
+ {
+ var uid = args.SolutionEntity;
+ var newGender = NewGender;
+ var grammarSystem = args.EntityManager.System();
+ var identitySystem = args.EntityManager.System();
+
+ // bleh, this probably should not be here but I have no clue where to put it
+ if (grammar.Gender != Gender.Epicene && grammar.Gender != Gender.Neuter)
+ {
+ if (grammar.Gender == Gender.Male)
+ newGender = Gender.Female;
+ else
+ newGender = Gender.Male;
+ }
+
+ if (newGender.HasValue)
+ {
+ grammarSystem.SetGender((uid, grammar), newGender);
+
+ if (args.EntityManager.HasComponent(uid))
+ identitySystem.QueueIdentityUpdate(uid);
+ }
+ }
+ }
+}
diff --git a/Content.Server/Chemistry/ReagentEffects/SexChange.cs b/Content.Server/Chemistry/ReagentEffects/SexChange.cs
new file mode 100644
index 0000000000..6ba69e23ae
--- /dev/null
+++ b/Content.Server/Chemistry/ReagentEffects/SexChange.cs
@@ -0,0 +1,36 @@
+using Content.Shared.Humanoid;
+using Content.Shared.Chemistry.Reagent;
+using Robust.Shared.Prototypes;
+
+namespace Content.Server.Chemistry.ReagentEffects;
+
+public sealed partial class SexChange : ReagentEffect
+{
+ ///
+ /// What sex is the consumer changed to? If not set then swap between male/female.
+ ///
+ [DataField("sex")]
+ public Sex? NewSex;
+
+ protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
+ => Loc.GetString("reagent-effect-guidebook-sex-change", ("chance", Probability));
+
+ public override void Effect(ReagentEffectArgs args)
+ {
+ if (args.EntityManager.TryGetComponent(args.SolutionEntity, out var appearance))
+ {
+ var uid = args.SolutionEntity;
+ var newSex = NewSex;
+ var humanoidAppearanceSystem = args.EntityManager.System();
+
+ if (newSex.HasValue)
+ {
+ humanoidAppearanceSystem.SetSex(uid, newSex.Value);
+ return;
+ }
+
+ if (appearance.Sex != Sex.Unsexed)
+ humanoidAppearanceSystem.SwapSex(uid);
+ }
+ }
+}
diff --git a/Content.Shared/Humanoid/SharedHumanoidAppearanceSystem.cs b/Content.Shared/Humanoid/SharedHumanoidAppearanceSystem.cs
index 4bab12dcfb..8c98f71591 100644
--- a/Content.Shared/Humanoid/SharedHumanoidAppearanceSystem.cs
+++ b/Content.Shared/Humanoid/SharedHumanoidAppearanceSystem.cs
@@ -359,6 +359,21 @@ public abstract class SharedHumanoidAppearanceSystem : EntitySystem
}
}
+ public void SwapSex(EntityUid uid, HumanoidAppearanceComponent? humanoid = null)
+ {
+ if (!Resolve(uid, ref humanoid) || humanoid.Sex == Sex.Unsexed)
+ return;
+
+ // Not set up for future possible alien sexes
+ if (humanoid.Sex == Sex.Male)
+ {
+ SetSex(uid,Sex.Female);
+ return;
+ }
+ SetSex(uid,Sex.Male);
+
+ }
+
public List GetValidBodyTypes(SpeciesPrototype species, Sex sex)
{
return species.BodyTypes.Select(protoId => _proto.Index(protoId))
diff --git a/Content.Shared/_Amour/GrammarSystem/GrammarSystem.cs b/Content.Shared/_Amour/GrammarSystem/GrammarSystem.cs
new file mode 100644
index 0000000000..7d9bc2fef3
--- /dev/null
+++ b/Content.Shared/_Amour/GrammarSystem/GrammarSystem.cs
@@ -0,0 +1,39 @@
+using System.Diagnostics.CodeAnalysis;
+using Robust.Shared.Enums;
+using Robust.Shared.GameObjects.Components.Localization;
+
+namespace Content.Shared._Amour.GrammarSystem;
+
+public sealed class GrammarSystem : EntitySystem
+{
+ public void Clear(Entity grammar)
+ {
+ grammar.Comp.Attributes.Clear();
+ Dirty(grammar);
+ }
+
+ public bool TryGet(Entity grammar, string key, [NotNullWhen(true)] out string? value)
+ {
+ return grammar.Comp.Attributes.TryGetValue(key, out value);
+ }
+
+ public void Set(Entity grammar, string key, string? value)
+ {
+ if (value == null)
+ grammar.Comp.Attributes.Remove(key);
+ else
+ grammar.Comp.Attributes[key] = value;
+
+ Dirty(grammar);
+ }
+
+ public void SetGender(Entity grammar, Gender? gender)
+ {
+ Set(grammar, "gender", gender?.ToString());
+ }
+
+ public void SetProperNoun(Entity grammar, bool? proper)
+ {
+ Set(grammar, "proper", proper?.ToString());
+ }
+}
diff --git a/Resources/Locale/ru-RU/guidebook/chemistry/effects.ftl b/Resources/Locale/ru-RU/guidebook/chemistry/effects.ftl
index f09ac1c15a..6d3a3321a1 100644
--- a/Resources/Locale/ru-RU/guidebook/chemistry/effects.ftl
+++ b/Resources/Locale/ru-RU/guidebook/chemistry/effects.ftl
@@ -321,3 +321,15 @@ reagent-effect-guidebook-missing =
[1] Causes
*[other] cause
} an unknown effect as nobody has written this effect yet
+
+#Amour
+reagent-effect-guidebook-sex-change =
+ { $chance ->
+ [1] Делает
+ *[other] делает
+ } метаболизатор меняет пол
+reagent-effect-guidebook-gender-change =
+ { $chance ->
+ [1] Делает
+ *[other] делает
+ } метаболизатор меняет пол
diff --git a/Resources/Locale/ru-RU/reagents/meta/fun.ftl b/Resources/Locale/ru-RU/reagents/meta/fun.ftl
index c460b83366..8c248a854f 100644
--- a/Resources/Locale/ru-RU/reagents/meta/fun.ftl
+++ b/Resources/Locale/ru-RU/reagents/meta/fun.ftl
@@ -10,3 +10,9 @@ reagent-name-saxoite = саксонит
reagent-desc-saxoite = Отдаёт джазом.
reagent-name-licoxide = ликоксид
reagent-desc-licoxide = Это выглядит... электризующе.
+reagent-name-estrogen-plus = Эстроген Плюс
+reagent-desc-estrogen-plus = Эстроген... плюс тестостерон... как это работает?..
+reagent-name-estrogen = Эстроген
+reagent-desc-estrogen = Средство для выражения вашей женской натуры.
+reagent-name-testosterone = Тестостерон
+reagent-desc-testosterone = Химическое вещество, выражающее вашу мужскую сторону.
diff --git a/Resources/Prototypes/Hydroponics/mutations.yml b/Resources/Prototypes/Hydroponics/mutations.yml
index 17617f5ee3..5c78eab547 100644
--- a/Resources/Prototypes/Hydroponics/mutations.yml
+++ b/Resources/Prototypes/Hydroponics/mutations.yml
@@ -32,6 +32,7 @@
- ChangelingSting
- CogChamp
- JuiceThatMakesYouWeh
+ - EstrogenPlus
- quantity: 5
weight: 2
reagents:
diff --git a/Resources/Prototypes/Reagents/fun.yml b/Resources/Prototypes/Reagents/fun.yml
index befa8d8296..e371223aa9 100644
--- a/Resources/Prototypes/Reagents/fun.yml
+++ b/Resources/Prototypes/Reagents/fun.yml
@@ -348,3 +348,103 @@
conditions:
- !type:ReagentThreshold
min: 50
+
+- type: reagent
+ id: EstrogenPlus
+ name: reagent-name-estrogen-plus
+ desc: reagent-desc-estrogen-plus
+ physicalDesc: reagent-physical-desc-soothing
+ flavor: medicine
+ color: "#ffffff"
+ metabolisms:
+ Medicine:
+ effects:
+ - !type:SexChange
+ conditions:
+ - !type:ReagentThreshold
+ min: 20
+ - !type:GenderChange
+ conditions:
+ - !type:ReagentThreshold
+ min: 20
+ - !type:AdjustReagent
+ reagent: EstrogenPlus
+ amount: -20
+ conditions:
+ - !type:ReagentThreshold
+ min: 20
+ - !type:PopupMessage
+ type: Local
+ messages: [ "generic-reagent-effect-changed" ]
+ conditions:
+ - !type:ReagentThreshold
+ reagent: EstrogenPlus
+ min: 20
+
+- type: reagent
+ id: Estrogen
+ name: reagent-name-estrogen
+ desc: reagent-desc-estrogen
+ physicalDesc: reagent-physical-desc-enigmatic
+ flavor: medicine
+ color: "#f5aab9"
+ metabolisms:
+ Medicine:
+ effects:
+ - !type:SexChange
+ sex: Female
+ conditions:
+ - !type:ReagentThreshold
+ min: 20
+ - !type:GenderChange
+ gender: Female
+ conditions:
+ - !type:ReagentThreshold
+ min: 20
+ - !type:AdjustReagent
+ reagent: Estrogen
+ amount: -20
+ conditions:
+ - !type:ReagentThreshold
+ min: 20
+ - !type:PopupMessage
+ type: Local
+ messages: [ "generic-reagent-effect-changed" ]
+ conditions:
+ - !type:ReagentThreshold
+ reagent: Estrogen
+ min: 20
+
+- type: reagent
+ id: Testosterone
+ name: reagent-name-testosterone
+ desc: reagent-desc-testosterone
+ physicalDesc: reagent-physical-desc-enigmatic
+ flavor: medicine
+ color: "#5bcffa"
+ metabolisms:
+ Medicine:
+ effects:
+ - !type:SexChange
+ sex: Male
+ conditions:
+ - !type:ReagentThreshold
+ min: 20
+ - !type:GenderChange
+ gender: Male
+ conditions:
+ - !type:ReagentThreshold
+ min: 20
+ - !type:AdjustReagent
+ reagent: Testosterone
+ amount: -20
+ conditions:
+ - !type:ReagentThreshold
+ min: 20
+ - !type:PopupMessage
+ type: Local
+ messages: [ "generic-reagent-effect-changed" ]
+ conditions:
+ - !type:ReagentThreshold
+ reagent: Testosterone
+ min: 20
diff --git a/Resources/Prototypes/Recipes/Construction/fun.yml b/Resources/Prototypes/Recipes/Construction/fun.yml
index a8dada9955..9f55289ae0 100644
--- a/Resources/Prototypes/Recipes/Construction/fun.yml
+++ b/Resources/Prototypes/Recipes/Construction/fun.yml
@@ -8,3 +8,26 @@
description: An air horn made from bananium.
icon: { sprite: Objects/Fun/bananiumhorn.rsi, state: icon }
objectType: Item
+
+- type: reaction
+ id: EstrogenPlus
+ reactants:
+ Testosterone:
+ amount: 1
+ Estrogen:
+ amount: 1
+ products:
+ EstrogenPlus: 1
+
+# Terraria gender swap potion reference? teheh
+- type: reaction
+ id: EstrogenPlusFlower
+ reactants:
+ Bicaridine:
+ amount: 1
+ Siderlac:
+ amount: 1
+ PolypyryliumOligomers:
+ amount: 1
+ products:
+ EstrogenPlus: 1