diff --git a/Content.Shared/_DEN/ReagentProduction/Components/ReagentProducerComponent.cs b/Content.Shared/_DEN/ReagentProduction/Components/ReagentProducerComponent.cs new file mode 100644 index 0000000000..cbff5b03b6 --- /dev/null +++ b/Content.Shared/_DEN/ReagentProduction/Components/ReagentProducerComponent.cs @@ -0,0 +1,25 @@ +using Content.Shared._DEN.ReagentProduction.Prototypes; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; + +namespace Content.Shared._DEN.ReagentProduction.Components; + +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class ReagentProducerComponent : Component +{ + [DataField, AutoNetworkedField] + public List> ProductionTypes = []; + + /// + /// The next time to fill solution + /// + [DataField(customTypeSerializer: typeof(TimeOffsetSerializer))] + public TimeSpan NextUpdate; + + /// + /// The interval between updates. + /// + [DataField] + public TimeSpan UpdateInterval = TimeSpan.FromSeconds(10); +} diff --git a/Content.Shared/_DEN/ReagentProduction/EntitySystems/ReagentProductionSystem.cs b/Content.Shared/_DEN/ReagentProduction/EntitySystems/ReagentProductionSystem.cs new file mode 100644 index 0000000000..68e1ecb667 --- /dev/null +++ b/Content.Shared/_DEN/ReagentProduction/EntitySystems/ReagentProductionSystem.cs @@ -0,0 +1,206 @@ +using System.Globalization; +using Content.Shared._DEN.ReagentProduction.Components; +using Content.Shared._DEN.ReagentProduction.Events; +using Content.Shared._DEN.ReagentProduction.Prototypes; +using Content.Shared.Chemistry.Components; +using Content.Shared.Chemistry.Components.SolutionManager; +using Content.Shared.Chemistry.EntitySystems; +using Content.Shared.DoAfter; +using Content.Shared.FixedPoint; +using Content.Shared.IdentityManagement; +using Content.Shared.Mobs.Systems; +using Content.Shared.Popups; +using Content.Shared.Verbs; +using Robust.Shared.Prototypes; +using Robust.Shared.Timing; +using Enumerable = System.Linq.Enumerable; +using static Content.Shared._DEN.ReagentProduction.Events.ReagentProductionEvents; + +namespace Content.Shared._DEN.ReagentProduction.EntitySystems; + +public sealed class ReagentProductionSystem : EntitySystem +{ + [Dependency] private readonly IGameTiming _gameTiming = default!; + [Dependency] private readonly IPrototypeManager _protoManager = default!; + [Dependency] private readonly MobStateSystem _mobState = default!; + [Dependency] private readonly SharedDoAfterSystem _doAfter = default!; + [Dependency] private readonly SharedPopupSystem _popup = default!; + [Dependency] private readonly SharedSolutionContainerSystem _solutionContainer = default!; + + public static readonly VerbCategory ReagentFillCategory = new("verb-categories-fill", "/Textures/_DEN/Interface/VerbIcons/lewd.svg.192dpi.png"); + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(ProductionTypeAdded); + SubscribeLocalEvent(ProductionTypeRemoved); + + SubscribeLocalEvent>(AddVerbs); + + SubscribeLocalEvent(FinishFillDoAfter); + SubscribeLocalEvent(OnMapInit); + } + + private void OnMapInit(Entity ent, ref MapInitEvent args) + { + ent.Comp.NextUpdate = _gameTiming.CurTime + ent.Comp.UpdateInterval; + } + + public override void Update(float frameTime) + { + base.Update(frameTime); + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out var producerComponent, out _)) + { + // If the mob is dead OR it isnt time for the next update, don't move foward + if (!_mobState.IsAlive(uid) || _gameTiming.CurTime < producerComponent.NextUpdate) + continue; + + producerComponent.NextUpdate += producerComponent.UpdateInterval; + + // for every production type the producer has + foreach (var productionType in Enumerable.Select(producerComponent.ProductionTypes, productionTypeId => _protoManager.Index(productionTypeId))) + { + // ensure there's a solution to add to + _solutionContainer.EnsureSolution(uid, productionType.SolutionName, out var solution, productionType.MaximumCapacity); + + if (solution == null) + continue; + // do some math to figure out how much we can add + var amountToAdd = FixedPoint2.Clamp( + solution.MaxVolume - solution.Volume, + FixedPoint2.Zero, + productionType.UnitsPerProduction); + + if (amountToAdd <= 0) + return; + //and add it :) + solution.AddReagent(productionType.Reagent, amountToAdd); + } + } + } + + private void AddVerbs(Entity container, ref GetVerbsEvent args) + { + var user = args.User; + + if (!args.Using.HasValue || !args.CanInteract || !args.CanAccess) + return; + + if (!TryComp(user, out var producerComp)) + return; + + // Add a verb for every production type the producer has + foreach (var productionTypeId in producerComp.ProductionTypes) + { + if (!_protoManager.TryIndex(productionTypeId, out var productionType) || + !_protoManager.TryIndex(productionType.Reagent, out var reagent)) + continue; + + var verb = new InteractionVerb + { + Category = ReagentFillCategory, + Act = () => StartFillDoAfter((user, producerComp), container, productionTypeId), + Text = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(reagent.LocalizedName), + Priority = -1, + CloseMenu = false, + }; + args.Verbs.Add(verb); + } + } + + private void StartFillDoAfter( + Entity user, + Entity target, + ProtoId productionTypeId + ) + { + var productionType = _protoManager.Index(productionTypeId); + + _doAfter.TryStartDoAfter( + new DoAfterArgs(EntityManager, user, productionType.DoAfterLength, new ReagentProductionFillEvent(productionTypeId), user, target: target) + { + BreakOnMove = true, + BreakOnDropItem = true, + }); + } + + private void FinishFillDoAfter(Entity ent, ref ReagentProductionFillEvent args) + { + if (!_protoManager.TryIndex(args.ProductionType, out var productionType) || args.Target == null || args.Cancelled || args.Handled) + return; + + if (!TryComp(args.Target.Value, out var refillableSolution)) + return; + + if (!_solutionContainer.TryGetSolution(ent.Owner, productionType.SolutionName, out var userSolutionComp)|| + !_solutionContainer.TryGetSolution(args.Target.Value, refillableSolution.Solution, out var targetSolutionComp)) + return; + + var targetSolution = targetSolutionComp.Value.Comp.Solution; + + // If there's no cum to cum you cant cum okay? + if (userSolutionComp.Value.Comp.Solution.Volume <= 0) + { + _popup.PopupPredicted(Loc.GetString(productionType.DryPopup),args.Args.User,args.Args.User); + return; + } + + // Get available volume in target solution + var targetAvailableVolume = targetSolution.MaxVolume - targetSolution.Volume; + + // If theres no room just silently return + if (targetAvailableVolume <= 0) + return; + + // Get amount to add, attempts to add the largest amount with the maximum set from production type + var amountToAdd = + FixedPoint2.Clamp(targetAvailableVolume, FixedPoint2.Zero, productionType.MaximumLoad); + + var split = _solutionContainer.SplitSolution(userSolutionComp.Value, amountToAdd); + var quantity = _solutionContainer.AddSolution(targetSolutionComp.Value, split); + + _popup.PopupPredicted( + Loc.GetString( + productionType.SuccessPopup, + ("amount", quantity), + ("target", Identity.Entity(args.Target.Value, EntityManager))), + args.Args.User, + args.Args.User, + PopupType.Medium); + + args.Handled = true; + } + + public void AddProductionType(EntityUid entity, ReagentProductionTypePrototype prototypeType) + { + EnsureComp(entity); + + RaiseLocalEvent(entity, new ReagentProductionTypeAdded(prototypeType)); + } + + public void RemoveProductionType(EntityUid entity, ReagentProductionTypePrototype prototypeType) + { + EnsureComp(entity); + + RaiseLocalEvent(entity, new ReagentProductionTypeRemoved(prototypeType)); + } + + private void ProductionTypeAdded(Entity ent, ref ReagentProductionTypeAdded args) + { + if (!_protoManager.TryIndex(args.ProductionType, out var productionType)) + return; + + ent.Comp.ProductionTypes.Add(args.ProductionType); + + _solutionContainer.EnsureSolution(ent.Owner, productionType.SolutionName,out _, out var solution, productionType.MaximumCapacity); + solution?.AddReagent(productionType.Reagent, productionType.MaximumCapacity); + } + private void ProductionTypeRemoved(Entity ent, ref ReagentProductionTypeRemoved args) + { + ent.Comp.ProductionTypes.Remove(args.ProductionType); + //If there are no more production types, just remove the component + if (ent.Comp.ProductionTypes.Count == 0) + RemCompDeferred(ent); + } +} diff --git a/Content.Shared/_DEN/ReagentProduction/Events/ReagentProductionEvents.cs b/Content.Shared/_DEN/ReagentProduction/Events/ReagentProductionEvents.cs new file mode 100644 index 0000000000..b705ed3358 --- /dev/null +++ b/Content.Shared/_DEN/ReagentProduction/Events/ReagentProductionEvents.cs @@ -0,0 +1,39 @@ +using Content.Shared._DEN.ReagentProduction.Prototypes; +using Content.Shared.DoAfter; +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization; + + +namespace Content.Shared._DEN.ReagentProduction.Events; + +public sealed class ReagentProductionEvents +{ + [Serializable, NetSerializable,] + public sealed class ReagentProductionTypeAdded(ProtoId productionType) : EntityEventArgs + { + public ProtoId ProductionType { get; } = productionType; + } + + [Serializable, NetSerializable,] + public sealed class ReagentProductionTypeRemoved(ProtoId productionType) : EntityEventArgs + { + public ProtoId ProductionType { get; } = productionType; + } +} + +[Serializable, NetSerializable,] +public sealed partial class ReagentProductionFillEvent : DoAfterEvent +{ + public ProtoId ProductionType; + + public ReagentProductionFillEvent( ProtoId productionType) + { + ProductionType = productionType; + } + + public override DoAfterEvent Clone() + { + return this; + } +} + diff --git a/Content.Shared/_DEN/ReagentProduction/Prototypes/ReagentProductionTypePrototype.cs b/Content.Shared/_DEN/ReagentProduction/Prototypes/ReagentProductionTypePrototype.cs new file mode 100644 index 0000000000..9b0b69071c --- /dev/null +++ b/Content.Shared/_DEN/ReagentProduction/Prototypes/ReagentProductionTypePrototype.cs @@ -0,0 +1,52 @@ +using Content.Shared.Chemistry.Reagent; +using Content.Shared.FixedPoint; +using Robust.Shared.Prototypes; + +namespace Content.Shared._DEN.ReagentProduction.Prototypes; + +[Prototype] +public sealed partial class ReagentProductionTypePrototype : IPrototype +{ + [IdDataField] + public string ID { get; private set; } = default!; + + /// + /// Reagent to produce + /// + [DataField] + public ProtoId Reagent = "Water"; + /// + /// The solution to produce into + /// + [DataField] + public string SolutionName = "balls"; //cum is stored in the balls? + /// + /// Maximum capacity of the solution + /// + [DataField] + public FixedPoint2 MaximumCapacity = 30; + + /// + /// Maximum amount you can expel at once + /// + [DataField] + public FixedPoint2 MaximumLoad = 10; + + [DataField] + public TimeSpan DoAfterLength = TimeSpan.FromSeconds(3); + + /// + /// How many units are produced each update + /// + [DataField] + public FixedPoint2 UnitsPerProduction = 5; + + /// + /// Popup that occurs when your solution is empty + /// + [DataField] + public string DryPopup = "cum-verb-dry"; + + [DataField] + public string SuccessPopup = "cum-verb-success"; +} diff --git a/Content.Shared/_DEN/Traits/TraitFunctions/TraitFunctions.ReagentProduction.cs b/Content.Shared/_DEN/Traits/TraitFunctions/TraitFunctions.ReagentProduction.cs new file mode 100644 index 0000000000..96dfc09b8f --- /dev/null +++ b/Content.Shared/_DEN/Traits/TraitFunctions/TraitFunctions.ReagentProduction.cs @@ -0,0 +1,46 @@ +using Content.Shared._DEN.ReagentProduction.EntitySystems; +using Content.Shared._DEN.ReagentProduction.Prototypes; +using JetBrains.Annotations; +using Robust.Shared.Prototypes; + +namespace Content.Shared._DEN.Traits.TraitFunctions; + +[UsedImplicitly] +public sealed partial class AddReagentProductionTrait : ITraitFunction +{ + /// + /// Reagent Production types this trait provides. + /// + [DataField(required: true)] public List> ProductionTypes { get; private set; } = []; + + [ViewVariables] public List? AddedComponents = null; + + public void OnTraitAdded(EntityUid owner, EntityManager entityManager) + { + + var prototypeManager = IoCManager.Resolve(); + var reagentProduction = entityManager.System(); + + foreach (var productionType in ProductionTypes) + { + if (!prototypeManager.TryIndex(productionType, out var prototype)) + continue; + + reagentProduction.AddProductionType(owner, prototype); + } + } + + public void OnTraitRemoved(EntityUid owner, EntityManager entityManager) + { + var prototypeManager = IoCManager.Resolve(); + var reagentProduction = entityManager.System(); + + foreach (var productionType in ProductionTypes) + { + if (!prototypeManager.TryIndex(productionType, out var prototype)) + continue; + + reagentProduction.RemoveProductionType(owner, prototype); + } + } +} diff --git a/Resources/Locale/en-US/_DEN/guidebook/guides.ftl b/Resources/Locale/en-US/_DEN/guidebook/guides.ftl new file mode 100644 index 0000000000..96cd47026b --- /dev/null +++ b/Resources/Locale/en-US/_DEN/guidebook/guides.ftl @@ -0,0 +1,2 @@ +# Chemical Tabs +guide-entry-lewd = Lewd diff --git a/Resources/Locale/en-US/_DEN/reagents/meta/chemicals.ftl b/Resources/Locale/en-US/_DEN/reagents/meta/chemicals.ftl new file mode 100644 index 0000000000..1ddad48b08 --- /dev/null +++ b/Resources/Locale/en-US/_DEN/reagents/meta/chemicals.ftl @@ -0,0 +1,5 @@ +reagent-name-glycerol = glycerol +reagent-desc-glycerol = A sweet tasting, colorless, and oderless hydrating chemical. + +reagent-name-hydro-cellulose = hydroxyethyl cellulose +reagent-desc-hydro-cellulose = A commonly used thickening agent, often found in foods, lubes, and cosmetics. diff --git a/Resources/Locale/en-US/_DEN/reagents/meta/lewd.ftl b/Resources/Locale/en-US/_DEN/reagents/meta/lewd.ftl new file mode 100644 index 0000000000..828445c3d5 --- /dev/null +++ b/Resources/Locale/en-US/_DEN/reagents/meta/lewd.ftl @@ -0,0 +1,11 @@ +reagent-name-cum = cum +reagent-desc-cum = A sticky cloudy-white liquid. + +reagent-name-nat-lube = natural lubricant +reagent-desc-nat-lube = A slippery clear liquid. + +reagent-name-synth-cum = synthetic cum +reagent-desc-synth-cum = A flavorless lubricant made to look like cum. + +reagent-name-synth-lube = synthetic lube +reagent-desc-synth-lube = Flavorless lubricant, made with maximum slipperyness in mind! Silicon free. diff --git a/Resources/Locale/en-US/_DEN/traits/categories.ftl b/Resources/Locale/en-US/_DEN/traits/categories.ftl index ea2c28cb06..59fc07d97a 100644 --- a/Resources/Locale/en-US/_DEN/traits/categories.ftl +++ b/Resources/Locale/en-US/_DEN/traits/categories.ftl @@ -1,2 +1,3 @@ trait-category-species-morphs = Morphotypes trait-category-species-specific = Species-specific +trait-category-lewd = Lewd diff --git a/Resources/Locale/en-US/_DEN/traits/lewd.ftl b/Resources/Locale/en-US/_DEN/traits/lewd.ftl new file mode 100644 index 0000000000..54263bd518 --- /dev/null +++ b/Resources/Locale/en-US/_DEN/traits/lewd.ftl @@ -0,0 +1,34 @@ +trait-cum-producer-name = Cum Producer +trait-cum-producer-desc = This trait allows you to fill containers (such as beakers) with cum, to suit your roleplay needs. + + Keep server rules in mind and ABSOLUTELY NEVER expose people to lewd reagents without their explicit consent. + This includes, for example, leaving it in public places for others to see, or tricking people into consuming it. + You WILL be banned for breaking this rule. + +trait-synth-cum-producer-name = Synthetic Cum Producer +trait-synth-cum-producer-desc = This trait allows you to fill containers (such as beakers) with synthetic cum, to suit your roleplay needs. + + Keep server rules in mind and ABSOLUTELY NEVER expose people to lewd reagents without their explicit consent. + This includes, for example, leaving it in public places for others to see, or tricking people into consuming it. + You WILL be banned for breaking this rule. + +trait-squirt-producer-name = Natural Lubricant Producer +trait-squirt-producer-desc = This trait allows you to fill containers (such as beakers) with your natural lubricant, to suit your roleplay needs. + + Keep server rules in mind and ABSOLUTELY NEVER expose people to lewd reagents without their explicit consent. + This includes, for example, leaving it in public places for others to see, or tricking people into consuming it. + You WILL be banned for breaking this rule. + +trait-synth-lube-producer-name = Synthetic Lube Producer +trait-synth-lube-producer-desc = This trait allows you to fill containers (such as beakers) with synthetic lube, to suit your roleplay needs. + + Keep server rules in mind and ABSOLUTELY NEVER expose people to lewd reagents without their explicit consent. + This includes, for example, leaving it in public places for others to see, or tricking people into consuming it. + You WILL be banned for breaking this rule. + +trait-milk-producer-name = Breast Milk Producer +trait-milk-producer-desc = This trait allows you to fill containers (such as beakers) with milk, to suit your roleplay needs. + + Keep server rules in mind and ABSOLUTELY NEVER expose people to lewd reagents without their explicit consent. + This includes, for example, leaving it in public places for others to see, or tricking people into consuming it. + You WILL be banned for breaking this rule. diff --git a/Resources/Locale/en-US/_DEN/traits/quirks.ftl b/Resources/Locale/en-US/_DEN/traits/quirks.ftl new file mode 100644 index 0000000000..c585ddeb3d --- /dev/null +++ b/Resources/Locale/en-US/_DEN/traits/quirks.ftl @@ -0,0 +1,2 @@ +trait-honey-producer-name = Honey Stomach +trait-honey-producer-desc = Your abdomen contains an extra stomach that processes nutrients into honey. diff --git a/Resources/Locale/en-US/_DEN/verbs/reagent-production-verbs.ftl b/Resources/Locale/en-US/_DEN/verbs/reagent-production-verbs.ftl new file mode 100644 index 0000000000..4734db5b37 --- /dev/null +++ b/Resources/Locale/en-US/_DEN/verbs/reagent-production-verbs.ftl @@ -0,0 +1,19 @@ +verb-categories-fill = Fill with + +cum-verb-dry = Your cum tank is empty. +cum-verb-success = You fill {THE($target)} with {$amount}u of cum from your cock. + +milk-verb-dry = Your breasts are empty. +milk-verb-success = You fill {THE($target)} with {$amount}u of milk from your breasts. + +squirt-verb-dry = You're too dry. +squirt-verb-success = You fill {THE($target)} with {$amount}u of natural lubricant. + +synth-lube-verb-dry = Your lube tube is empty. +synth-lube-verb-success = You dispense {$amount}u of synthetic lubricant into {THE($target)}. + +synth-cum-verb-dry = Your synthetic balls are empty. +synth-cum-verb-success = You dispense {$amount}u of synthetic cum into {THE($target)}. + +honey-verb-dry = Your honey stomach is empty. +honey-verb-success = You fill {THE($target)} with {$amount}u of honey from your extra stomach. diff --git a/Resources/Prototypes/Guidebook/chemicals.yml b/Resources/Prototypes/Guidebook/chemicals.yml index 730d7b3045..7313c192a9 100644 --- a/Resources/Prototypes/Guidebook/chemicals.yml +++ b/Resources/Prototypes/Guidebook/chemicals.yml @@ -12,6 +12,7 @@ - Botanical - Biological - Special + - Lewd # DEN - Others filterEnabled: True diff --git a/Resources/Prototypes/_DEN/EntityTraits/categories.yml b/Resources/Prototypes/_DEN/EntityTraits/categories.yml index 723ce83024..2f3e085d77 100644 --- a/Resources/Prototypes/_DEN/EntityTraits/categories.yml +++ b/Resources/Prototypes/_DEN/EntityTraits/categories.yml @@ -1,3 +1,4 @@ +# Species - type: traitCategory id: SpeciesMorphs name: trait-category-species-morphs @@ -8,3 +9,10 @@ id: SpeciesSpecific priority: -10 name: trait-category-species-specific + +# Misc +- type: traitCategory + id: Lewd + name: trait-category-lewd + priority: 20 + maxTraitPoints: 3 diff --git a/Resources/Prototypes/_DEN/EntityTraits/lewd.yml b/Resources/Prototypes/_DEN/EntityTraits/lewd.yml new file mode 100644 index 0000000000..480ee70980 --- /dev/null +++ b/Resources/Prototypes/_DEN/EntityTraits/lewd.yml @@ -0,0 +1,56 @@ +# Reagent Production Traits + +- type: entityTrait + id: CumProducer + name: trait-cum-producer-name + description: trait-cum-producer-desc + category: Lewd + cost: 1 + functions: + - !type:AddReagentProductionTrait + productionTypes: + - CumProduction + +- type: entityTrait + id: SyntheticCumProducer + name: trait-synth-cum-producer-name + description: trait-synth-cum-producer-desc + category: Lewd + cost: 1 + functions: + - !type:AddReagentProductionTrait + productionTypes: + - SynthCumProduction + +- type: entityTrait + id: SquirtProducer + name: trait-squirt-producer-name + description: trait-squirt-producer-desc + category: Lewd + cost: 1 + functions: + - !type:AddReagentProductionTrait + productionTypes: + - SquirtProduction + +- type: entityTrait + id: SyntheticLubeProducer + name: trait-synth-lube-producer-name + description: trait-synth-lube-producer-desc + category: Lewd + cost: 1 + functions: + - !type:AddReagentProductionTrait + productionTypes: + - SynthLubeProduction + +- type: entityTrait + id: MilkProducer + name: trait-milk-producer-name + description: trait-milk-producer-desc + category: Lewd + cost: 1 + functions: + - !type:AddReagentProductionTrait + productionTypes: + - BreastMilkProduction diff --git a/Resources/Prototypes/_DEN/EntityTraits/quirks.yml b/Resources/Prototypes/_DEN/EntityTraits/quirks.yml index d03d373ac0..ef69cafb97 100644 --- a/Resources/Prototypes/_DEN/EntityTraits/quirks.yml +++ b/Resources/Prototypes/_DEN/EntityTraits/quirks.yml @@ -42,3 +42,13 @@ - type: DamagedSiliconAccent enableChargeCorruption: false damageAtMaxCorruption: 100 + +#- type: entityTrait +# id: HoneyProducer +# name: trait-honey-producer-name +# description: trait-honey-producer-desc +# category: Quirks +# functions: +# - !type:AddReagentProductionTrait +# productionTypes: +# - HoneyProduction diff --git a/Resources/Prototypes/_DEN/Guidebook/chemicals.yml b/Resources/Prototypes/_DEN/Guidebook/chemicals.yml new file mode 100644 index 0000000000..7caf5c713e --- /dev/null +++ b/Resources/Prototypes/_DEN/Guidebook/chemicals.yml @@ -0,0 +1,5 @@ +- type: guideEntry + id: Lewd + name: guide-entry-lewd + text: "/ServerInfo/Guidebook/_DEN/ChemicalTabs/Lewd.xml" + filterEnabled: True diff --git a/Resources/Prototypes/_DEN/ReagentProduction/production_types.yml b/Resources/Prototypes/_DEN/ReagentProduction/production_types.yml new file mode 100644 index 0000000000..383781336d --- /dev/null +++ b/Resources/Prototypes/_DEN/ReagentProduction/production_types.yml @@ -0,0 +1,64 @@ +- type: reagentProductionType + id: CumProduction + reagent: Cum + solutionName: balls + maximumCapacity: 30 + maximumLoad: 10 + unitsPerProduction: 5 + dryPopup: cum-verb-dry + successPopup: cum-verb-success + +- type: reagentProductionType + id: BreastMilkProduction + reagent: Milk + solutionName: breasts + maximumCapacity: 50 + maximumLoad: 5 + fillTime: 1 + unitsPerProduction: 5 + dryPopup: milk-verb-dry + successPopup: milk-verb-success + +- type: reagentProductionType + id: SquirtProduction + reagent: NaturalLubricant + solutionName: pussy + maximumCapacity: 10 + maximumLoad: 2 + unitsPerProduction: 4 + dryPopup: squirt-verb-dry + successPopup: squirt-verb-success + +# Apparently we don't have honey yet??? fucking bunk. +#- type: reagentProductionType +# id: HoneyProduction +# reagent: Honey +# solutionName: honeyStomach +# maximumCapacity: 50 +# maximumLoad: 5 +# fillTime: 1 +# unitsPerProduction: 5 +# dryPopup: honey-verb-dry +# successPopup: honey-verb-success + +- type: reagentProductionType + id: SynthCumProduction + reagent: SyntheticCum + solutionName: syntheticBalls #I guess???????? + maximumCapacity: 50 + maximumLoad: 10 + fillTime: 3 + unitsPerProduction: 10 + dryPopup: synth-cum-verb-dry + successPopup: synth-cum-verb-success + +- type: reagentProductionType + id: SynthLubeProduction + reagent: SyntheticLubricant + solutionName: syntheticLubeTube #yupppp + maximumCapacity: 70 + maximumLoad: 30 + fillTime: 3 + unitsPerProduction: 2 + dryPopup: synth-lube-verb-dry + successPopup: synth-lube-verb-success diff --git a/Resources/Prototypes/_DEN/Reagents/chemicals.yml b/Resources/Prototypes/_DEN/Reagents/chemicals.yml new file mode 100644 index 0000000000..112025cc18 --- /dev/null +++ b/Resources/Prototypes/_DEN/Reagents/chemicals.yml @@ -0,0 +1,24 @@ +- type: reagent + id: Glycerol + group: Foods + name: reagent-name-glycerol + desc: reagent-desc-glycerol + color: "#E9EAF2" + flavor: sweet + viscosity: 0.35 + physicalDesc: reagent-physical-desc-thick + metabolisms: + Digestion: + effects: + - !type:SatiateThirst + factor: 6 + +- type: reagent + id: HydroxyethylCellulose + color: "#E9EAF2" + group: Foods + name: reagent-name-hydro-cellulose + desc: reagent-desc-hydro-cellulose + flavor: nothing + viscosity: 0.35 + physicalDesc: reagent-physical-desc-thick diff --git a/Resources/Prototypes/_DEN/Reagents/lewd.yml b/Resources/Prototypes/_DEN/Reagents/lewd.yml new file mode 100644 index 0000000000..311eddd7f3 --- /dev/null +++ b/Resources/Prototypes/_DEN/Reagents/lewd.yml @@ -0,0 +1,66 @@ +- type: reagent + id: Cum + name: reagent-name-cum + group: Lewd + desc: reagent-desc-cum + physicalDesc: reagent-physical-desc-sticky + flavor: salty + color: "#ffffff" + viscosity: 0.35 + recognizable: true + evaporationSpeed: 0.3 + metabolisms: + Digestion: + effects: + - !type:SatiateThirst + factor: 0.2 + - !type:SatiateHunger + factor: 1 + footstepSound: + collection: FootstepSticky + params: + volume: 6 + +- type: reagent + id: SyntheticCum + parent: Cum + name: reagent-name-synth-cum + desc: reagent-desc-synth-cum + flavor: nothing + metabolisms: + Digestion: + effects: + - !type:SatiateThirst + factor: 0.1 + +- type: reagent + id: NaturalLubricant + name: reagent-name-nat-lube + desc: reagent-desc-nat-lube + parent: SpaceLube + group: Lewd + physicalDesc: reagent-physical-desc-shiny + flavor: funny + color: "#d6d6d6" + evaporationSpeed: 0.3 + metabolisms: + Digestion: + effects: + - !type:SatiateThirst + factor: 0.3 + footstepSound: + collection: FootstepSticky + params: + volume: 4 + +- type: reagent + id: SyntheticLubricant + parent: NaturalLubricant + name: reagent-name-synth-lube + desc: reagent-desc-synth-lube + flavor: nothing + metabolisms: + Digestion: + effects: + - !type:SatiateThirst + factor: 0.1 diff --git a/Resources/Prototypes/_DEN/Recipes/Reactions/chemicals.yml b/Resources/Prototypes/_DEN/Recipes/Reactions/chemicals.yml new file mode 100644 index 0000000000..5495fa89cb --- /dev/null +++ b/Resources/Prototypes/_DEN/Recipes/Reactions/chemicals.yml @@ -0,0 +1,22 @@ +# This is NOT accurate. +- type: reaction + id: Glycerol + minTemp: 373.15 + reactants: + Water: + amount: 3 + Fat: + amount: 1 + products: + Glycerol: 4 + +- type: reaction + id: HydroxyethylCellulose + reactants: + Cellulose: + amount: 1 + SodiumHydroxide: + amount: 1 + products: + HydroxyethylCellulose: 1 + SodiumHydroxide: 1 diff --git a/Resources/Prototypes/_DEN/Recipes/Reactions/lewd.yml b/Resources/Prototypes/_DEN/Recipes/Reactions/lewd.yml new file mode 100644 index 0000000000..9dfc5919bc --- /dev/null +++ b/Resources/Prototypes/_DEN/Recipes/Reactions/lewd.yml @@ -0,0 +1,22 @@ +- type: reaction + id: SyntheticLubricant + minTemp: 398.15 + requiredMixerCategories: + - Stir + reactants: + Water: + amount: 2 + Glycerol: + amount: 1 + products: + SyntheticLubricant: 3 + +- type: reaction + id: SyntheticCum + reactants: + SyntheticLubricant: + amount: 3 + SodiumCarbonate: + amount: 1 + products: + SyntheticCum: 4 diff --git a/Resources/ServerInfo/Guidebook/_DEN/ChemicalTabs/Lewd.xml b/Resources/ServerInfo/Guidebook/_DEN/ChemicalTabs/Lewd.xml new file mode 100644 index 0000000000..aeaaf2f135 --- /dev/null +++ b/Resources/ServerInfo/Guidebook/_DEN/ChemicalTabs/Lewd.xml @@ -0,0 +1,5 @@ + +# Lewd +The reagents listed in this category includes bodily fluids and libido enhancing stimulants. + + diff --git a/Resources/Textures/_DEN/Interface/VerbIcons/ATTRIBUTION.txt b/Resources/Textures/_DEN/Interface/VerbIcons/ATTRIBUTION.txt new file mode 100644 index 0000000000..8d0a923ba2 --- /dev/null +++ b/Resources/Textures/_DEN/Interface/VerbIcons/ATTRIBUTION.txt @@ -0,0 +1,3 @@ +All icons are public domain. + +lewd.svg by portfiend (GitHub) diff --git a/Resources/Textures/_DEN/Interface/VerbIcons/lewd.svg b/Resources/Textures/_DEN/Interface/VerbIcons/lewd.svg new file mode 100644 index 0000000000..1baa326034 --- /dev/null +++ b/Resources/Textures/_DEN/Interface/VerbIcons/lewd.svg @@ -0,0 +1,65 @@ + + + +18+ diff --git a/Resources/Textures/_DEN/Interface/VerbIcons/lewd.svg.192dpi.png b/Resources/Textures/_DEN/Interface/VerbIcons/lewd.svg.192dpi.png new file mode 100644 index 0000000000..2f1ab44a29 Binary files /dev/null and b/Resources/Textures/_DEN/Interface/VerbIcons/lewd.svg.192dpi.png differ diff --git a/Resources/Textures/_DEN/Interface/VerbIcons/lewd.svg.192dpi.png.yml b/Resources/Textures/_DEN/Interface/VerbIcons/lewd.svg.192dpi.png.yml new file mode 100644 index 0000000000..5c43e23305 --- /dev/null +++ b/Resources/Textures/_DEN/Interface/VerbIcons/lewd.svg.192dpi.png.yml @@ -0,0 +1,2 @@ +sample: + filter: true