Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The Blood Cult #1001

Draft
wants to merge 19 commits into
base: master
Choose a base branch
from
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
15 changes: 14 additions & 1 deletion Content.Client/Antag/AntagStatusIconSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
using Content.Shared.Revolutionary.Components;
using Content.Shared.StatusIcon;
using Content.Shared.StatusIcon.Components;
using Content.Shared.WhiteDream.BloodCult.BloodCultist;
using Content.Shared.WhiteDream.BloodCult.Components;
using Content.Shared.WhiteDream.BloodCult.Constructs;
using Content.Shared.Zombies;
using Robust.Client.Player;
using Robust.Shared.Prototypes;
Expand All @@ -23,6 +26,10 @@ public override void Initialize()
SubscribeLocalEvent<ZombieComponent, GetStatusIconsEvent>(GetIcon);
SubscribeLocalEvent<HeadRevolutionaryComponent, GetStatusIconsEvent>(GetIcon);
SubscribeLocalEvent<InitialInfectedComponent, GetStatusIconsEvent>(GetIcon);

SubscribeLocalEvent<ConstructComponent, GetStatusIconsEvent>(GetIcon);
SubscribeLocalEvent<BloodCultistComponent, GetStatusIconsEvent>(GetBloodCultIcon);
SubscribeLocalEvent<BloodCultLeaderComponent, GetStatusIconsEvent>(GetIcon);
}

/// <summary>
Expand All @@ -39,7 +46,6 @@ private void GetIcon<T>(EntityUid uid, T comp, ref GetStatusIconsEvent ev) where
ev.StatusIcons.Add(_prototype.Index(comp.StatusIcon));
}


/// <summary>
/// Adds the Rev Icon on an entity if the player is supposed to see it. This additional function is needed to deal
/// with a special case where if someone is a head rev we only want to display the headrev icon.
Expand All @@ -50,6 +56,13 @@ private void GetRevIcon(EntityUid uid, RevolutionaryComponent comp, ref GetStatu
return;

GetIcon(uid, comp, ref ev);
}

private void GetBloodCultIcon(EntityUid uid, BloodCultistComponent comp, ref GetStatusIconsEvent ev)
{
if (HasComp<BloodCultLeaderComponent>(uid))
return;

GetIcon(uid, comp, ref ev);
}
}
114 changes: 114 additions & 0 deletions Content.Client/ListViewSelector/ListViewSelectorBUI.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
using Content.Client.Lathe.UI;
using Content.Client.UserInterface.Controls;
using Content.Shared.ListViewSelector;
using JetBrains.Annotations;
using Robust.Client.UserInterface.Controls;
using Robust.Shared.Prototypes;

// ReSharper disable InconsistentNaming

namespace Content.Client.ListViewSelector;

[UsedImplicitly]
public sealed class ListViewSelectorBUI(EntityUid owner, Enum uiKey) : BoundUserInterface(owner, uiKey)
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;

private FancyWindow _window = new();
private BoxContainer? _itemsContainer;

protected override void Open()
{
_window = FormWindow();
_window.OnClose += Close;
_window.OpenCentered();
}

protected override void UpdateState(BoundUserInterfaceState state)
{
base.UpdateState(state);

if (state is ListViewSelectorState listViewSelectorState)
{
PopulateWindow(listViewSelectorState.Items);
}
}

protected override void Dispose(bool disposing)
{
base.Dispose(disposing);

if (disposing)
_window.Close();
}

private FancyWindow FormWindow()
{
var window = new FancyWindow
{
HorizontalExpand = true,
VerticalExpand = true,
MinWidth = 350,
MinHeight = 400,
Title = Loc.GetString("list-view-window-default-title")
};

var scrollContainer = new ScrollContainer
{
HorizontalExpand = true,
VerticalExpand = true
};

var itemsContainer = new BoxContainer
{
Orientation = BoxContainer.LayoutOrientation.Vertical
};

scrollContainer.AddChild(itemsContainer);
window.AddChild(scrollContainer);

_itemsContainer = itemsContainer;

return window;
}

private void PopulateWindow(List<ListViewSelectorEntry> items)
{
if (_itemsContainer is null)
{
return;
}

_itemsContainer.Children.Clear();

foreach (var item in items)
{
var itemName = item.Name;
var itemDesc = item.Description;
if (_prototypeManager.TryIndex(item.Id, out var itemPrototype))
{
itemName = itemPrototype.Name;
itemDesc = itemPrototype.Description;
}

var button = new Button
{
Text = itemName,
};

if (!string.IsNullOrEmpty(itemDesc))
{
button.TooltipSupplier = _ => new RecipeTooltip(itemDesc);
}

button.OnButtonUp += _ =>
{
var msg = new ListViewItemSelectedMessage(item, items.IndexOf(item));
SendMessage(msg);
Close();
};

_itemsContainer.AddChild(button);
}
}
}
5 changes: 4 additions & 1 deletion Content.Client/ShortConstruction/ShortConstructionSystem.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Content.Client.Construction;
// using Content.Client.WhiteDream.BloodCult.UI;
using Content.Shared.Construction.Prototypes;
using Content.Shared.RadialSelector;
using Content.Shared.ShortConstruction;
Expand Down Expand Up @@ -36,11 +37,13 @@ private void OnItemRecieved(Entity<ShortConstructionComponent> ent, ref RadialSe
return;
}

var hijack = new ConstructionPlacementHijack(_construction, prototype);

