Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using Content.Shared.Chemistry.Components.SolutionManager;
using Content.Shared.Chemistry.EntitySystems;
using Robust.Shared.Prototypes;
using Content.Shared.StatusIcon.Components;
using Content.Shared._Coyote.AphrodisiacLacedContainerVisibility;
using Content.Client.Consent;

namespace Content.Client._Coyote.AphrodisiacLacedContainerVisibility;

/// <summary>
/// System that shows visual feedback to any container that is injected with a aphrodisiac.
/// </summary>
public sealed class AphrodisiacLacedContainerVisibilitySystem : EntitySystem
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IClientConsentManager _consentManager = default!;

private readonly string _consentId = "AphrodisiacsVisibility";
private bool? _consentOn = null;
private bool ConsentOn
{
get // this is probably wrong xd
{
if (_consentOn == null)
CheckConsent();

if (_consentOn == null)
return false; // failsafe

return _consentOn.Value;
}
set => _consentOn = value;
}

public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<AphrodisiacLacedContainerVisibilityComponent, GetStatusIconsEvent>(OnGetStatusIcon);
_consentManager.OnServerDataLoaded += CheckConsent;

CheckConsent();
}

private void CheckConsent()
{
if (!_consentManager.HasLoaded)
return;

var settings = _consentManager.GetConsent();
ConsentOn = settings.Toggles.TryGetValue(_consentId, out var val) && val == "on";
}

private void OnGetStatusIcon(EntityUid uid, AphrodisiacLacedContainerVisibilityComponent component, ref GetStatusIconsEvent args)
{
if (!component.Laced
|| !ConsentOn)
return;

args.StatusIcons.Add(_prototypeManager.Index(component.Icon));
}
}
16 changes: 15 additions & 1 deletion Content.Server/Botany/Systems/BotanySystem.Seed.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
using Content.Shared.Administration.Logs;
using Content.Shared.Database;
using Content.Server._NF.Contraband.Systems; // Frontier
using Content.Server._Coyote.Helpers; // Coyote
using Content.Shared._Coyote.AphrodisiacLacedContainerVisibility; // Coyote

namespace Content.Server.Botany.Systems;

Expand All @@ -33,6 +35,8 @@ public sealed partial class BotanySystem : EntitySystem
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
[Dependency] private readonly ContrabandTurnInSystem _contraband = default!; // Frontier

private ServerAphrodisiacChecker _helper = new(); // Coyote

