Skip to content

Commit

Permalink
Merge pull request #1037 from Saeko-44/master
Browse files Browse the repository at this point in the history
The juice that lets you see ghosts
  • Loading branch information
widgetbeck authored Dec 22, 2024
2 parents 42816be + af13859 commit a7abaa6
Show file tree
Hide file tree
Showing 11 changed files with 231 additions and 4 deletions.
43 changes: 43 additions & 0 deletions Content.Client/Ghost/GhostSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,10 @@ private bool GhostVisibility
public bool IsGhostBarPatron => PlayerGhostPatron != null;

public event Action<GhostComponent>? PlayerRemoved;
public event Action<MediumComponent>? MediumRemoved;
public event Action<GhostComponent>? PlayerUpdated;
public event Action<GhostComponent>? PlayerAttached;
public event Action<MediumComponent>? MediumAttached;
public event Action? PlayerDetached;
public event Action<GhostWarpsResponseEvent>? GhostWarpsResponse;
public event Action<GhostUpdateGhostRoleCountEvent>? GhostRoleCountUpdated;
Expand All @@ -69,6 +71,11 @@ public override void Initialize()
SubscribeLocalEvent<EyeComponent, ToggleLightingActionEvent>(OnToggleLighting);
SubscribeLocalEvent<EyeComponent, ToggleFoVActionEvent>(OnToggleFoV);
SubscribeLocalEvent<GhostComponent, ToggleGhostsActionEvent>(OnToggleGhosts);

SubscribeLocalEvent<MediumComponent, ComponentStartup>(OnMediumStartup);
SubscribeLocalEvent<MediumComponent, LocalPlayerAttachedEvent>(OnGhostMediumPlayerAttach);
SubscribeLocalEvent<MediumComponent, ToggleGhostsMediumActionEvent>(OnToggleGhostsMedium);
SubscribeLocalEvent<MediumComponent, ComponentRemove>(OnGhostMediumRemove);
}

private void OnStartup(EntityUid uid, GhostComponent component, ComponentStartup args)
Expand All @@ -77,6 +84,12 @@ private void OnStartup(EntityUid uid, GhostComponent component, ComponentStartup
sprite.Visible = GhostVisibility || uid == _playerManager.LocalEntity;
}

private void OnMediumStartup(EntityUid uid, MediumComponent component, ComponentStartup args)
{
if (TryComp(uid, out SpriteComponent? sprite))
sprite.Visible = GhostVisibility || uid == _playerManager.LocalEntity;
}

