From bb6b95a1195ebffc7a93fce448e57e7c5fdb37e5 Mon Sep 17 00:00:00 2001 From: Bug Date: Wed, 10 Jun 2026 20:12:58 -0400 Subject: [PATCH 1/5] Attempting to get prizeball trait working --- .../Systems/PrizeballLayingSystem.cs | 9 + .../EntityEffects/Effects/Redeem.cs | 26 +++ .../Systems/PrizeballLayingSystem.cs | 208 ++++++++++++++++++ .../Components/PrizeballLayingComponent.cs | 129 +++++++++++ .../Systems/SharedPrizeballLayingSystem.cs | 51 +++++ .../Traits/Events/PrizeballLayingEvents.cs | 15 ++ .../en-US/_HL/flavors/flavor-profiles.ftl | 1 + Resources/Locale/en-US/_HL/reagents/fun.ftl | 3 + Resources/Locale/en-US/_HL/traits/traits.ftl | 3 + .../en-US/actions/actions/prizeball-lay.ftl | 23 ++ Resources/Prototypes/_HL/Actions/types.yml | 12 + Resources/Prototypes/_HL/Reagents/fun.yml | 14 ++ Resources/Prototypes/_HL/Traits/lewd.yml | 16 ++ .../_NF/Entities/Objects/Fun/prizeticket.yml | 15 ++ 14 files changed, 525 insertions(+) create mode 100644 Content.Client/_HL/LewdEggLaying/Systems/PrizeballLayingSystem.cs create mode 100644 Content.Server/_Hardlight/EntityEffects/Effects/Redeem.cs create mode 100644 Content.Server/_Hardlight/LewdEgglaying/Systems/PrizeballLayingSystem.cs create mode 100644 Content.Shared/_Hardlight/LewdEgglaying/Components/PrizeballLayingComponent.cs create mode 100644 Content.Shared/_Hardlight/LewdEgglaying/Systems/SharedPrizeballLayingSystem.cs create mode 100644 Content.Shared/_Hardlight/Traits/Events/PrizeballLayingEvents.cs create mode 100644 Resources/Locale/en-US/actions/actions/prizeball-lay.ftl diff --git a/Content.Client/_HL/LewdEggLaying/Systems/PrizeballLayingSystem.cs b/Content.Client/_HL/LewdEggLaying/Systems/PrizeballLayingSystem.cs new file mode 100644 index 00000000000..d52fdede397 --- /dev/null +++ b/Content.Client/_HL/LewdEggLaying/Systems/PrizeballLayingSystem.cs @@ -0,0 +1,9 @@ +using Content.Shared.Animals.Systems; + +namespace Content.Client.Animals.Systems; + +// HL: This is just an empty class so that the matching code in SharedPrizeballLayingSystem can run on the client. +public sealed class PrizeballLayingSystem : SharedPrizeballLayingSystem +{ + +} \ No newline at end of file diff --git a/Content.Server/_Hardlight/EntityEffects/Effects/Redeem.cs b/Content.Server/_Hardlight/EntityEffects/Effects/Redeem.cs new file mode 100644 index 00000000000..e6b72b6531a --- /dev/null +++ b/Content.Server/_Hardlight/EntityEffects/Effects/Redeem.cs @@ -0,0 +1,26 @@ +using Content.Shared.EntityEffects; +using Content.Shared.Animals.Components; // HL: Moved the LewdEggLayingComponent to Shared +using Content.Server.Animals.Systems; +using Robust.Shared.Prototypes; + +namespace Content.Server.EntityEffects.Effects +{ + /// + /// Attempts to find a prizeball laying component and triggers its effects + /// + public sealed partial class Redeem : EntityEffect + { + public override void Effect(EntityEffectBaseArgs args) + { + var entman = args.EntityManager; + if (entman.TryGetComponent(args.TargetEntity, out PrizeballLayingComponent? egglaying)) + { + float amt = (args is EntityEffectReagentArgs reagentArgs) ? (float) reagentArgs.Quantity : 1.0f; + entman.System().Redeem(args.TargetEntity, amt, egglaying); + } + } + + protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys) + => Loc.GetString("reagent-effect-guidebook-redeem", ("chance", Probability)); + } +} diff --git a/Content.Server/_Hardlight/LewdEgglaying/Systems/PrizeballLayingSystem.cs b/Content.Server/_Hardlight/LewdEgglaying/Systems/PrizeballLayingSystem.cs new file mode 100644 index 00000000000..f0e67e51821 --- /dev/null +++ b/Content.Server/_Hardlight/LewdEgglaying/Systems/PrizeballLayingSystem.cs @@ -0,0 +1,208 @@ +using Content.Shared.Actions; +using Content.Shared.DoAfter; +using Content.Shared.IdentityManagement; +using Content.Shared.Movement.Systems; +using Content.Shared.Storage; +using Content.Shared.Traits.Events; +using Content.Server.Popups; +using Robust.Server.Audio; +using Robust.Shared.Player; +using Robust.Shared.Random; +using Content.Shared.Animals.Systems; +using Content.Shared.Animals.Components; + +namespace Content.Server.Animals.Systems; + +/// +/// Gives the ability to lay pballs/other things; +/// produces endlessly if the owner does not have a HungerComponent. +/// +public sealed class PrizeballLayingSystem : SharedPrizeballLayingSystem // HL: We've changed the base to SharedPrizeballLayingSystem so we can run the Verb drawing on the client. +{ + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly SharedActionsSystem _actions = default!; + [Dependency] private readonly SharedDoAfterSystem _doAfter = default!; + [Dependency] private readonly AudioSystem _audio = default!; + [Dependency] private readonly PopupSystem _popup = default!; + [Dependency] private readonly MovementSpeedModifierSystem _movementSpeedModifier = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnHostShutdown); + SubscribeLocalEvent(OnPballLayingAction); + SubscribeLocalEvent(OnPballLayingDoAfter); + SubscribeLocalEvent(OnPballLayingInsideDoAfter); + SubscribeLocalEvent(OnRefreshMovespeed); + } + + private void OnHostShutdown(EntityUid user, PrizeballLayingComponent pballLaying, ComponentShutdown args) + { + _actions.RemoveAction(user, pballLaying.Action); + } + + protected override void AttemptLayInside(Entity user, EntityUid target) + { + var doargs = new DoAfterArgs(EntityManager, user.Owner, user.Comp.PballLayDelay, new PrizeballLayingInsideDoAfterEvent(), user.Owner, target) + { + BreakOnMove = true, + BlockDuplicate = true, + BreakOnDamage = true, + CancelDuplicate = true, + }; + + _popup.PopupEntity(Loc.GetString("action-popup-lay-pball-inside-start", ("entity", Identity.Entity(user.Owner, EntityManager)), ("target", Identity.Entity(target, EntityManager))), user); + _doAfter.TryStartDoAfter(doargs); + } + + private void OnRefreshMovespeed(EntityUid user, PrizeballLayingComponent pballLaying, RefreshMovementSpeedModifiersEvent args) + { + if (pballLaying.isHeavyOfPballs()) + { + args.ModifySpeed(pballLaying.PballSlowMult, pballLaying.PballSlowMult); + } + } + + private void OnPballLayingAction(EntityUid user, PrizeballLayingComponent pballLaying, PrizeballLayingActionEvent args) + { + if (!pballLaying.hasPballs()) + { + _popup.PopupEntity(Loc.GetString("action-popup-lay-pball-no-pballs"), user, user); + return; + } + + var doAfter = new DoAfterArgs(EntityManager, user, pballLaying.PballLayDelay, new PrizeballLayingDoAfterEvent(), user) + { + BreakOnMove = true, + BlockDuplicate = true, + BreakOnDamage = true, + CancelDuplicate = true, + }; + + _popup.PopupEntity(Loc.GetString("action-popup-lay-pball-user-start"), user, user); + _doAfter.TryStartDoAfter(doAfter); + } + + public void Redeem(EntityUid user, float amount, PrizeballLayingComponent? pballLaying = null) + { + if (!Resolve(user, ref pballLaying) || pballLaying.Temporary) + return; + + amount *= pballLaying.ProductionMult; + + bool hasPballsBefore = pballLaying.hasPballs(); + bool isHeavyBefore = pballLaying.isHeavyOfPballs(); + bool isFullBefore = pballLaying.isFullOfPballs(); + + AddPballs(user, pballLaying, amount); + + if(pballLaying.hasPballs() && !hasPballsBefore) + { + _popup.PopupEntity(Loc.GetString("action-popup-lay-pball-firstpball"), user, user); + _actions.AddAction(user, ref pballLaying.Action, pballLaying.ActionPrototype); + } + else if(pballLaying.isHeavyOfPballs() && !isHeavyBefore) + { + _movementSpeedModifier.RefreshMovementSpeedModifiers(user); + _popup.PopupEntity(Loc.GetString("action-popup-lay-pball-heavypballs"), user, user); + } + else if(pballLaying.isFullOfPballs() && !isFullBefore) + { + _popup.PopupEntity(Loc.GetString("action-popup-lay-pball-fullpballs"), user, user); + } + else if(pballLaying.doFlavor()) + { + _popup.PopupEntity(Loc.GetString(_random.Pick(pballLaying.FlavorMessages)), user, user); + } + } + + private void OnPballLayingInsideDoAfter(EntityUid user, PrizeballLayingComponent myPballs, PrizeballLayingInsideDoAfterEvent args) + { + if (args.Cancelled || args.Handled || args.Target == null) + return; + + args.Handled = true; + + if (myPballs.Deleted || !myPballs.hasPballs()) + { + _popup.PopupEntity(Loc.GetString("action-popup-lay-pball-nopballs"), user, user); + return; + } + var target = args.Target.Value; + + _audio.PlayPvs(myPballs.PballLaySound, user); + + if (!TryComp(target, out var theirPballs)) + { + theirPballs = (PrizeballLayingComponent)Factory.GetComponent(Factory.GetComponentName()); + EntityManager.AddComponent(target, theirPballs); + theirPballs.makeTempFrom(myPballs); + _actions.AddAction(target, ref theirPballs.Action, theirPballs.ActionPrototype); + } + + /// HL: Moved the AddPballs to a helper function so we can share the pballs count in the component to the client + AddPballs(user, myPballs, -1.0f); + AddPballs(target, theirPballs, 1.0f); + + _movementSpeedModifier.RefreshMovementSpeedModifiers(user); + _movementSpeedModifier.RefreshMovementSpeedModifiers(target); + + if(myPballs.hasPballs()) + { + _popup.PopupEntity(Loc.GetString("action-popup-lay-pball-inside-give-more", ("entity", Identity.Entity(target, EntityManager))), user, user); + _popup.PopupEntity(Loc.GetString("action-popup-lay-pball-inside-receive-more", ("entity", Identity.Entity(user, EntityManager))), target, target); + args.Repeat = true; + } + else + { + _popup.PopupEntity(Loc.GetString("action-popup-lay-pball-inside-give-done", ("entity", Identity.Entity(target, EntityManager))), user, user); + _popup.PopupEntity(Loc.GetString("action-popup-lay-pball-inside-receive-done", ("entity", Identity.Entity(user, EntityManager))), target, target); + + if(myPballs.Temporary) + EntityManager.RemoveComponent(user); + else + _actions.RemoveAction(user, myPballs.Action); + } + } + + private void OnPballLayingDoAfter(EntityUid user, PrizeballLayingComponent pballLaying, PrizeballLayingDoAfterEvent args) + { + if (args.Cancelled || args.Handled) + return; + + args.Handled = true; + + if (pballLaying.Deleted || !pballLaying.hasPballs()) + { + _popup.PopupEntity(Loc.GetString("action-popup-lay-pball-nopballs"), user, user); + return; + } + + foreach (var ent in EntitySpawnCollection.GetSpawns(pballLaying.EggSpawn, _random)) + { + Spawn(ent, Transform(user).Coordinates); + } + + _audio.PlayPvs(pballLaying.PballLaySound, user); + + pballLaying.addPballs(-1.0f); + _movementSpeedModifier.RefreshMovementSpeedModifiers(user); + + if(pballLaying.hasPballs()) + { + _popup.PopupEntity(Loc.GetString("action-popup-lay-pball-user-more"), user, user); + args.Repeat = true; + } + else + { + _popup.PopupEntity(Loc.GetString("action-popup-lay-pball-user-done"), user, user); + + if(pballLaying.Temporary) + EntityManager.RemoveComponent(user); + else + _actions.RemoveAction(user, pballLaying.Action); + } + _popup.PopupEntity(Loc.GetString("action-popup-lay-pball-others", ("entity", user)), user, Filter.PvsExcept(user), true); + } +} diff --git a/Content.Shared/_Hardlight/LewdEgglaying/Components/PrizeballLayingComponent.cs b/Content.Shared/_Hardlight/LewdEgglaying/Components/PrizeballLayingComponent.cs new file mode 100644 index 00000000000..ec69567c098 --- /dev/null +++ b/Content.Shared/_Hardlight/LewdEgglaying/Components/PrizeballLayingComponent.cs @@ -0,0 +1,129 @@ +using Content.Shared.Storage; +using Robust.Shared.Audio; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; +using Content.Shared.Animals.Systems; + +namespace Content.Shared.Animals.Components; // HL: Moved this to Shared so the client can use it for verb drawing. + +/// +/// This component handles prizeball laying for the prizeball layer trait +/// + +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(fieldDeltas: true)] +public sealed partial class PrizeballLayingComponent : Component +{ + [DataField] + public EntProtoId ActionPrototype = "ActionLayPrizeball"; + + [DataField] + public EntityUid? Action; + + /// + /// Messages while producing prizeballs + /// + [DataField] + public IReadOnlyList FlavorMessages = new[] + { + "action-popup-lay-pball-flavor-1", + "action-popup-lay-pball-flavor-2", + "action-popup-lay-pball-flavor-3", + "action-popup-lay-pball-flavor-4" + }; + + /// + /// The item that gets laid/spawned, retrieved from animal prototype. + /// + [DataField(required: true)] + public List EggSpawn = new(); + + /// + /// The sound played when prizeball pops out + /// + [DataField] + public SoundSpecifier PballLaySound = new SoundPathSpecifier("/Audio/Machines/machine_vend.ogg"); + + /// + /// How many prizeballs produced per unit of cum + /// + [DataField] + public float ProductionMult = 0.2f; + + /// + /// How many prizeballs between each flavor text + /// + [DataField] + public float FlavorFreq = 6.0f; + + /// + /// The number of pballs when movespeed is slowed + /// + [DataField] + public float PballSlowThreshold = 10; + + /// + /// The max number of prizeballs you can hold + /// + [DataField] + public float MaxPballs = 24; + + /// + /// How much the user is slowed by prizeballs + /// + [DataField] + public float PballSlowMult = 0.5f; + + /// + /// How long it takes for the prizeball to come out + /// + [DataField] + public float PballLayDelay = 5.0f; + + /// + /// The number of prizeballs in your belly + /// + [DataField, AutoNetworkedField] + public float pballs = 0; + + /// + /// The number of prizeballs produced since last flavor text + /// + public float pballsFlavorAccum = 0; + + /// + /// The number of prizeballs produced since last flavor text + /// + public bool Temporary = false; + public bool hasPballs() + { + return pballs >= 1.0f; + } + public bool isHeavyOfPballs() + { + return pballs >= PballSlowThreshold; + } + public bool isFullOfPballs() + { + return pballs >= MaxPballs; + } + public bool doFlavor() + { + if(pballsFlavorAccum >= FlavorFreq) + { + pballsFlavorAccum -= FlavorFreq; + return true; + } + return false; + } + public void makeTempFrom(PrizeballLayingComponent other) + { + FlavorMessages = other.FlavorMessages; + EggSpawn = other.EggSpawn; + PballLaySound = other.PballLaySound; + PballSlowThreshold = other.PballSlowThreshold; + MaxPballs = other.MaxPballs; + PballSlowMult = other.PballSlowMult; + PballLayDelay = other.PballLayDelay; + Temporary = true; + } +} \ No newline at end of file diff --git a/Content.Shared/_Hardlight/LewdEgglaying/Systems/SharedPrizeballLayingSystem.cs b/Content.Shared/_Hardlight/LewdEgglaying/Systems/SharedPrizeballLayingSystem.cs new file mode 100644 index 00000000000..002ae5891f3 --- /dev/null +++ b/Content.Shared/_Hardlight/LewdEgglaying/Systems/SharedPrizeballLayingSystem.cs @@ -0,0 +1,51 @@ +using Content.Shared.Verbs; +using Content.Shared.Animals.Components; +using Robust.Shared.Player; + +namespace Content.Shared.Animals.Systems; + +/* + HL + Moved LewdEggLayingSystem to a shared system so that the AddVerb can be called clientside to deal with lag when right-clicking objects/players. + LewdEggLayingComponent is now shared, and we had to network the eggs count. + We also had to move the AddEgg to a helper function to keep any processing code out of the Component and in the Shared space + The LewdEggLayingSystem on the Server is mostly handling everything, with an empty class of the same name on the Client so that the client can run the AddVerb code locally. +*/ +public abstract class SharedPrizeballLayingSystem : EntitySystem +{ + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent>(AddLayPballInsideVerb); + } + + private void AddLayPballInsideVerb(Entity user, ref GetVerbsEvent args) + { + // Todo figure out how to only make verb appear for player mobs + var target = args.Target; + if (!args.CanInteract || user.Owner == target || !user.Comp.hasPballs() || !TryComp(target, out ActorComponent? actor)) + return; + + InnateVerb verbLayPball = new() + { + Act = () => AttemptLayInside(user, target), + Text = Loc.GetString($"lay-pball-inside-verb-get-text"), + Priority = 1 + }; + args.Verbs.Add(verbLayPball); + } + + protected void AddPballs(EntityUid uid, PrizeballLayingComponent comp, float amt) + { + comp.pballs = Math.Clamp(comp.pballs + amt, 0, comp.MaxPballs); + if (amt > 0) + { + comp.pballsFlavorAccum += amt; + } + DirtyField(uid, comp, nameof(PrizeballLayingComponent.pballs)); + } + + protected virtual void AttemptLayInside(Entity user, EntityUid target) { } + +} \ No newline at end of file diff --git a/Content.Shared/_Hardlight/Traits/Events/PrizeballLayingEvents.cs b/Content.Shared/_Hardlight/Traits/Events/PrizeballLayingEvents.cs new file mode 100644 index 00000000000..fb738c3627e --- /dev/null +++ b/Content.Shared/_Hardlight/Traits/Events/PrizeballLayingEvents.cs @@ -0,0 +1,15 @@ +using Content.Shared.DoAfter; +using Robust.Shared.Serialization; +using Content.Shared.Actions; + +namespace Content.Shared.Traits.Events; + +public sealed partial class PrizeballLayingActionEvent : InstantActionEvent { } + +[Serializable, NetSerializable] +public sealed partial class PrizeballLayingDoAfterEvent : SimpleDoAfterEvent { } + +[Serializable, NetSerializable] +public sealed partial class PrizeballLayingInsideDoAfterEvent : SimpleDoAfterEvent { } + + diff --git a/Resources/Locale/en-US/_HL/flavors/flavor-profiles.ftl b/Resources/Locale/en-US/_HL/flavors/flavor-profiles.ftl index c932f66e8a9..0be60a8a527 100644 --- a/Resources/Locale/en-US/_HL/flavors/flavor-profiles.ftl +++ b/Resources/Locale/en-US/_HL/flavors/flavor-profiles.ftl @@ -1,4 +1,5 @@ flavor-woof = like woof +flavor-highscore = Like a sweet sweet highscore. flavor-complex-tha-slop = like processed shit flavor-complex-old-socks = like old socks diff --git a/Resources/Locale/en-US/_HL/reagents/fun.ftl b/Resources/Locale/en-US/_HL/reagents/fun.ftl index adb5db94dcd..2aac28ecff5 100644 --- a/Resources/Locale/en-US/_HL/reagents/fun.ftl +++ b/Resources/Locale/en-US/_HL/reagents/fun.ftl @@ -4,3 +4,6 @@ reagent-name-juice-that-makes-you-bark = juice that makes you Bark reagent-desc-juice-that-makes-you-bark = Pure essence of vulp plush. Makes you Woof! +### juice that makes you Prizeball +reagent-name-prizeball-juice = Juice that makes you Prizeball +reagent-desc-prizeball-juice = You ate. . . Tickets. . ? \ No newline at end of file diff --git a/Resources/Locale/en-US/_HL/traits/traits.ftl b/Resources/Locale/en-US/_HL/traits/traits.ftl index 55f5f598bfe..464488065af 100644 --- a/Resources/Locale/en-US/_HL/traits/traits.ftl +++ b/Resources/Locale/en-US/_HL/traits/traits.ftl @@ -72,6 +72,9 @@ hl-trait-egglayer-desc = You produce and lay eggs (10 cum per egg) hl-trait-egglayer-infertile-name = Egg Layer (very infertile) hl-trait-egglayer-infertile-desc = You produce eggs very slowly and seldomly (50 cum per egg) +hl-trait-Prizeballlayer = Gashaponsition +hl-trait-Prizeballlayer-desc = You produce and dispense Prizeballs (50 Tickets per Prizeball) + hl-trait-Brainwasher-name = Brainwasher hl-trait-Brainwasher-desc = Through natural or artificial means, you have the ability to brainwash peoples. diff --git a/Resources/Locale/en-US/actions/actions/prizeball-lay.ftl b/Resources/Locale/en-US/actions/actions/prizeball-lay.ftl new file mode 100644 index 00000000000..6d0c0667e04 --- /dev/null +++ b/Resources/Locale/en-US/actions/actions/prizeball-lay.ftl @@ -0,0 +1,23 @@ +action-popup-lay-pball-user = You lay a prizeball. +action-popup-lay-pball-others = {CAPITALIZE(THE($entity))} lays a shiny prizeball. +action-popup-lay-pball-too-hungry = You need more tickets before you can lay another prizeball! + +action-popup-lay-pball-user-start = You squat and push, feeling a prizeball stretching its way down... +action-popup-lay-pball-user-more = Another prizeball begins to push out... +action-popup-lay-pball-user-done = Your insides feel smooth and free of rewards! +action-popup-lay-pball-nopballs = You don't feel any prizeballs to lay! +action-popup-lay-pball-firstpball = Your ticket filled abdomen contracts and squeezes, feeling a smooth mass forming. +action-popup-lay-pball-heavypballs = Your lumpy belly makes it feel hard to turn and move! +action-popup-lay-pball-fullpballs = You feel your dispensing chute clenching and trying to hold in a long line of prizeballs! +action-popup-lay-pball-flavor-1 = Many rewards can be felt in your abdomen! +action-popup-lay-pball-flavor-2 = You feel like your dispensing chute is jammed to the brim! +action-popup-lay-pball-flavor-3 = Your vend wire is pulsing involuntarily! +action-popup-lay-pball-flavor-4 = Your insides feel full of solid heavy balls! + +action-popup-lay-pball-inside-start = {$entity} kisses their oviduct lips tightly against {$target}, and begins to push... +action-popup-lay-pball-inside-give-more = You feel an prizeball pop into {$entity}, squeezing into them as more push behind it. +action-popup-lay-pball-inside-receive-more = {$entity}'s dispening port pushes smooth mysterious capsules into you. +action-popup-lay-pball-inside-give-done = Pressing your prizeball laying port tightly against {$entity}, the last prizeball forces its way inside them! +action-popup-lay-pball-inside-receive-done = You feel full as {$entity}'s last prizeball stretches into your orifice. + +lay-pball-inside-verb-get-text = Lay prizeball inside diff --git a/Resources/Prototypes/_HL/Actions/types.yml b/Resources/Prototypes/_HL/Actions/types.yml index ef9299b4ecb..512d6d88fba 100644 --- a/Resources/Prototypes/_HL/Actions/types.yml +++ b/Resources/Prototypes/_HL/Actions/types.yml @@ -34,6 +34,18 @@ useDelay: 5 event: !type:LewdEggLayingActionEvent +- type: entity + id: ActionLayPrizeball + name: Lay your prizeball + description: Kneel and push with all your might. + categories: [ HideSpawnMenu ] + components: + - type: InstantAction + icon: { sprite: _NF/Objects/Fun/prizeticket.rsi, state: prizeball } + useDelay: 5 + event: !type:PrizeballLayingActionEvent + + - type: entity id: ActionResomiGravityJump name: Leap diff --git a/Resources/Prototypes/_HL/Reagents/fun.yml b/Resources/Prototypes/_HL/Reagents/fun.yml index 919c0b23669..aa5a16b70ff 100644 --- a/Resources/Prototypes/_HL/Reagents/fun.yml +++ b/Resources/Prototypes/_HL/Reagents/fun.yml @@ -30,3 +30,17 @@ conditions: - !type:ReagentThreshold min: 50 + +- type: reagent + id: PrizeballJuice + name: reagent-name-prizeball-juice + desc: reagent-desc-prizeball-juice + physicalDesc: reagent-physical-desc-vibrant + group: Toxins + flavor: highscore + color: "#872420" + metabolisms: + Poison: + metabolismRate: 1 + effects: + - !type:Redeem \ No newline at end of file diff --git a/Resources/Prototypes/_HL/Traits/lewd.yml b/Resources/Prototypes/_HL/Traits/lewd.yml index c27bf9c5548..226973ec4e9 100644 --- a/Resources/Prototypes/_HL/Traits/lewd.yml +++ b/Resources/Prototypes/_HL/Traits/lewd.yml @@ -55,6 +55,22 @@ eggSlowMult: 0.5 eggLayDelay: 5 +- type: trait + id: PrizeballLayer + name: hl-trait-Prizeballlayer + description: hl-trait-Prizeballlayer-desc + category: Physical + components: + - type: PrizeballLaying + eggSpawn: + - id: PrizeBall + productionMult: 0.2 + flavorFreq: 6 + maxEggs: 24 + pballSlowThreshold: 10 + pballSlowMult: 0.5 + pballLayDelay: 5 + - type: trait id: Brainwasher name: hl-trait-Brainwasher-name diff --git a/Resources/Prototypes/_NF/Entities/Objects/Fun/prizeticket.yml b/Resources/Prototypes/_NF/Entities/Objects/Fun/prizeticket.yml index a1c17ba6f8f..f291b1ba10c 100644 --- a/Resources/Prototypes/_NF/Entities/Objects/Fun/prizeticket.yml +++ b/Resources/Prototypes/_NF/Entities/Objects/Fun/prizeticket.yml @@ -43,6 +43,21 @@ - type: Item heldPrefix: prize ticket - type: Appearance + - type: Food + solution: food + delay: 0.25 + forceFeedDelay: 1 + - type: FlavorProfile + flavors: + - paper + - type: BadFood + - type: SolutionContainerManager + solutions: + food: + maxVol: 1 + reagents: + - ReagentId: PrizeballJuice + Quantity: .1 - type: entity parent: PrizeTicket From c48098972b700629a54832f4b0e70abfbb427357 Mon Sep 17 00:00:00 2001 From: Bug Date: Thu, 11 Jun 2026 17:30:14 -0400 Subject: [PATCH 2/5] Fixed a few minor issues Updated Prizeball laying systems to match the equivalent LewdEggLaying System, and made the trait appear in the traits tab --- .../_Hardlight/LewdEgglaying/Systems/PrizeballLayingSystem.cs | 4 ++-- Resources/Prototypes/_HL/Traits/lewd.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Content.Server/_Hardlight/LewdEgglaying/Systems/PrizeballLayingSystem.cs b/Content.Server/_Hardlight/LewdEgglaying/Systems/PrizeballLayingSystem.cs index f0e67e51821..77294cee0f5 100644 --- a/Content.Server/_Hardlight/LewdEgglaying/Systems/PrizeballLayingSystem.cs +++ b/Content.Server/_Hardlight/LewdEgglaying/Systems/PrizeballLayingSystem.cs @@ -160,7 +160,7 @@ private void OnPballLayingInsideDoAfter(EntityUid user, PrizeballLayingComponent _popup.PopupEntity(Loc.GetString("action-popup-lay-pball-inside-receive-done", ("entity", Identity.Entity(user, EntityManager))), target, target); if(myPballs.Temporary) - EntityManager.RemoveComponent(user); + RemComp(user); else _actions.RemoveAction(user, myPballs.Action); } @@ -186,7 +186,7 @@ private void OnPballLayingDoAfter(EntityUid user, PrizeballLayingComponent pball _audio.PlayPvs(pballLaying.PballLaySound, user); - pballLaying.addPballs(-1.0f); + AddPballs(user, pballLaying, -1.0f); _movementSpeedModifier.RefreshMovementSpeedModifiers(user); if(pballLaying.hasPballs()) diff --git a/Resources/Prototypes/_HL/Traits/lewd.yml b/Resources/Prototypes/_HL/Traits/lewd.yml index 226973ec4e9..2e3371eed84 100644 --- a/Resources/Prototypes/_HL/Traits/lewd.yml +++ b/Resources/Prototypes/_HL/Traits/lewd.yml @@ -59,7 +59,7 @@ id: PrizeballLayer name: hl-trait-Prizeballlayer description: hl-trait-Prizeballlayer-desc - category: Physical + category: Lewd components: - type: PrizeballLaying eggSpawn: From ce82ee1fe3016af9bdea415edaf7bb3cd83a104b Mon Sep 17 00:00:00 2001 From: Bug Date: Thu, 11 Jun 2026 17:33:59 -0400 Subject: [PATCH 3/5] Fixed some langaunge in the en localization --- Resources/Locale/en-US/actions/actions/prizeball-lay.ftl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Resources/Locale/en-US/actions/actions/prizeball-lay.ftl b/Resources/Locale/en-US/actions/actions/prizeball-lay.ftl index 6d0c0667e04..d3e2dcbaa78 100644 --- a/Resources/Locale/en-US/actions/actions/prizeball-lay.ftl +++ b/Resources/Locale/en-US/actions/actions/prizeball-lay.ftl @@ -7,15 +7,15 @@ action-popup-lay-pball-user-more = Another prizeball begins to push out... action-popup-lay-pball-user-done = Your insides feel smooth and free of rewards! action-popup-lay-pball-nopballs = You don't feel any prizeballs to lay! action-popup-lay-pball-firstpball = Your ticket filled abdomen contracts and squeezes, feeling a smooth mass forming. -action-popup-lay-pball-heavypballs = Your lumpy belly makes it feel hard to turn and move! +action-popup-lay-pball-heavypballs = Your reward-filled belly makes it feel hard to turn and move! action-popup-lay-pball-fullpballs = You feel your dispensing chute clenching and trying to hold in a long line of prizeballs! action-popup-lay-pball-flavor-1 = Many rewards can be felt in your abdomen! action-popup-lay-pball-flavor-2 = You feel like your dispensing chute is jammed to the brim! action-popup-lay-pball-flavor-3 = Your vend wire is pulsing involuntarily! action-popup-lay-pball-flavor-4 = Your insides feel full of solid heavy balls! -action-popup-lay-pball-inside-start = {$entity} kisses their oviduct lips tightly against {$target}, and begins to push... -action-popup-lay-pball-inside-give-more = You feel an prizeball pop into {$entity}, squeezing into them as more push behind it. +action-popup-lay-pball-inside-start = {$entity} kisses their prize chute lips tightly against {$target}, and begins to push... +action-popup-lay-pball-inside-give-more = You feel a prizeball pop into {$entity}, squeezing into them as more push behind it. action-popup-lay-pball-inside-receive-more = {$entity}'s dispening port pushes smooth mysterious capsules into you. action-popup-lay-pball-inside-give-done = Pressing your prizeball laying port tightly against {$entity}, the last prizeball forces its way inside them! action-popup-lay-pball-inside-receive-done = You feel full as {$entity}'s last prizeball stretches into your orifice. From cc1cf1291578ad31573e9a813314d71e2b3ff78a Mon Sep 17 00:00:00 2001 From: Bug Date: Thu, 11 Jun 2026 23:19:11 -0400 Subject: [PATCH 4/5] Fixed some minor things Removed the HL tag from comments on code in HL folder Fixed the flavor Fixed maxPballs being maxEggs in lewd.yml --- .../_HL/LewdEggLaying/Systems/PrizeballLayingSystem.cs | 2 +- .../_Hardlight/LewdEgglaying/Systems/PrizeballLayingSystem.cs | 2 +- .../LewdEgglaying/Components/PrizeballLayingComponent.cs | 2 +- Resources/Locale/en-US/_HL/flavors/flavor-profiles.ftl | 2 +- .../en-US/{actions/actions => _HL/lewd}/prizeball-lay.ftl | 0 Resources/Prototypes/_HL/Reagents/fun.yml | 2 +- Resources/Prototypes/_HL/Traits/lewd.yml | 2 +- Resources/Prototypes/_NF/Entities/Objects/Fun/prizeticket.yml | 2 +- 8 files changed, 7 insertions(+), 7 deletions(-) rename Resources/Locale/en-US/{actions/actions => _HL/lewd}/prizeball-lay.ftl (100%) diff --git a/Content.Client/_HL/LewdEggLaying/Systems/PrizeballLayingSystem.cs b/Content.Client/_HL/LewdEggLaying/Systems/PrizeballLayingSystem.cs index d52fdede397..2dbe6f00fd9 100644 --- a/Content.Client/_HL/LewdEggLaying/Systems/PrizeballLayingSystem.cs +++ b/Content.Client/_HL/LewdEggLaying/Systems/PrizeballLayingSystem.cs @@ -2,7 +2,7 @@ namespace Content.Client.Animals.Systems; -// HL: This is just an empty class so that the matching code in SharedPrizeballLayingSystem can run on the client. +// This is just an empty class so that the matching code in SharedPrizeballLayingSystem can run on the client. public sealed class PrizeballLayingSystem : SharedPrizeballLayingSystem { diff --git a/Content.Server/_Hardlight/LewdEgglaying/Systems/PrizeballLayingSystem.cs b/Content.Server/_Hardlight/LewdEgglaying/Systems/PrizeballLayingSystem.cs index 77294cee0f5..5dd3c033430 100644 --- a/Content.Server/_Hardlight/LewdEgglaying/Systems/PrizeballLayingSystem.cs +++ b/Content.Server/_Hardlight/LewdEgglaying/Systems/PrizeballLayingSystem.cs @@ -17,7 +17,7 @@ namespace Content.Server.Animals.Systems; /// Gives the ability to lay pballs/other things; /// produces endlessly if the owner does not have a HungerComponent. /// -public sealed class PrizeballLayingSystem : SharedPrizeballLayingSystem // HL: We've changed the base to SharedPrizeballLayingSystem so we can run the Verb drawing on the client. +public sealed class PrizeballLayingSystem : SharedPrizeballLayingSystem // We've changed the base to SharedPrizeballLayingSystem so we can run the Verb drawing on the client. { [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly SharedActionsSystem _actions = default!; diff --git a/Content.Shared/_Hardlight/LewdEgglaying/Components/PrizeballLayingComponent.cs b/Content.Shared/_Hardlight/LewdEgglaying/Components/PrizeballLayingComponent.cs index ec69567c098..ed72c57eab8 100644 --- a/Content.Shared/_Hardlight/LewdEgglaying/Components/PrizeballLayingComponent.cs +++ b/Content.Shared/_Hardlight/LewdEgglaying/Components/PrizeballLayingComponent.cs @@ -4,7 +4,7 @@ using Robust.Shared.Prototypes; using Content.Shared.Animals.Systems; -namespace Content.Shared.Animals.Components; // HL: Moved this to Shared so the client can use it for verb drawing. +namespace Content.Shared.Animals.Components; // Moved this to Shared so the client can use it for verb drawing. /// /// This component handles prizeball laying for the prizeball layer trait diff --git a/Resources/Locale/en-US/_HL/flavors/flavor-profiles.ftl b/Resources/Locale/en-US/_HL/flavors/flavor-profiles.ftl index 0be60a8a527..587957472db 100644 --- a/Resources/Locale/en-US/_HL/flavors/flavor-profiles.ftl +++ b/Resources/Locale/en-US/_HL/flavors/flavor-profiles.ftl @@ -1,5 +1,5 @@ flavor-woof = like woof -flavor-highscore = Like a sweet sweet highscore. +flavor-highscore = like a sweet sweet highscore. flavor-complex-tha-slop = like processed shit flavor-complex-old-socks = like old socks diff --git a/Resources/Locale/en-US/actions/actions/prizeball-lay.ftl b/Resources/Locale/en-US/_HL/lewd/prizeball-lay.ftl similarity index 100% rename from Resources/Locale/en-US/actions/actions/prizeball-lay.ftl rename to Resources/Locale/en-US/_HL/lewd/prizeball-lay.ftl diff --git a/Resources/Prototypes/_HL/Reagents/fun.yml b/Resources/Prototypes/_HL/Reagents/fun.yml index aa5a16b70ff..c182d529233 100644 --- a/Resources/Prototypes/_HL/Reagents/fun.yml +++ b/Resources/Prototypes/_HL/Reagents/fun.yml @@ -37,7 +37,7 @@ desc: reagent-desc-prizeball-juice physicalDesc: reagent-physical-desc-vibrant group: Toxins - flavor: highscore + flavor: flavor-highscore color: "#872420" metabolisms: Poison: diff --git a/Resources/Prototypes/_HL/Traits/lewd.yml b/Resources/Prototypes/_HL/Traits/lewd.yml index 2e3371eed84..f43077901be 100644 --- a/Resources/Prototypes/_HL/Traits/lewd.yml +++ b/Resources/Prototypes/_HL/Traits/lewd.yml @@ -66,7 +66,7 @@ - id: PrizeBall productionMult: 0.2 flavorFreq: 6 - maxEggs: 24 + maxPballs: 24 pballSlowThreshold: 10 pballSlowMult: 0.5 pballLayDelay: 5 diff --git a/Resources/Prototypes/_NF/Entities/Objects/Fun/prizeticket.yml b/Resources/Prototypes/_NF/Entities/Objects/Fun/prizeticket.yml index f291b1ba10c..5c0fbfd3047 100644 --- a/Resources/Prototypes/_NF/Entities/Objects/Fun/prizeticket.yml +++ b/Resources/Prototypes/_NF/Entities/Objects/Fun/prizeticket.yml @@ -43,8 +43,8 @@ - type: Item heldPrefix: prize ticket - type: Appearance + solution: food # HL added The food component to the prize ticket, as well as prizeball juice for the prizeball layer trait - type: Food - solution: food delay: 0.25 forceFeedDelay: 1 - type: FlavorProfile From 52ad5b6e0f7fbec537e3256e82c45eb11e637d65 Mon Sep 17 00:00:00 2001 From: Bug Date: Fri, 12 Jun 2026 00:18:08 -0400 Subject: [PATCH 5/5] Actually fixed the Linter issue this time, I hope --- Resources/Prototypes/_HL/Flavors/flavors.yml | 5 +++++ Resources/Prototypes/_HL/Reagents/fun.yml | 2 +- .../Prototypes/_NF/Entities/Objects/Fun/prizeticket.yml | 3 ++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Resources/Prototypes/_HL/Flavors/flavors.yml b/Resources/Prototypes/_HL/Flavors/flavors.yml index 22aa1738d3e..54ee075395a 100644 --- a/Resources/Prototypes/_HL/Flavors/flavors.yml +++ b/Resources/Prototypes/_HL/Flavors/flavors.yml @@ -3,6 +3,11 @@ flavorType: Base description: flavor-woof +- type: flavor + id: highscore + flavorType: Base + description: flavor-highscore + - type: flavor id: thaslop flavorType: complex diff --git a/Resources/Prototypes/_HL/Reagents/fun.yml b/Resources/Prototypes/_HL/Reagents/fun.yml index c182d529233..aa5a16b70ff 100644 --- a/Resources/Prototypes/_HL/Reagents/fun.yml +++ b/Resources/Prototypes/_HL/Reagents/fun.yml @@ -37,7 +37,7 @@ desc: reagent-desc-prizeball-juice physicalDesc: reagent-physical-desc-vibrant group: Toxins - flavor: flavor-highscore + flavor: highscore color: "#872420" metabolisms: Poison: diff --git a/Resources/Prototypes/_NF/Entities/Objects/Fun/prizeticket.yml b/Resources/Prototypes/_NF/Entities/Objects/Fun/prizeticket.yml index 5c0fbfd3047..aed75f8feb3 100644 --- a/Resources/Prototypes/_NF/Entities/Objects/Fun/prizeticket.yml +++ b/Resources/Prototypes/_NF/Entities/Objects/Fun/prizeticket.yml @@ -43,8 +43,9 @@ - type: Item heldPrefix: prize ticket - type: Appearance - solution: food # HL added The food component to the prize ticket, as well as prizeball juice for the prizeball layer trait + # HL added The food component to the prize ticket, as well as prizeball juice for the prizeball layer trait - type: Food + solution: food delay: 0.25 forceFeedDelay: 1 - type: FlavorProfile