Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/unstable' into master-upstream
Browse files Browse the repository at this point in the history
  • Loading branch information
FoxxoTrystan committed Oct 25, 2024
2 parents c91b8ff + 7e8a2c9 commit a492482
Show file tree
Hide file tree
Showing 29 changed files with 384 additions and 78 deletions.
5 changes: 5 additions & 0 deletions Content.Client/Chapel/SacrificialAltarSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
using Content.Shared.Chapel;

namespace Content.Client.Chapel;

public sealed class SacrificialAltarSystem : SharedSacrificialAltarSystem;
13 changes: 4 additions & 9 deletions Content.Client/Lobby/UI/HumanoidProfileEditor.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,7 @@ public void SetProfile(HumanoidCharacterProfile? profile, int? slot)
UpdateSkinColor();
UpdateSpawnPriorityControls();
UpdateFlavorTextEdit();
UpdateCustomSpecieNameEdit();
UpdateAgeEdit();
UpdateEyePickers();
UpdateSaveButton();
Expand Down Expand Up @@ -1206,15 +1207,9 @@ private void UpdateNameEdit()

private void UpdateCustomSpecieNameEdit()
{
if (Profile == null)
return;

_customspecienameEdit.Text = Profile.Customspeciename ?? "";

if (!_prototypeManager.TryIndex<SpeciesPrototype>(Profile.Species, out var speciesProto))
return;

_ccustomspecienamecontainerEdit.Visible = speciesProto.CustomName;
var species = _species.Find(x => x.ID == Profile?.Species) ?? _species.First();
_customspecienameEdit.Text = string.IsNullOrEmpty(Profile?.Customspeciename) ? Loc.GetString(species.Name) : Profile.Customspeciename;
_ccustomspecienamecontainerEdit.Visible = species.CustomName;
}

private void UpdateFlavorTextEdit()
Expand Down
129 changes: 129 additions & 0 deletions Content.Server/Chapel/SacrificialAltarSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
using Content.Server.Bible.Components;
using Content.Shared.Abilities.Psionics;
using Content.Shared.Administration.Logs;
using Content.Shared.Body.Components;
using Content.Shared.Body.Systems;
using Content.Shared.Database;
using Content.Shared.Chapel;
using Content.Shared.DoAfter;
using Content.Shared.Humanoid;
using Content.Shared.Mind;
using Content.Shared.Popups;
using Content.Shared.Psionics.Glimmer;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;

namespace Content.Server.Chapel;

public sealed class SacrificialAltarSystem : SharedSacrificialAltarSystem
{
[Dependency] private readonly GlimmerSystem _glimmer = default!;
[Dependency] private readonly IPrototypeManager _proto = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly SharedBodySystem _body = default!;
[Dependency] private readonly SharedMindSystem _mind = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;

public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<SacrificialAltarComponent, SacrificeDoAfterEvent>(OnDoAfter);
}

private void OnDoAfter(Entity<SacrificialAltarComponent> ent, ref SacrificeDoAfterEvent args)
{
ent.Comp.SacrificeStream = _audio.Stop(ent.Comp.SacrificeStream);
ent.Comp.DoAfter = null;

if (args.Cancelled || args.Handled || args.Args.Target is not { } target
|| !TryComp<PsionicComponent>(target, out var psionic)
|| !_mind.TryGetMind(target, out var _, out var _))
return;

_adminLogger.Add(LogType.Action, LogImpact.Extreme, $"{ToPrettyString(args.Args.User):player} sacrificed {ToPrettyString(target):target} on {ToPrettyString(ent):altar}");

// lower glimmer by a random amount
_glimmer.Glimmer -= (int) (ent.Comp.GlimmerReduction * psionic.CurrentAmplification);

if (ent.Comp.RewardPool is not null && _random.Prob(ent.Comp.BaseItemChance * psionic.CurrentDampening))
{
var proto = _proto.Index(_random.Pick(ent.Comp.RewardPool));
Spawn(proto.ToString(), Transform(ent).Coordinates);
}
// TODO GOLEMS: create a soul crystal and transfer mind into it

// finally gib the targets old body
if (TryComp<BodyComponent>(target, out var body))
_body.GibBody(target, gibOrgans: false, body, launchGibs: true);
else
QueueDel(target);
}