_placement.BeginPlacing(new PlacementInformation
{
IsTile = false,
PlacementOption = prototype.PlacementMode
},
new ConstructionPlacementHijack(_construction, prototype));
hijack);
}
}
85 changes: 85 additions & 0 deletions Content.Client/WhiteDream/BloodCult/BloodCultistSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
using System.Numerics;
using Content.Shared.Antag;
using Content.Shared.Ghost;
using Content.Shared.StatusIcon.Components;
using Content.Shared.WhiteDream.BloodCult;
using Content.Shared.WhiteDream.BloodCult.BloodCultist;
using Content.Shared.WhiteDream.BloodCult.Components;
using Content.Shared.WhiteDream.BloodCult.Constructs;
using Robust.Client.GameObjects;
using Robust.Shared.Random;
using Robust.Shared.Utility;

namespace Content.Client.WhiteDream.BloodCult;

public sealed class BloodCultistSystem : EntitySystem
{
[Dependency] private readonly IRobustRandom _random = default!;

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

SubscribeLocalEvent<PentagramComponent, ComponentStartup>(OnPentagramAdded);
SubscribeLocalEvent<PentagramComponent, ComponentShutdown>(OnPentagramRemoved);

SubscribeLocalEvent<ConstructComponent, CanDisplayStatusIconsEvent>(OnCanShowCultIcon);
SubscribeLocalEvent<BloodCultistComponent, CanDisplayStatusIconsEvent>(OnCanShowCultIcon);
SubscribeLocalEvent<BloodCultLeaderComponent, CanDisplayStatusIconsEvent>(OnCanShowCultIcon);
}

private void OnPentagramAdded(EntityUid uid, PentagramComponent component, ComponentStartup args)
{
if (!TryComp<SpriteComponent>(uid, out var sprite))
return;

if (sprite.LayerMapTryGet(PentagramKey.Key, out _))
return;

var adj = sprite.Bounds.Height / 2 + 1.0f / 32 * 10.0f;

var randomState = _random.Pick(component.States);

var layer = sprite.AddLayer(new SpriteSpecifier.Rsi(component.RsiPath, randomState));

sprite.LayerMapSet(PentagramKey.Key, layer);
sprite.LayerSetOffset(layer, new Vector2(0.0f, adj));
}

private void OnPentagramRemoved(EntityUid uid, PentagramComponent component, ComponentShutdown args)
{
if (!TryComp<SpriteComponent>(uid, out var sprite))
return;

if (!sprite.LayerMapTryGet(PentagramKey.Key, out var layer))
return;

sprite.RemoveLayer(layer);
}


/// <summary>
/// Determine whether a client should display the cult icon.
/// </summary>
private void OnCanShowCultIcon<T>(EntityUid uid, T comp, ref CanDisplayStatusIconsEvent args)
where T : IAntagStatusIconComponent
{
if (!CanDisplayIcon(args.User, comp.IconVisibleToGhost))
args.Cancelled = true;
}

/// <summary>
/// The criteria that determine whether a client should see Cult/Cult leader icons.
/// </summary>
private bool CanDisplayIcon(EntityUid? uid, bool visibleToGhost)
{
if (HasComp<BloodCultistComponent>(uid) ||
HasComp<BloodCultLeaderComponent>(uid) ||
HasComp<ConstructComponent>(uid))
{
return true;
}

return visibleToGhost && HasComp<GhostComponent>(uid);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using Content.Client.Light.Components;
using Content.Shared.WhiteDream.BloodCult;
using Content.Shared.WhiteDream.BloodCult.Items.VoidTorch;
using Robust.Client.GameObjects;

namespace Content.Client.WhiteDream.BloodCult.Items.VoidTorch;

public sealed class VoidTorchSystem : VisualizerSystem<VoidTorchComponent>
{
protected override void OnAppearanceChange(EntityUid uid,
VoidTorchComponent component,
ref AppearanceChangeEvent args)
{
if (args.Sprite == null)
return;
if (!AppearanceSystem.TryGetData<bool>(uid, GenericCultVisuals.State, out var state)
|| !TryComp<LightBehaviourComponent>(uid, out var lightBehaviour))
return;

lightBehaviour.StopLightBehaviour();
lightBehaviour.StartLightBehaviour(state ? component.TurnOnLightBehaviour : component.TurnOffLightBehaviour);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
using Content.Client.UserInterface.Controls;
using Content.Shared.WhiteDream.BloodCult.UI;
using JetBrains.Annotations;
using Robust.Client.UserInterface.Controls;

// ReSharper disable InconsistentNaming

namespace Content.Client.WhiteDream.BloodCult.NameSelector;

[UsedImplicitly]
public sealed class NameSelectorBUI(EntityUid owner, Enum uiKey) : BoundUserInterface(owner, uiKey)
{
private readonly FancyWindow _window = new();

protected override void Open()
{
base.Open();

FormWindow();
_window.OpenCentered();
_window.OnClose += Close;
}

protected override void Dispose(bool disposing)
{
base.Dispose(disposing);

if (disposing)
_window.Close();
}

private void FormWindow()
{
var container = new BoxContainer
{
Orientation = BoxContainer.LayoutOrientation.Vertical
};

var label = new Label
{
Text = Loc.GetString("name-selector-title")
};

var lineEdit = new LineEdit
{
HorizontalExpand = true
};

var button = new Button
{
Text = Loc.GetString("name-selector-accept-button")
};

button.OnButtonUp += _ =>
{
var msg = new NameSelectedMessage(lineEdit.Text);
SendMessage(msg);
Close();
};

container.AddChild(label);
container.AddChild(lineEdit);
container.AddChild(button);

_window.AddChild(container);
}
}
Loading
Loading