public override void Initialize()
{
base.Initialize();
Expand Down Expand Up @@ -168,6 +172,8 @@ public IEnumerable<EntityUid> GenerateProduct(SeedData proto, EntityCoordinates
if (totalYield > 1 || proto.HarvestRepeat != HarvestType.NoRepeat)
proto.Unique = false;

bool seedLaced = _helper.IsSeedLaced(_prototypeManager, proto); // Coyote: Check if seed has aphrodisiacs

for (var i = 0; i < totalYield; i++)
{
var product = _robustRandom.Pick(proto.ProductPrototypes);
Expand All @@ -191,6 +197,15 @@ public IEnumerable<EntityUid> GenerateProduct(SeedData proto, EntityCoordinates
_metaData.SetEntityDescription(entity,
metaData.EntityDescription + " " + Loc.GetString("botany-mysterious-description-addon"), metaData);
}

// Coyote start: Ensure component if laced
if (seedLaced)
{
var aphroVisibility = EnsureComp<AphrodisiacLacedContainerVisibilityComponent>(entity);
aphroVisibility.Laced = true;
aphroVisibility.Solution = produce.SolutionName;
}
// Coyote end
}

return products;
Expand All @@ -200,6 +215,5 @@ public bool CanHarvest(SeedData proto, EntityUid? held = null)
{
return !proto.Ligneous || proto.Ligneous && held != null && HasComp<SharpComponent>(held);
}

#endregion
}
1 change: 0 additions & 1 deletion Content.Server/Chemistry/EntitySystems/InjectorSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using Content.Shared.Chemistry.Components;
using Content.Shared.Chemistry.Components.SolutionManager;
using Content.Shared.Chemistry.EntitySystems;
using Content.Shared.Chemistry.Reagent;
using Content.Shared.Database;
using Content.Shared.DoAfter;
using Content.Shared.FixedPoint;
Expand Down
9 changes: 9 additions & 0 deletions Content.Server/Nutrition/EntitySystems/FoodSequenceSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
using Content.Server._NF.Kitchen.Components; // Frontier
using Content.Shared._Coyote.AphrodisiacLacedContainerVisibility; // Coyote

namespace Content.Server.Nutrition.EntitySystems;

Expand Down Expand Up @@ -270,5 +271,13 @@ private void MergeTags(EntityUid start, EntityUid element)
if (HasComp<MothFoodComponent>(element))
EnsureComp<MothFoodComponent>(start);
// End Frontier

// Coyote: Ensure the aphro visibility component if it exists, and pass over laced value
if (TryComp<AphrodisiacLacedContainerVisibilityComponent>(element, out var elementComp))
{
var startComp = EnsureComp<AphrodisiacLacedContainerVisibilityComponent>(start);
startComp.Laced = elementComp.Laced;
}
// Coyote
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using Content.Shared.Chemistry.Components.SolutionManager;
using Content.Shared.Chemistry.EntitySystems;
using Content.Shared.Chemistry.Reagent;
using Robust.Shared.Prototypes;
using Content.Server._Coyote.Helpers;
using Content.Shared.SSDIndicator;
using Content.Shared.StatusIcon.Components;
using Content.Shared._Coyote.AphrodisiacLacedContainerVisibility;
using Content.Shared.Chemistry.Components;

namespace Content.Server._Coyote.AphrodisiacLacedContainerVisibility;

/// <summary>
/// System that shows visual feedback to any container that is injected with a aphrodisiac.
/// </summary>
public sealed class AphrodisiacLacedContainerVisibilitySystem : EntitySystem
{
[Dependency] private readonly SharedSolutionContainerSystem _solutionContainerSystem = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;

private ServerAphrodisiacChecker _helper = new();

public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<AphrodisiacLacedContainerVisibilityComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<AphrodisiacLacedContainerVisibilityComponent, SolutionContainerChangedEvent>(OnSolutionChange);
}

public void OnMapInit(Entity<AphrodisiacLacedContainerVisibilityComponent> entity, ref MapInitEvent args)
{
EnsureComp<StatusIconComponent>(entity);
CheckForAphrodisiacs(entity);
}

public void OnSolutionChange(Entity<AphrodisiacLacedContainerVisibilityComponent> entity, ref SolutionContainerChangedEvent args)
{
if (args.Solution != null)
CheckForAphrodisiacs(entity, args.Solution);
else
CheckForAphrodisiacs(entity);
}

public void CheckForAphrodisiacs(Entity<AphrodisiacLacedContainerVisibilityComponent> entity)
{
if (!EntityManager.HasComponent<SolutionContainerManagerComponent>(entity))
return;

if (_solutionContainerSystem.TryGetSolution(entity.Owner, entity.Comp.Solution, out _, out var solution))
{
CheckForAphrodisiacs(entity, solution);
}
}

// Override to skip solution TryGet.
private void CheckForAphrodisiacs(Entity<AphrodisiacLacedContainerVisibilityComponent> entity, Solution solution)
{
var laced = _helper.CheckForAphrodisiacs(_prototypeManager, solution);
entity.Comp.Laced = laced;
}
}
24 changes: 24 additions & 0 deletions Content.Server/_Coyote/Helpers/ServerAphrodisiacChecker.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@

using Content.Server.Botany;
using Content.Shared._Coyote.Helpers;
using Robust.Shared.Prototypes;

namespace Content.Server._Coyote.Helpers;