protected override void AttemptSacrifice(Entity<SacrificialAltarComponent> ent, EntityUid user, EntityUid target)
{
if (ent.Comp.DoAfter != null)
return;

// can't sacrifice yourself
if (user == target)
{
_popup.PopupEntity(Loc.GetString("altar-failure-reason-self"), ent, user, PopupType.SmallCaution);
return;
}

// you need to be psionic OR bible user
if (!HasComp<PsionicComponent>(user) && !HasComp<BibleUserComponent>(user))
{
_popup.PopupEntity(Loc.GetString("altar-failure-reason-user"), ent, user, PopupType.SmallCaution);
return;
}

// and no golems or familiars or whatever should be sacrificing
if (!HasComp<HumanoidAppearanceComponent>(user))
{
_popup.PopupEntity(Loc.GetString("altar-failure-reason-user-humanoid"), ent, user, PopupType.SmallCaution);
return;
}

// prevent psichecking SSD people...
// notably there is no check in OnDoAfter so you can't alt f4 to survive being sacrificed
if (!HasComp<ActorComponent>(target) || _mind.GetMind(target) == null)
{
_popup.PopupEntity(Loc.GetString("altar-failure-reason-target-catatonic", ("target", target)), ent, user, PopupType.SmallCaution);
return;
}

// TODO: there should be a penalty to the user for psichecking like this
if (!HasComp<PsionicComponent>(target))
{
_popup.PopupEntity(Loc.GetString("altar-failure-reason-target", ("target", target)), ent, user, PopupType.SmallCaution);
return;
}

if (!HasComp<HumanoidAppearanceComponent>(target))
{
_popup.PopupEntity(Loc.GetString("altar-failure-reason-target-humanoid", ("target", target)), ent, user, PopupType.SmallCaution);
return;
}

_popup.PopupEntity(Loc.GetString("altar-sacrifice-popup", ("user", user), ("target", target)), ent, PopupType.LargeCaution);

ent.Comp.SacrificeStream = _audio.PlayPvs(ent.Comp.SacrificeSound, ent)?.Entity;

var ev = new SacrificeDoAfterEvent();
var args = new DoAfterArgs(EntityManager, user, ent.Comp.SacrificeTime, ev, target: target, eventTarget: ent)
{
BreakOnDamage = true,
BreakOnUserMove = true,
BreakOnTargetMove = true,
BreakOnWeightlessMove = true,
NeedHand = true
};
DoAfter.TryStartDoAfter(args, out ent.Comp.DoAfter);
}
}
6 changes: 2 additions & 4 deletions Content.Shared/Chapel/SacrificeDoAfterEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
using Content.Shared.DoAfter;

namespace Content.Shared.Chapel;
[Serializable, NetSerializable]
public sealed partial class SacrificeDoAfterEvent : SimpleDoAfterEvent
{

}
[Serializable, NetSerializable]
public sealed partial class SacrificeDoAfterEvent : SimpleDoAfterEvent { }
48 changes: 48 additions & 0 deletions Content.Shared/Chapel/SacrificialAltarComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using Content.Shared.Random;
using Content.Shared.DoAfter;
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;

namespace Content.Shared.Chapel;

/// <summary>
/// Altar that lets you sacrifice psionics to lower glimmer by a large amount.
/// </summary>
[RegisterComponent, NetworkedComponent, Access(typeof(SharedSacrificialAltarSystem))]
public sealed partial class SacrificialAltarComponent : Component
{
/// <summary>
/// DoAfter for an active sacrifice.
/// </summary>
[DataField]
public DoAfterId? DoAfter;

/// <summary>
/// How long it takes to sacrifice someone once they die.
/// This is the window to interrupt a sacrifice if you want glimmer to stay high, or need the psionic to be revived.
/// </summary>
[DataField]
public TimeSpan SacrificeTime = TimeSpan.FromSeconds(8.35);

[DataField]
public SoundSpecifier SacrificeSound = new SoundPathSpecifier("/Audio/Psionics/heartbeat_fast.ogg");

[DataField]
public EntityUid? SacrificeStream;

/// <summary>
/// Base amount to reduce glimmer by, multiplied by the victim's Amplification stat.
/// </summary>
[DataField]
public float GlimmerReduction = 25;

[DataField]
public List<ProtoId<WeightedRandomEntityPrototype>>? RewardPool;

/// <summary>
/// The base chance to generate an item of power, multiplied by the victim's Dampening stat.
/// </summary>
[DataField]
public float BaseItemChance = 0.1f;
}
61 changes: 61 additions & 0 deletions Content.Shared/Chapel/SharedSacrificialAltarSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using System.Linq;
using Content.Shared.Buckle.Components;
using Content.Shared.DoAfter;
using Content.Shared.Examine;
using Content.Shared.Verbs;

