diff --git a/Content.Server/_Lust/InteractionsPanel/InteractionsPanel.Lust.cs b/Content.Server/_Lust/InteractionsPanel/InteractionsPanel.Lust.cs new file mode 100644 index 00000000000..9d80d958362 --- /dev/null +++ b/Content.Server/_Lust/InteractionsPanel/InteractionsPanel.Lust.cs @@ -0,0 +1,243 @@ +using Content.Server.Fluids.EntitySystems; +using Content.Shared._Sunrise.Aphrodisiac; +using Content.Shared._Sunrise.InteractionsPanel.Data.Components; +using Content.Shared._Sunrise.InteractionsPanel.Data.Prototypes; +using Content.Shared._Sunrise.InteractionsPanel.Data.UI; +using Content.Shared.Chat; +using Content.Shared.Chemistry.Components; +using Content.Shared.Chemistry.Reagent; +using Content.Shared.FixedPoint; +using Content.Shared.Forensics.Components; +using Content.Shared.Humanoid; +using Robust.Shared.Map; +using Robust.Shared.Random; + +namespace Content.Server._Sunrise.InteractionsPanel; + +public partial class InteractionsPanel +{ + [Dependency] private readonly PuddleSystem _puddle = default!; + + private const float LoveDecayRate = 0.5f; + private const float OrgasmCooldownSeconds = 15f; + + private void OnUndressMessageReceived(Entity ent, ref RequestUndressMessage args) + { + if (_inventory.TryGetSlots(ent, out var slots)) + { + foreach (var slot in slots) + { + _inventory.TryUnequip(ent, slot.Name, true, false, false); + } + } + } + + private void ProcessInteractionLustEffects(EntityUid user, EntityUid target, InteractionPrototype interactionPrototype) + { + if (interactionPrototype.LoveUser > 0) + ModifyLove(user, interactionPrototype.LoveUser); + + if (interactionPrototype.LoveTarget > 0) + ModifyLove(target, interactionPrototype.LoveTarget); + + ProcessVirginityLoss(user, target, interactionPrototype); + + TryEmitMoan(user, interactionPrototype.LoveUser, interactionPrototype.UserMoanChance); + TryEmitMoan(target, interactionPrototype.LoveTarget, interactionPrototype.TargetMoanChance); + } + + private void TryEmitMoan(EntityUid uid, FixedPoint2 loveGain, float chance) + { + if (!_gameTiming.IsFirstTimePredicted) + return; + + if (!_random.Prob(chance)) + return; + + if (!TryComp(uid, out var component)) + return; + + var now = _gameTiming.CurTime; + if (now < component.LastMoanTime + TimeSpan.FromSeconds(5)) + return; + + component.LastMoanTime = now; + Dirty(uid, component); + + _chatSystem.TryEmoteWithChat(uid, "Moan"); + } + + private void ProcessVirginityLoss(EntityUid user, EntityUid target, InteractionPrototype proto) + { + TryLoseVirginity(user, proto.UserVirginityLoss); + TryLoseVirginity(target, proto.TargetVirginityLoss); + } + + private void TryLoseVirginity(EntityUid ent, string type) + { + if (!TryComp(ent, out var comp)) + return; + + if (string.IsNullOrWhiteSpace(type) || type == "none") + return; + + var sex = TryComp(ent, out var humanoid) + ? humanoid.Sex.ToString().ToLowerInvariant() + : "unknown"; + + switch (type.ToLowerInvariant()) + { + case "anal": + if (comp.AnalVirginity == Virginity.Yes) + { + comp.AnalVirginity = Virginity.No; + Dirty(ent, comp); + _chatSystem.TrySendInGameICMessage(ent, "теряет анальную девственность", InGameICChatType.Emote, false); + } + break; + + case "vaginal": + case "female": + if (comp.Virginity == Virginity.Yes && sex == "female") + { + comp.Virginity = Virginity.No; + Dirty(ent, comp); + _chatSystem.TrySendInGameICMessage(ent, "теряет девственность", InGameICChatType.Emote, false); + } + break; + + case "male": + if (comp.Virginity == Virginity.Yes && sex == "male") + { + comp.Virginity = Virginity.No; + Dirty(ent, comp); + _chatSystem.TrySendInGameICMessage(ent, "теряет девственность", InGameICChatType.Emote, false); + } + break; + + case "futanari": + if (comp.Virginity == Virginity.Yes && sex == "futanari") + { + comp.Virginity = Virginity.No; + Dirty(ent, comp); + _chatSystem.TrySendInGameICMessage(ent, "теряет девственность", InGameICChatType.Emote, false); + } + break; + + case "any": + if (comp.Virginity == Virginity.Yes) + { + comp.Virginity = Virginity.No; + Dirty(ent, comp); + _chatSystem.TrySendInGameICMessage(ent, "теряет девственность", InGameICChatType.Emote, false); + } + break; + } + } + + private void SpawnSemen(EntityUid source, string prototype, EntityCoordinates coordinates) + { + var solution = new Solution(); + solution.AddReagent(new ReagentId(prototype, GetSemenDnaData(source)), 4f); + _puddle.TrySpillAt(coordinates, solution, out _, false); + } + + private List GetSemenDnaData(EntityUid source) + { + var dnaData = new DnaData(); + + if (TryComp(source, out var dnaComp) && dnaComp.DNA != null) + dnaData.DNA = dnaComp.DNA; + else + dnaData.DNA = Loc.GetString("forensics-dna-unknown"); + + return [dnaData]; + } + + private void UpdateLove(EntityUid uid, InteractionsComponent comp, float frameTime) + { + if (comp.LoveAmount <= 0) + { + if (TryComp(uid, out var loveVisionComp) && loveVisionComp.FromLoveSystem) + { + RemComp(uid); + } + return; + } + + comp.LoveAmount -= LoveDecayRate * frameTime; + if (comp.LoveAmount < 0) + comp.LoveAmount = 0; + + Dirty(uid, comp); + + var ratio = (float)(comp.LoveAmount / comp.MaxLoveAmount).Float(); + var hasEffect = HasComp(uid); + + if (ratio >= 0.33f && !hasEffect) + { + var newComp = AddComp(uid); + newComp.FromLoveSystem = true; + Dirty(uid, newComp); + } + else if (ratio < 0.33f && TryComp(uid, out var loveVisionComp) && loveVisionComp.FromLoveSystem) + { + RemComp(uid); + } + } + + private void TryOrgasm(EntityUid uid) + { + if (!TryComp(uid, out var comp)) + return; + + if (IsOnCooldown(uid, "orgasm")) + return; + + comp.LoveAmount = 0; + + _chatSystem.TrySendInGameICMessage(uid, "кончает", InGameICChatType.Emote, false); + _chatSystem.TryEmoteWithChat(uid, "Moan"); + + if (TryComp(uid, out var humanoidAppearanceComponent) && humanoidAppearanceComponent.Sex == Sex.Male) + SpawnSemen(uid, "Semen", Transform(uid).Coordinates); + + SetCooldown(uid, "orgasm", TimeSpan.FromSeconds(OrgasmCooldownSeconds)); + Dirty(uid, comp); + } + + public void ModifyLove(EntityUid uid, FixedPoint2 amount) + { + if (!TryComp(uid, out var comp)) + return; + + if (IsOnCooldown(uid, "orgasm")) + return; + + comp.LoveAmount += amount; + + if (comp.LoveAmount >= comp.MaxLoveAmount) + { + TryOrgasm(uid); + } + else if (comp.LoveAmount > comp.MaxLoveAmount) + { + comp.LoveAmount = comp.MaxLoveAmount; + } + + Dirty(uid, comp); + + var ratio = (float)(comp.LoveAmount / comp.MaxLoveAmount).Float(); + + if (ratio >= 0.33f && !HasComp(uid)) + { + var newComp = AddComp(uid); + newComp.FromLoveSystem = true; + Dirty(uid, newComp); + } + else if (ratio < 0.33f && TryComp(uid, out var loveVision) && loveVision.FromLoveSystem) + { + RemComp(uid); + } + } +} diff --git a/Content.Server/_Sunrise/InteractionsPanel/InteractionsPanel.Interactions.cs b/Content.Server/_Sunrise/InteractionsPanel/InteractionsPanel.Interactions.cs index 1039edef301..86423944882 100644 --- a/Content.Server/_Sunrise/InteractionsPanel/InteractionsPanel.Interactions.cs +++ b/Content.Server/_Sunrise/InteractionsPanel/InteractionsPanel.Interactions.cs @@ -1,18 +1,13 @@ using System.Numerics; using Content.Server._Sunrise.PlayerCache; using Content.Server.Chat.Systems; -using Content.Server.Fluids.EntitySystems; -using Content.Shared._Sunrise.Aphrodisiac; using Content.Shared._Sunrise.InteractionsPanel.Data.Components; using Content.Shared._Sunrise.InteractionsPanel.Data.Prototypes; using Content.Shared._Sunrise.InteractionsPanel.Data.UI; using Content.Shared.Chat; -using Content.Shared.Chemistry.Components; using Content.Shared.Clothing; using Content.Shared.Database; -using Content.Shared.FixedPoint; using Content.Shared.Hands; -using Content.Shared.Humanoid; using Content.Shared.Input; using Content.Shared.Verbs; using Robust.Shared.Audio; @@ -27,10 +22,6 @@ namespace Content.Server._Sunrise.InteractionsPanel; public partial class InteractionsPanel { [Dependency] private readonly PlayerCacheManager _playerCacheManager = default!; - [Dependency] private readonly PuddleSystem _puddle = default!; - - private const float LoveDecayRate = 0.5f; - private const float OrgasmCooldownSeconds = 15f; private void InitializeInteractions() { @@ -38,7 +29,7 @@ private void InitializeInteractions() subs => { subs.Event(OnInteractionMessageReceived); - subs.Event(OnUndressMessageReceived); + subs.Event(OnUndressMessageReceived); // Lust-Edit }); SubscribeLocalEvent>(AddInteractionsVerb); @@ -55,17 +46,6 @@ private void InitializeInteractions() .Register(); } - private void OnUndressMessageReceived(Entity ent, ref RequestUndressMessage args) - { - if (_inventory.TryGetSlots(ent, out var slots)) - { - foreach (var slot in slots) - { - _inventory.TryUnequip(ent, slot.Name, true, false, false); - } - } - } - private void TryAutoInteraction(ICommonSession? session) { if (session?.AttachedEntity is not { Valid: true } player || !Exists(player)) @@ -254,119 +234,12 @@ private void OnInteractionMessageReceived(Entity ent, ref SetCooldown(ent.Owner, args.InteractionId, interactionPrototype.Cooldown); } - if (interactionPrototype.LoveUser > 0) - ModifyLove(ent.Owner, interactionPrototype.LoveUser); - - if (interactionPrototype.LoveTarget > 0) - ModifyLove(target.Value, interactionPrototype.LoveTarget); - - ProcessVirginityLoss(ent.Owner, target.Value, interactionPrototype); - - TryEmitMoan(ent.Owner, interactionPrototype.LoveUser, interactionPrototype.UserMoanChance); - TryEmitMoan(target.Value, interactionPrototype.LoveTarget, interactionPrototype.TargetMoanChance); + ProcessInteractionLustEffects(ent.Owner, target.Value, interactionPrototype); // Lust-Edit _log.Add(LogType.Interactions, LogImpact.Medium, $"[InteractionsPanel] {ToPretty(ent.Owner)} использует \"{interactionPrototype.ID}\" на {ToPretty(target.Value)}"); } - private void TryEmitMoan(EntityUid uid, FixedPoint2 loveGain, float chance) - { - if (!_gameTiming.IsFirstTimePredicted) - return; - - if (!_random.Prob(chance)) - return; - - if (!TryComp(uid, out var component)) - return; - - var now = _gameTiming.CurTime; - if (now < component.LastMoanTime + TimeSpan.FromSeconds(5)) - return; - - component.LastMoanTime = now; - Dirty(uid, component); - - _chatSystem.TryEmoteWithChat(uid, "Moan"); - } - - private void ProcessVirginityLoss(EntityUid user, EntityUid target, InteractionPrototype proto) - { - TryLoseVirginity(user, proto.UserVirginityLoss); - TryLoseVirginity(target, proto.TargetVirginityLoss); - } - - private void TryLoseVirginity(EntityUid ent, string type) - { - if (!TryComp(ent, out var comp)) - return; - - if (string.IsNullOrWhiteSpace(type) || type == "none") - return; - - var sex = TryComp(ent, out var humanoid) - ? humanoid.Sex.ToString().ToLowerInvariant() - : "unknown"; - - switch (type.ToLowerInvariant()) - { - case "anal": - if (comp.AnalVirginity == Virginity.Yes) - { - comp.AnalVirginity = Virginity.No; - Dirty(ent, comp); - _chatSystem.TrySendInGameICMessage(ent, "теряет анальную девственность", InGameICChatType.Emote, false); - } - break; - - case "vaginal": - case "female": - if (comp.Virginity == Virginity.Yes && sex == "female") - { - comp.Virginity = Virginity.No; - Dirty(ent, comp); - _chatSystem.TrySendInGameICMessage(ent, "теряет девственность", InGameICChatType.Emote, false); - } - break; - - case "male": - if (comp.Virginity == Virginity.Yes && sex == "male") - { - comp.Virginity = Virginity.No; - Dirty(ent, comp); - _chatSystem.TrySendInGameICMessage(ent, "теряет девственность", InGameICChatType.Emote, false); - } - break; - - case "futanari": - if (comp.Virginity == Virginity.Yes && sex == "futanari") - { - comp.Virginity = Virginity.No; - Dirty(ent, comp); - _chatSystem.TrySendInGameICMessage(ent, "теряет девственность", InGameICChatType.Emote, false); - } - break; - - case "any": - if (comp.Virginity == Virginity.Yes) - { - comp.Virginity = Virginity.No; - Dirty(ent, comp); - _chatSystem.TrySendInGameICMessage(ent, "теряет девственность", InGameICChatType.Emote, false); - } - break; - } - } - - private void SpawnSemen(string prototype, EntityCoordinates coordinates) - { - _puddle.TrySpillAt( - coordinates, - new Solution(prototype, 4f), - out _, - false); - } - private void HandleCustomInteraction( EntityUid user, EntityUid target, @@ -435,97 +308,10 @@ private void UpdateInteractions(float frameTime) base.Update(frameTime); var query = EntityQueryEnumerator(); - while (query.MoveNext(out var uid, out var comp)) + while (query.MoveNext(out var uid, out var comp)) // Lust-Edit { UpdateCooldowns(uid); - UpdateLove(uid, comp, frameTime); - } - } - - private void UpdateLove(EntityUid uid, InteractionsComponent comp, float frameTime) - { - if (comp.LoveAmount <= 0) - { - if (TryComp(uid, out var loveVisionComp) && loveVisionComp.FromLoveSystem) - { - RemComp(uid); - } - return; - } - - comp.LoveAmount -= LoveDecayRate * frameTime; - if (comp.LoveAmount < 0) - comp.LoveAmount = 0; - - Dirty(uid, comp); - - var ratio = (float)(comp.LoveAmount / comp.MaxLoveAmount).Float(); - var hasEffect = HasComp(uid); - - if (ratio >= 0.33f && !hasEffect) - { - var newComp = AddComp(uid); - newComp.FromLoveSystem = true; - Dirty(uid, newComp); - } - else if (ratio < 0.33f && TryComp(uid, out var loveVisionComp) && loveVisionComp.FromLoveSystem) - { - RemComp(uid); - } - } - - private void TryOrgasm(EntityUid uid) - { - if (!TryComp(uid, out var comp)) - return; - - if (IsOnCooldown(uid, "orgasm")) - return; - - comp.LoveAmount = 0; - - _chatSystem.TrySendInGameICMessage(uid, "кончает", InGameICChatType.Emote, false); - _chatSystem.TryEmoteWithChat(uid, "Moan"); - - if (TryComp(uid, out var humanoidAppearanceComponent) && humanoidAppearanceComponent.Sex == Sex.Male) - SpawnSemen("Semen", Transform(uid).Coordinates); - - SetCooldown(uid, "orgasm", TimeSpan.FromSeconds(OrgasmCooldownSeconds)); - Dirty(uid, comp); - } - - public void ModifyLove(EntityUid uid, FixedPoint2 amount) - { - if (!TryComp(uid, out var comp)) - return; - - if (IsOnCooldown(uid, "orgasm")) - return; - - comp.LoveAmount += amount; - - if (comp.LoveAmount >= comp.MaxLoveAmount) - { - TryOrgasm(uid); - } - else if (comp.LoveAmount > comp.MaxLoveAmount) - { - comp.LoveAmount = comp.MaxLoveAmount; - } - - Dirty(uid, comp); - - var ratio = (float)(comp.LoveAmount / comp.MaxLoveAmount).Float(); - - if (ratio >= 0.33f && !HasComp(uid)) - { - var newComp = AddComp(uid); - newComp.FromLoveSystem = true; - Dirty(uid, newComp); - } - else if (ratio < 0.33f && TryComp(uid, out var loveVision) && loveVision.FromLoveSystem) - { - RemComp(uid); + UpdateLove(uid, comp, frameTime); // Lust-Edit } } diff --git a/Resources/Prototypes/_Lust/ERP/Other/semen.yml b/Resources/Prototypes/_Lust/ERP/Other/semen.yml index dfa0d119ead..0568ee55ccd 100644 --- a/Resources/Prototypes/_Lust/ERP/Other/semen.yml +++ b/Resources/Prototypes/_Lust/ERP/Other/semen.yml @@ -21,3 +21,4 @@ reagents: - ReagentId: Semen Quantity: 2 + - type: DnaSubstanceTrace