private void OnToggleLighting(EntityUid uid, EyeComponent component, ToggleLightingActionEvent args)
{
if (args.Handled)
Expand Down Expand Up @@ -110,6 +123,19 @@ private void OnToggleGhosts(EntityUid uid, GhostComponent component, ToggleGhost
args.Handled = true;
}

private void OnToggleGhostsMedium(EntityUid uid, MediumComponent component, ToggleGhostsMediumActionEvent args)
{
if (args.Handled)
return;

var locId = GhostVisibility ? "ghost-gui-toggle-ghost-visibility-popup-off" : "ghost-gui-toggle-ghost-visibility-popup-on";
Popup.PopupEntity(Loc.GetString(locId), args.Performer);
if (uid == _playerManager.LocalEntity)
ToggleGhostVisibility();

args.Handled = true;
}

private void OnGhostRemove(EntityUid uid, GhostComponent component, ComponentRemove args)
{
_actions.RemoveAction(uid, component.ToggleLightingActionEntity);
Expand All @@ -124,12 +150,29 @@ private void OnGhostRemove(EntityUid uid, GhostComponent component, ComponentRem
PlayerRemoved?.Invoke(component);
}

private void OnGhostMediumRemove(EntityUid uid, MediumComponent component, ComponentRemove args)
{
_actions.RemoveAction(uid, component.ToggleGhostsMediumActionEntity);

if (uid != _playerManager.LocalEntity)
return;

GhostVisibility = false;
MediumRemoved?.Invoke(component);
}

private void OnGhostPlayerAttach(EntityUid uid, GhostComponent component, LocalPlayerAttachedEvent localPlayerAttachedEvent)
{
GhostVisibility = true;
PlayerAttached?.Invoke(component);
}

private void OnGhostMediumPlayerAttach(EntityUid uid, MediumComponent component, LocalPlayerAttachedEvent localPlayerAttachedEvent)
{
GhostVisibility = true;
MediumAttached?.Invoke(component);
}

private void OnGhostState(EntityUid uid, GhostComponent component, ref AfterAutoHandleStateEvent args)
{
if (TryComp<SpriteComponent>(uid, out var sprite))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using Content.Shared.Construction.Prototypes;
using Robust.Shared.GameObjects;
using Robust.Shared.ViewVariables;

namespace Content.Client.Construction
{
[RegisterComponent]
public sealed partial class ConstructionMediumComponent : Component
{
[ViewVariables] public ConstructionPrototype? Prototype { get; set; }
}
}
71 changes: 67 additions & 4 deletions Content.Server/Ghost/GhostSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
using Content.Server.GameTicking;
using Content.Server.Ghost.Components;
using Content.Server.Mind;
using Content.Server.Polymorph.Components;
using Content.Server.Roles.Jobs;
using Content.Server.Warps;
using Content.Shared._Impstation.Ghost;
using Content.Shared.Actions;
using Content.Shared.CCVar;
using Content.Shared.Damage;
Expand All @@ -28,6 +30,7 @@
using Robust.Server.GameObjects;
using Robust.Server.Player;
using Robust.Shared.Configuration;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Systems;
Expand Down Expand Up @@ -95,6 +98,26 @@ public override void Initialize()

SubscribeLocalEvent<RoundEndTextAppendEvent>(_ => MakeVisible(true));
SubscribeLocalEvent<ToggleGhostVisibilityToAllEvent>(OnToggleGhostVisibilityToAll);

SubscribeLocalEvent<MediumComponent, ComponentStartup>(OnMediumStartup);
SubscribeLocalEvent<MediumComponent, MapInitEvent>(OnMapInitMedium);
SubscribeLocalEvent<MediumComponent, ComponentShutdown>(OnMediumShutdown);
}

public override void Update(float frameTime)
{
base.Update(frameTime);

var query = EntityQueryEnumerator<MediumComponent>();
while (query.MoveNext(out var uid, out var comp))
{
comp.CurrentMediumTime += frameTime;

if (comp.CurrentMediumTime > comp.MediumTime)
{
EntityManager.RemoveComponent<MediumComponent>(uid);
}
}
}

private void OnGhostHearingAction(EntityUid uid, GhostComponent component, ToggleGhostHearingActionEvent args)
Expand Down Expand Up @@ -171,8 +194,8 @@ private void OnGhostStartup(EntityUid uid, GhostComponent component, ComponentSt

if (_gameTicker.RunLevel != GameRunLevel.PostRound)
{
_visibilitySystem.AddLayer((uid, visibility), (int) VisibilityFlags.Ghost, false);
_visibilitySystem.RemoveLayer((uid, visibility), (int) VisibilityFlags.Normal, false);
_visibilitySystem.AddLayer((uid, visibility), (int)VisibilityFlags.Ghost, false);
_visibilitySystem.RemoveLayer((uid, visibility), (int)VisibilityFlags.Normal, false);
_visibilitySystem.RefreshVisibility(uid, visibilityComponent: visibility);
}

Expand All @@ -182,6 +205,23 @@ private void OnGhostStartup(EntityUid uid, GhostComponent component, ComponentSt
component.TimeOfDeath = time;
}

private void OnMediumStartup(EntityUid uid, MediumComponent component, ComponentStartup args)
{
// Allow this entity to be seen by other ghosts.
var visibility = EnsureComp<VisibilityComponent>(uid);

if (_gameTicker.RunLevel != GameRunLevel.PostRound)
{
_visibilitySystem.AddLayer((uid, visibility), (int)VisibilityFlags.Ghost, false);
_visibilitySystem.RemoveLayer((uid, visibility), (int)VisibilityFlags.Normal, false);
_visibilitySystem.RefreshVisibility(uid, visibilityComponent: visibility);
}

SetCanSeeGhosts(uid, true);

var time = _gameTiming.CurTime;
}

private void OnGhostShutdown(EntityUid uid, GhostComponent component, ComponentShutdown args)
{
// Perf: If the entity is deleting itself, no reason to change these back.
Expand All @@ -191,8 +231,8 @@ private void OnGhostShutdown(EntityUid uid, GhostComponent component, ComponentS
// Entity can't be seen by ghosts anymore.
if (TryComp(uid, out VisibilityComponent? visibility))
{
_visibilitySystem.RemoveLayer((uid, visibility), (int) VisibilityFlags.Ghost, false);
_visibilitySystem.AddLayer((uid, visibility), (int) VisibilityFlags.Normal, false);
_visibilitySystem.RemoveLayer((uid, visibility), (int)VisibilityFlags.Ghost, false);
_visibilitySystem.AddLayer((uid, visibility), (int)VisibilityFlags.Normal, false);
_visibilitySystem.RefreshVisibility(uid, visibilityComponent: visibility);
}

Expand All @@ -201,6 +241,24 @@ private void OnGhostShutdown(EntityUid uid, GhostComponent component, ComponentS
_actions.RemoveAction(uid, component.BooActionEntity);
}

private void OnMediumShutdown(EntityUid uid, MediumComponent component, ComponentShutdown args)
{
// Perf: If the entity is deleting itself, no reason to change these back.
if (Terminating(uid))
return;

// Entity can't be seen by ghosts anymore.
if (TryComp(uid, out VisibilityComponent? visibility))
{
_visibilitySystem.RemoveLayer((uid, visibility), (int)VisibilityFlags.Ghost, false);
_visibilitySystem.AddLayer((uid, visibility), (int)VisibilityFlags.Normal, false);
_visibilitySystem.RefreshVisibility(uid, visibilityComponent: visibility);
}

// Entity can't see ghosts anymore.
SetCanSeeGhosts(uid, false);
}

private void SetCanSeeGhosts(EntityUid uid, bool canSee, EyeComponent? eyeComponent = null)
{
if (!Resolve(uid, ref eyeComponent, false))
Expand All @@ -221,6 +279,11 @@ private void OnMapInit(EntityUid uid, GhostComponent component, MapInitEvent arg
_actions.AddAction(uid, ref component.ToggleGhostsActionEntity, component.ToggleGhostsAction);
}

private void OnMapInitMedium(EntityUid uid, MediumComponent component, MapInitEvent args)
{
_actions.AddAction(uid, ref component.ToggleGhostsMediumActionEntity, component.ToggleGhostsMediumAction);
}

private void OnGhostExamine(EntityUid uid, GhostComponent component, ExaminedEvent args)
{
var timeSinceDeath = _gameTiming.RealTime.Subtract(component.TimeOfDeath);
Expand Down
29 changes: 29 additions & 0 deletions Content.Server/_Impstation/EntityEffects/Effects/Medium.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using Content.Shared._Impstation.Ghost;
using Content.Shared.EntityEffects;
using Content.Shared.Polymorph;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;

namespace Content.Server._Impstation.EntityEffects.Effects;

public sealed partial class Medium : EntityEffect
{
/// <summary>
/// What Medium prototype is used on effect
/// </summary>
//[DataField("prototype", customTypeSerializer:typeof(PrototypeIdSerializer<MediumPrototype>))]
//public string MediumPrototype { get; set; }

protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
{
return "Grants whoever drinks this the ability to see ghosts for a while";
}

public override void Effect(EntityEffectBaseArgs args)
{
var entityManager = args.EntityManager;
var uid = args.TargetEntity;

entityManager.EnsureComponent<MediumComponent>(uid);
}
}
29 changes: 29 additions & 0 deletions Content.Shared/_Impstation/Ghost/MediumComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using Content.Shared.Actions;
using Content.Shared.Ghost;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;

namespace Content.Shared._Impstation.Ghost;

[RegisterComponent, NetworkedComponent, Access(typeof(SharedGhostSystem))]
[AutoGenerateComponentState(true)]
public sealed partial class MediumComponent : Component
{
[DataField]
public EntProtoId ToggleGhostsMediumAction = "ActionToggleGhostsMedium";

[DataField, AutoNetworkedField]
public EntityUid? ToggleGhostsMediumActionEntity;

//Time in seconds passed since medium vision activated
[DataField, AutoNetworkedField]
public float CurrentMediumTime = 0;

//Time after how many seconds the medium effect stops
//Im just gonna put it here as a constant instead of making a whole prototype to set it from the yaml
//Because Im not expected for other reagents to reuse that effect and even less so with a different time limit
[DataField, AutoNetworkedField]
public float MediumTime = 300; // 5 minutes
}

public sealed partial class ToggleGhostsMediumActionEvent : InstantActionEvent { }
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,5 @@ flavor-complex-snotty = like snot
flavor-complex-speed = like speed
flavor-base-whimsy = whimsical
flavor-complex-secticket = like rotten eggs
flavor-complex-medium = like your vision expanded
3 changes: 3 additions & 0 deletions Resources/Locale/en-US/_Impstation/reagents/meta/fun.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@ reagent-desc-ungh-juice = The glucose and citric acid seem to have neutralized t
reagent-name-holium = holium
reagent-desc-holium = An impossibly compressed liquid. It feels as though it could tear through any surface.
reagent-name-medium = medium
reagent-desc-medium = An alchemical medium to the afterlife.
10 changes: 10 additions & 0 deletions Resources/Prototypes/_Impstation/Entities/Mobs/Player/medium.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
- type: entity
id: ActionToggleGhostsMedium
name: Toggle Ghosts
description: Toggle the visibility of ghosts.
components:
- type: InstantAction
icon: { sprite: Mobs/Ghosts/ghost_human.rsi, state: icon }
clientExclusive: true
checkCanInteract: false
event: !type:ToggleGhostsMediumActionEvent
5 changes: 5 additions & 0 deletions Resources/Prototypes/_Impstation/Flavors/flavors.yml
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,8 @@
id: unholy
flavorType: Base
description: flavor-base-unholy

- type: flavor
id: medium
flavorType: Complex
description: flavor-complex-medium
15 changes: 15 additions & 0 deletions Resources/Prototypes/_Impstation/Reagents/fun.yml
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,18 @@
entity: FloorChasmEntity
maxOnTileWhitelist:
tags: [ FloorChasmEntity ]

- type: reagent
id: Medium
name: reagent-name-medium
desc: reagent-desc-medium
physicalDesc: reagent-physical-desc-reflective
flavor: medium
color: "#DC89E0"
metabolisms:
Poison:
effects:
- !type:Medium
conditions:
- !type:ReagentThreshold
min: 20
16 changes: 16 additions & 0 deletions Resources/Prototypes/_Impstation/Recipes/Reactions/chemicals.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,19 @@
catalyst: true
products:
Holium: 1

- type: reaction
id: Medium
impact: Medium #lol
reactants:
AquamDivinos:
amount: 1
Oculine:
amount: 1
THC:
amount: 1
PhilosophersJuice:
amount: 1
catalyst: true
products:
Medium: 1

0 comments on commit a7abaa6

Please sign in to comment.