namespace Content.Shared.Chapel;

public abstract partial class SharedSacrificialAltarSystem : EntitySystem
{
[Dependency] protected readonly SharedDoAfterSystem DoAfter = default!;

public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<SacrificialAltarComponent, ExaminedEvent>(OnExamined);
SubscribeLocalEvent<SacrificialAltarComponent, BuckleChangeEvent>(OnUnstrapped);
SubscribeLocalEvent<SacrificialAltarComponent, GetVerbsEvent<AlternativeVerb>>(OnGetVerbs);
}

private void OnExamined(Entity<SacrificialAltarComponent> ent, ref ExaminedEvent args)
{
args.PushMarkup(Loc.GetString("altar-examine"));
}

private void OnUnstrapped(Entity<SacrificialAltarComponent> ent, ref BuckleChangeEvent args)
{
if (ent.Comp.DoAfter is not { } id)
return;

DoAfter.Cancel(id);
ent.Comp.DoAfter = null;
}

private void OnGetVerbs(Entity<SacrificialAltarComponent> ent, ref GetVerbsEvent<AlternativeVerb> args)
{
if (!args.CanAccess || !args.CanInteract || ent.Comp.DoAfter != null
|| !TryComp<StrapComponent>(ent, out var strap)
|| GetFirstBuckled(strap) is not { } target)
return;

var user = args.User;
args.Verbs.Add(new AlternativeVerb()
{
Act = () => AttemptSacrifice(ent, user, target),
Text = Loc.GetString("altar-sacrifice-verb"),
Priority = 2
});
}

private EntityUid? GetFirstBuckled(StrapComponent strap)
{
if (strap.BuckledEntities.Count <= 0)
return null;

return strap.BuckledEntities.First();
}

protected virtual void AttemptSacrifice(Entity<SacrificialAltarComponent> ent, EntityUid user, EntityUid target) { }
}
Binary file modified Resources/Audio/Floof/Lewd/kiss.ogg
Binary file not shown.
Binary file modified Resources/Audio/Floof/Lewd/lick.ogg
Binary file not shown.
12 changes: 6 additions & 6 deletions Resources/Audio/Voice/Human/attributions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,12 @@

- files: ["female_cough_1.ogg"]
license: "CC0-1.0"
copyright: "Ashe Kirk"
copyright: "Ashe Kirk, converted to mono and had its volume reduced by Mnemotechnician for Einstein-Engines"
source: "https://freesound.org/people/OwlStorm/sounds/151213/"

- files: ["female_cough_2.ogg"]
license: "CC0-1.0"
copyright: "thatkellytrna on freesound.org"
copyright: "thatkellytrna on freesound.org, converted to mono and had its volume reduced by Mnemotechnician for Einstein-Engines"
source: "https://freesound.org/people/thatkellytrna/sounds/425777/"

- files: ["male_cough_2.ogg"]
Expand All @@ -87,22 +87,22 @@

- files: ["female_sneeze_1.ogg"]
license: "CC0-1.0"
copyright: "sherby168 on freesound.org"
copyright: "sherby168 on freesound.org, volume reduced by 10db by Mnemotechnician for Einstein-Engines"
source: "https://freesound.org/people/sherby168/sounds/540771/"

- files: ["male_sneeze_1.ogg"]
license: "CC-BY-4.0"
copyright: "InspectorJ (www.jshaw.co.uk) of Freesound.org"
copyright: "InspectorJ (www.jshaw.co.uk) of Freesound.org, volume reduced by 10db by Mnemotechnician for Einstein-Engines"
source: "https://freesound.org/people/InspectorJ/sounds/352177/"