// We use this helper server-side for helping with specific server side issues (e.g.checking reagents in seeds, which is server-side only.)
// Sealed cause we don't need more inheritance atop of this.
public sealed class ServerAphrodisiacChecker : SharedAphrodisiacChecker
{
public ServerAphrodisiacChecker() : base() { }

public bool IsSeedLaced(IPrototypeManager prototypeManager, SeedData seed)
{
foreach ((var reagent, _) in seed.Chemicals)
{
if (IsReagentAphrodisiac(prototypeManager, reagent))
return true;
}

return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
using Robust.Shared.Map;
using Robust.Shared.Network;
using Dependency = Robust.Shared.IoC.DependencyAttribute;
using Content.Shared._Coyote.Helpers; // Coyote
using Content.Shared._Coyote.AphrodisiacLacedContainerVisibility; // Coyote

namespace Content.Shared.Chemistry.EntitySystems;

Expand Down Expand Up @@ -70,6 +72,8 @@ public abstract partial class SharedSolutionContainerSystem : EntitySystem
[Dependency] protected readonly MetaDataSystem MetaDataSys = default!;
[Dependency] protected readonly INetManager NetManager = default!;

private SharedAphrodisiacChecker _helper = new(); // Coyote

public override void Initialize()
{
base.Initialize();
Expand Down Expand Up @@ -324,6 +328,16 @@ public void UpdateChemicals(Entity<SolutionComponent> soln, bool needsReactionsP
RaiseLocalEvent(uid, ref overflowEv);
}

// Coyote start: Ensure component on container if there is aphrodisiacs on the solution
if (_helper.CheckForAphrodisiacs(PrototypeManager, solution)
&& TryComp<ContainedSolutionComponent>(soln.Owner, out var containedSolution))
{
var lacedComp = EnsureComp<AphrodisiacLacedContainerVisibilityComponent>(containedSolution.Container);
lacedComp.Laced = true;
lacedComp.Solution = solution.Name ?? "";
}
// Coyote end

UpdateAppearance((uid, comp, null));

var changedEv = new SolutionChangedEvent(soln);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using Content.Shared.StatusIcon;
using Robust.Shared.Prototypes;
using Robust.Shared.GameStates;

namespace Content.Shared._Coyote.AphrodisiacLacedContainerVisibility;

/// <summary>
/// Component that keeps track of solution containers to see if they have been injected by horny juice.
/// </summary>
[RegisterComponent, NetworkedComponent]
[AutoGenerateComponentState]
public sealed partial class AphrodisiacLacedContainerVisibilityComponent : Component
{
/// <summary>
/// The name of the solution of which to check for HORNY
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
[DataField("solution")]
[AutoNetworkedField]
public string Solution { get; set; } = string.Empty;

// REVIEW: Maybe instead of the laced bool, I just remove the component using its own system when the aphro runs out.
// <summary>
// If this entity has been laced.
// </summary>
[ViewVariables(VVAccess.ReadWrite)]
[DataField("laced")]
[AutoNetworkedField]
public bool Laced { get; set; } = false;

// <summary>
// The icon to be used for the status effect.
// </summary>
[ViewVariables(VVAccess.ReadWrite)]
[DataField("icon")]
[AutoNetworkedField]
public ProtoId<SsdIconPrototype> Icon = "AphroLacedSSDIcon";
}
37 changes: 37 additions & 0 deletions Content.Shared/_Coyote/Helpers/ServerAphrodisiacChecker.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@

using Content.Shared.Chemistry.Components;
using Content.Shared.Chemistry.Reagent;
using Robust.Shared.Prototypes;

namespace Content.Shared._Coyote.Helpers;

// Base helper class for all related aphrodisiac checking.
// Virtual cause we need a server-side version of it, and might need a client-side one in the future.
[Virtual]
public class SharedAphrodisiacChecker
{
private readonly string _aphrodisiacGroup = "Aphrodisiac";
private readonly string _aphrodisiacDrinkGroup = "AphrodisiacDrink";

public SharedAphrodisiacChecker() { }
public bool CheckForAphrodisiacs(IPrototypeManager prototypeManager, Solution solution)
{
foreach (var (reagent, _) in solution.Contents)
{
if (IsReagentAphrodisiac(prototypeManager, reagent))
{
return true;
}
}

return false;
}

public bool IsReagentAphrodisiac(IPrototypeManager prototypeManager, string reagent) => IsReagentAphrodisiac(prototypeManager, new ReagentId(reagent, null));

public bool IsReagentAphrodisiac(IPrototypeManager prototypeManager, ReagentId reagent)
{
var prototype = prototypeManager.Index<ReagentPrototype>(reagent.Prototype);
return prototype.Group == _aphrodisiacGroup || prototype.Group == _aphrodisiacDrinkGroup;
}
}
3 changes: 3 additions & 0 deletions Resources/Locale/en-US/Blep/consent.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ consent-GenitalMarkings-desc = Turn this on to allow showing/hiding genital mark
consent-Aphrodisiacs-name = Be affected by aphrodisiacs
consent-Aphrodisiacs-desc = Turn this on to be affected by pomelustine, philterex, and libidozenithine.

consent-AphrodisiacsVisibility-name = See if ingestables are laced
consent-AphrodisiacsVisibility-desc = Turn this on to have an indicator show on containers and foods if they have aphrodisiacs in them.

consent-SizeManipulation-name = Allow size manipulation
consent-SizeManipulation-desc = Turn this on to allow yourself to be grown or shrunk by size manipulation.

Expand Down
2 changes: 2 additions & 0 deletions Resources/Prototypes/Body/Organs/Animal/animal.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
groups:
- id: Food
- id: Drink
- id: AphrodisiacDrink # Coyote edit; Necessary to detect aphrodisiac injected solutions.
- type: Item
size: Small
heldPrefix: stomach
Expand Down Expand Up @@ -144,6 +145,7 @@
- id: Cryogenic # Frontier
- id: Poison
- id: Narcotic
- id: Aphrodisiac # Coyote edit; Necessary to detect aphrodisiac injected solutions.
- type: Item
size: Small
heldPrefix: heart
Expand Down
2 changes: 2 additions & 0 deletions Resources/Prototypes/Body/Organs/Animal/slimes.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
- id: Poison
- id: Narcotic
- id: Alcohol
- id: Aphrodisiac # Coyote edit; Necessary to detect aphrodisiac injected solutions.
- id: AphrodisiacDrink # Coyote edit; Necessary to detect aphrodisiac injected solutions.
rateModifier: 0.2
- type: SolutionContainerManager
solutions:
Expand Down
1 change: 1 addition & 0 deletions Resources/Prototypes/Body/Organs/arachnid.yml
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@
- id: Cryogenic # Frontier
- id: Poison
- id: Narcotic
- id: Aphrodisiac # Coyote edit; Necessary to detect aphrodisiac injected solutions.

- type: entity
id: OrganArachnidLiver
Expand Down
Loading
Loading