- files: ["male_yawn_1.ogg"]
license: "CC-BY-4.0"
copyright: "ckvoiceover on freesound.org"
copyright: "ckvoiceover on freesound.org, converted to mono and had its volume reduced by 18db by Mnemotechnician for Einstein-Engines"
source: "https://freesound.org/people/ckvoiceover/sounds/401338/"

- files: ["female_yawn_1.ogg"]
license: "CC0-1.0"
copyright: "Reitanna on freesound.org"
copyright: "Reitanna on freesound.org, converted to mono, slightly edited and had its volume reduced by 10db by Mnemotechnician for Einstein-Engines"
source: "https://freesound.org/people/Reitanna/sounds/252239/"

- files:
Expand Down
Binary file modified Resources/Audio/Voice/Human/female_cough_1.ogg
Binary file not shown.
Binary file modified Resources/Audio/Voice/Human/female_cough_2.ogg
Binary file not shown.
Binary file modified Resources/Audio/Voice/Human/female_sneeze_1.ogg
Binary file not shown.
Binary file modified Resources/Audio/Voice/Human/female_yawn_1.ogg
Binary file not shown.
Binary file modified Resources/Audio/Voice/Human/male_sneeze_1.ogg
Binary file not shown.
Binary file modified Resources/Audio/Voice/Human/male_yawn_1.ogg
Binary file not shown.
40 changes: 40 additions & 0 deletions Resources/Changelog/Changelog.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7492,3 +7492,43 @@ Entries:
id: 6477
time: '2024-10-20T19:28:35.0000000+00:00'
url: https://github.com/Simple-Station/Einstein-Engines/pull/1113
- author: VMSolidus
changes:
- type: Add
message: >-
Sacrificing Psions has been added. Psions can be sacrificed by
Epistemics upon an altar in order to dramatically reduce glimmer. The
more powerful the Psion to be sacrificed, the more glimmer is reduced.
id: 6478
time: '2024-10-20T21:34:05.0000000+00:00'
url: https://github.com/Simple-Station/Einstein-Engines/pull/1110
- author: Aidenkrz
changes:
- type: Fix
message: Flavor text can be updated again.
id: 6479
time: '2024-10-21T00:24:18.0000000+00:00'
url: https://github.com/Simple-Station/Einstein-Engines/pull/1119
- author: VMSolidus
changes:
- type: Add
message: Glacier is now on a planetary surface
id: 6480
time: '2024-10-21T00:41:02.0000000+00:00'
url: https://github.com/Simple-Station/Einstein-Engines/pull/1115
- author: VMSolidus
changes:
- type: Fix
message: >-
Asterisk Station no longer spawns entombed in snow, and is now on top of
an ice sheet.
id: 6481
time: '2024-10-21T00:41:18.0000000+00:00'
url: https://github.com/Simple-Station/Einstein-Engines/pull/1118
- author: Aidenkrz
changes:
- type: Fix
message: Custom specie name doesn't disappear in the editor anymore.
id: 6482
time: '2024-10-22T01:42:11.0000000+00:00'
url: https://github.com/Simple-Station/Einstein-Engines/pull/1120
11 changes: 11 additions & 0 deletions Resources/Locale/en-US/chapel/altar.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
altar-examine = [color=purple]This altar can be used to sacrifice Psionics.[/color]
altar-sacrifice-verb = Sacrifice
altar-failure-reason-self = You can't sacrifice yourself!
altar-failure-reason-user = You are not psionic or clerically trained!
altar-failure-reason-user-humanoid = You are not a humanoid!
altar-failure-reason-target = {CAPITALIZE(THE($target))} {CONJUGATE-BE($target)} not psionic!
altar-failure-reason-target-humanoid = {CAPITALIZE(THE($target))} {CONJUGATE-BE($target)} not a humanoid!
altar-failure-reason-target-catatonic = {CAPITALIZE(THE($target))} {CONJUGATE-BE($target)} braindead!
altar-sacrifice-popup = {$user} starts to sacrifice {$target}!
Loading

0 comments on commit a492482

Please sign in to comment.