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

Upstream Merge 2024-09-26 #212

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
0e187aa
Update Credits (#923)
github-actions[bot] Sep 21, 2024
49d128c
Reimplement Part Upgrading (#917)
VMSolidus Sep 21, 2024
f126bb4
[Port] Uplink Discounts From White Dream (#930)
VMSolidus Sep 21, 2024
331d68d
Automatic Changelog Update (#917)
SimpleStation14 Sep 21, 2024
1b43123
Automatic Changelog Update (#930)
SimpleStation14 Sep 21, 2024
61e1c8c
Psionic "Heal Other" Powers (#942)
VMSolidus Sep 21, 2024
272b4ec
Automatic Changelog Update (#942)
SimpleStation14 Sep 21, 2024
5bf5d57
More Objects Hit By Projectiles (#943)
VMSolidus Sep 21, 2024
900630c
Automatic Changelog Update (#943)
SimpleStation14 Sep 21, 2024
89860b4
Update Credits (#946)
github-actions[bot] Sep 22, 2024
99ee312
Fix HealingWord & Revivify Bugs (#949)
VMSolidus Sep 24, 2024
7c7619c
More Quick Construction Recipes And Upgrades (#945)
gluesniffler Sep 24, 2024
5b9f28c
Automatic Changelog Update (#949)
SimpleStation14 Sep 24, 2024
08248ff
Automatic Changelog Update (#945)
SimpleStation14 Sep 24, 2024
42871bc
IPCs Don't Weigh 5kg (#959)
VMSolidus Sep 25, 2024
b53b555
Automatic Changelog Update (#959)
SimpleStation14 Sep 25, 2024
af0c932
Enemies and Allies Content Port (#956)
fenndragon Sep 26, 2024
883352e
Automatic Changelog Update (#956)
SimpleStation14 Sep 26, 2024
6fe7e67
Merge remote-tracking branch 'refs/remotes/real-ee/master' into floof…
Mnemotechnician Sep 26, 2024
f50c29e
Remove obsolete prototypes
Mnemotechnician Sep 26, 2024
26d2938
Begone
Mnemotechnician Sep 26, 2024
5c92c52
Fix dead IPCs not having a startup button
Mnemotechnician Sep 26, 2024
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
95 changes: 53 additions & 42 deletions Content.Client/ShortConstruction/UI/ShortConstructionMenuBUI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using Robust.Client.UserInterface.Controls;
using Robust.Shared.Enums;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;

// ReSharper disable InconsistentNaming

Expand All @@ -30,7 +31,6 @@ public sealed class ShortConstructionMenuBUI : BoundUserInterface
private readonly SpriteSystem _spriteSystem;

private RadialMenu? _menu;

public ShortConstructionMenuBUI(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
_construction = _entManager.System<ConstructionSystem>();
Expand All @@ -39,8 +39,17 @@ public ShortConstructionMenuBUI(EntityUid owner, Enum uiKey) : base(owner, uiKey

protected override void Open()
{
_menu = FormMenu();
_menu.OnClose += Close;
_menu = new RadialMenu
{
HorizontalExpand = true,
VerticalExpand = true,
BackButtonStyleClass = "RadialMenuBackButton",
CloseButtonStyleClass = "RadialMenuCloseButton"
};

if (_entManager.TryGetComponent<ShortConstructionComponent>(Owner, out var crafting))
CreateMenu(crafting.Entries);

_menu.OpenCenteredAt(_inputManager.MouseScreenPosition.Position / _displayManager.ScreenSize);
}

Expand All @@ -51,56 +60,58 @@ protected override void Dispose(bool disposing)
_menu?.Dispose();
}

private RadialMenu FormMenu()
private void CreateMenu(List<ShortConstructionEntry> entries, string? parentCategory = null)
{
var menu = new RadialMenu
{
HorizontalExpand = true,
VerticalExpand = true,
BackButtonStyleClass = "RadialMenuBackButton",
CloseButtonStyleClass = "RadialMenuCloseButton"
};

if (!_entManager.TryGetComponent<ShortConstructionComponent>(Owner, out var crafting))
return menu;
if (_menu == null)
return;

var mainContainer = new RadialContainer
var container = new RadialContainer
{
Radius = 36f / MathF.Sin(MathF.PI / 2f / crafting.Prototypes.Count)
Name = parentCategory ?? "Main",
Radius = 48f + 24f * MathF.Log(entries.Count),
};

foreach (var protoId in crafting.Prototypes)
{
if (!_protoManager.TryIndex(protoId, out var proto))
continue;
_menu.AddChild(container);

var button = new RadialMenuTextureButton
foreach (var entry in entries)
{
if (entry.Category != null)
{
ToolTip = Loc.GetString(proto.Name),
StyleClasses = { "RadialMenuButton" },
SetSize = new Vector2(48f, 48f)
};

var texture = new TextureRect
var button = CreateButton(entry.Category.Name, entry.Category.Icon);
button.TargetLayer = entry.Category.Name;
CreateMenu(entry.Category.Entries, entry.Category.Name);
container.AddChild(button);
}
else if (entry.Prototype != null
&& _protoManager.TryIndex(entry.Prototype, out var proto))
{
VerticalAlignment = Control.VAlignment.Center,
HorizontalAlignment = Control.HAlignment.Center,
Texture = _spriteSystem.Frame0(proto.Icon),
TextureScale = new Vector2(1.5f, 1.5f)
};
var button = CreateButton(proto.Name, proto.Icon);
button.OnButtonUp += _ => ConstructItem(proto);
container.AddChild(button);
}
}

button.AddChild(texture);
}

button.OnButtonUp += _ =>
{
ConstructItem(proto);
};
private RadialMenuTextureButton CreateButton(string name, SpriteSpecifier icon)
{
var button = new RadialMenuTextureButton
{
ToolTip = Loc.GetString(name),
StyleClasses = { "RadialMenuButton" },
SetSize = new Vector2(64f, 64f),
};

mainContainer.AddChild(button);
}
var texture = new TextureRect
{
VerticalAlignment = Control.VAlignment.Center,
HorizontalAlignment = Control.HAlignment.Center,
Texture = _spriteSystem.Frame0(icon),
TextureScale = new Vector2(2f, 2f)
};

menu.AddChild(mainContainer);
return menu;
button.AddChild(texture);
return button;
}

/// <summary>
Expand All @@ -121,6 +132,6 @@ private void ConstructItem(ConstructionPrototype prototype)
}, new ConstructionPlacementHijack(_construction, prototype));

// Should only close the menu if we're placing a construction hijack.
_menu!.Close();
// Theres not much point to closing it though. _menu!.Close();
}
}
5 changes: 5 additions & 0 deletions Content.Client/Store/Ui/StoreMenu.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Content.Client.Message;
using Content.Shared.FixedPoint;
using Content.Shared.Store;
using Content.Client.Stylesheets;
using Robust.Client.AutoGenerated;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
Expand Down Expand Up @@ -147,6 +148,10 @@ private void AddListingGui(ListingData listing)
}

var newListing = new StoreListingControl(listing, GetListingPriceString(listing), hasBalance, texture);

if (listing.DiscountValue > 0)
newListing.StoreItemBuyButton.AddStyleClass(StyleNano.ButtonColorDangerDefault.ToString());

newListing.StoreItemBuyButton.OnButtonDown += args
=> OnListingButtonPressed?.Invoke(args, listing);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,3 @@ public async Task ChangeMachine()
AssertPrototype("Autolathe");
}
}

Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

namespace Content.IntegrationTests.Tests.Interaction;

// This partial class contains various constant prototype IDs common to interaction tests.
Expand Down Expand Up @@ -27,8 +28,6 @@ public abstract partial class InteractionTest

// Parts
protected const string Bin1 = "MatterBinStockPart";
protected const string Cap1 = "CapacitorStockPart";
protected const string Manipulator1 = "MicroManipulatorStockPart";
protected const string Battery1 = "PowerCellSmall";
protected const string Battery4 = "PowerCellHyper";
}

164 changes: 164 additions & 0 deletions Content.Server/Abilities/Psionics/Abilities/HealOtherPowerSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
using Robust.Shared.Player;
using Content.Server.DoAfter;
using Content.Shared.Abilities.Psionics;
using Content.Shared.Damage;
using Content.Shared.DoAfter;
using Content.Shared.Popups;
using Content.Shared.Psionics.Events;
using Content.Shared.Examine;
using static Content.Shared.Examine.ExamineSystemShared;
using Robust.Shared.Timing;
using Content.Shared.Actions.Events;
using Robust.Server.Audio;
using Content.Server.Atmos.Rotting;
using Content.Shared.Mobs.Systems;
using Content.Shared.Mobs;
using Content.Shared.Mobs.Components;
using Content.Shared.Psionics.Glimmer;

namespace Content.Server.Abilities.Psionics;

public sealed class RevivifyPowerSystem : EntitySystem
{
[Dependency] private readonly AudioSystem _audioSystem = default!;
[Dependency] private readonly DoAfterSystem _doAfterSystem = default!;
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
[Dependency] private readonly SharedPsionicAbilitiesSystem _psionics = default!;
[Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly ExamineSystemShared _examine = default!;
[Dependency] private readonly DamageableSystem _damageable = default!;
[Dependency] private readonly RottingSystem _rotting = default!;
[Dependency] private readonly MobThresholdSystem _mobThreshold = default!;
[Dependency] private readonly MobStateSystem _mobState = default!;
[Dependency] private readonly GlimmerSystem _glimmer = default!;


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

SubscribeLocalEvent<PsionicComponent, PsionicHealOtherPowerActionEvent>(OnPowerUsed);
SubscribeLocalEvent<PsionicComponent, DispelledEvent>(OnDispelled);
SubscribeLocalEvent<PsionicComponent, PsionicHealOtherDoAfterEvent>(OnDoAfter);
}


private void OnPowerUsed(EntityUid uid, PsionicComponent component, PsionicHealOtherPowerActionEvent args)
{
if (component.DoAfter is not null)
return;

if (!args.Immediate)
AttemptDoAfter(uid, component, args);
else ActivatePower(uid, component, args);

if (args.PopupText is not null
&& _glimmer.Glimmer > args.GlimmerPopupThreshold * component.CurrentDampening)
_popupSystem.PopupEntity(Loc.GetString(args.PopupText, ("entity", uid)), uid,
Filter.Pvs(uid).RemoveWhereAttachedEntity(entity => !_examine.InRangeUnOccluded(uid, entity, ExamineRange, null)),
true,
args.PopupType);

if (args.PlaySound
&& _glimmer.Glimmer > args.GlimmerSoundThreshold * component.CurrentDampening)
_audioSystem.PlayPvs(args.SoundUse, uid, args.AudioParams);

// Sanitize the Glimmer inputs because otherwise the game will crash if someone makes MaxGlimmer lower than MinGlimmer.
var minGlimmer = (int) Math.Round(MathF.MinMagnitude(args.MinGlimmer, args.MaxGlimmer)
+ component.CurrentAmplification - component.CurrentDampening);
var maxGlimmer = (int) Math.Round(MathF.MaxMagnitude(args.MinGlimmer, args.MaxGlimmer)
+ component.CurrentAmplification - component.CurrentDampening);

_psionics.LogPowerUsed(uid, args.PowerName, minGlimmer, maxGlimmer);
args.Handled = true;
}

private void AttemptDoAfter(EntityUid uid, PsionicComponent component, PsionicHealOtherPowerActionEvent args)
{
var ev = new PsionicHealOtherDoAfterEvent(_gameTiming.CurTime);
if (args.HealingAmount is not null)
ev.HealingAmount = args.HealingAmount;
if (args.RotReduction is not null)
ev.RotReduction = args.RotReduction.Value;
ev.DoRevive = args.DoRevive;
var doAfterArgs = new DoAfterArgs(EntityManager, uid, args.UseDelay, ev, uid, target: args.Target)
{
BreakOnUserMove = args.BreakOnUserMove,
BreakOnTargetMove = args.BreakOnTargetMove,
Hidden = _glimmer.Glimmer > args.GlimmerDoAfterVisibilityThreshold * component.CurrentDampening,
};

if (!_doAfterSystem.TryStartDoAfter(doAfterArgs, out var doAfterId))
return;

component.DoAfter = doAfterId;
}

private void OnDispelled(EntityUid uid, PsionicComponent component, DispelledEvent args)
{
if (component.DoAfter is null)
return;

_doAfterSystem.Cancel(component.DoAfter);
component.DoAfter = null;
args.Handled = true;
}

private void OnDoAfter(EntityUid uid, PsionicComponent component, PsionicHealOtherDoAfterEvent args)
{
// It's entirely possible for the caster to stop being Psionic(due to mindbreaking) mid cast
if (component is null
|| args.Cancelled)
return;
component.DoAfter = null;

// The target can also cease existing mid-cast
if (args.Target is null)
return;

if (args.RotReduction is not null)
_rotting.ReduceAccumulator(args.Target.Value, TimeSpan.FromSeconds(args.RotReduction.Value * component.CurrentAmplification));

if (!TryComp<DamageableComponent>(args.Target.Value, out var damageableComponent))
return;

if (args.HealingAmount is not null)
_damageable.TryChangeDamage(args.Target.Value, args.HealingAmount * component.CurrentAmplification, true, false, damageableComponent, uid);

if (!args.DoRevive
|| _rotting.IsRotten(args.Target.Value)
|| !TryComp<MobStateComponent>(args.Target.Value, out var mob)
|| !_mobState.IsDead(args.Target.Value, mob)
|| !_mobThreshold.TryGetThresholdForState(args.Target.Value, MobState.Dead, out var threshold)
|| damageableComponent.TotalDamage > threshold)
return;

_mobState.ChangeMobState(args.Target.Value, MobState.Critical, mob, uid);
}

// This would be the same thing as OnDoAfter, except that here the target isn't nullable, so I have to reuse code with different arguments.
private void ActivatePower(EntityUid uid, PsionicComponent component, PsionicHealOtherPowerActionEvent args)
{
if (component is null)
return;

if (args.RotReduction is not null)
_rotting.ReduceAccumulator(args.Target, TimeSpan.FromSeconds(args.RotReduction.Value * component.CurrentAmplification));

if (!TryComp<DamageableComponent>(args.Target, out var damageableComponent))
return;

if (args.HealingAmount is not null)
_damageable.TryChangeDamage(args.Target, args.HealingAmount * component.CurrentAmplification, true, false, damageableComponent, uid);

if (!args.DoRevive
|| _rotting.IsRotten(args.Target)
|| !TryComp<MobStateComponent>(args.Target, out var mob)
|| !_mobState.IsDead(args.Target, mob)
|| !_mobThreshold.TryGetThresholdForState(args.Target, MobState.Dead, out var threshold)
|| damageableComponent.TotalDamage > threshold)
return;

_mobState.ChangeMobState(args.Target, MobState.Critical, mob, uid);
}
}
7 changes: 7 additions & 0 deletions Content.Server/Anomaly/AnomalySystem.Vessel.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Content.Server.Anomaly.Components;
using Content.Server.Construction;
using Content.Server.Power.EntitySystems;
using Content.Shared.Anomaly;
using Content.Shared.Anomaly.Components;
Expand All @@ -20,6 +21,7 @@ private void InitializeVessel()
{
SubscribeLocalEvent<AnomalyVesselComponent, ComponentShutdown>(OnVesselShutdown);
SubscribeLocalEvent<AnomalyVesselComponent, MapInitEvent>(OnVesselMapInit);
SubscribeLocalEvent<AnomalyVesselComponent, UpgradeExamineEvent>(OnUpgradeExamine);
SubscribeLocalEvent<AnomalyVesselComponent, InteractUsingEvent>(OnVesselInteractUsing);
SubscribeLocalEvent<AnomalyVesselComponent, ExaminedEvent>(OnExamined);
SubscribeLocalEvent<AnomalyVesselComponent, ResearchServerGetPointsPerSecondEvent>(OnVesselGetPointsPerSecond);
Expand Down Expand Up @@ -65,6 +67,11 @@ private void OnVesselMapInit(EntityUid uid, AnomalyVesselComponent component, Ma
UpdateVesselAppearance(uid, component);
}

private void OnUpgradeExamine(EntityUid uid, AnomalyVesselComponent component, UpgradeExamineEvent args)
{
args.AddPercentageUpgrade("anomaly-vessel-component-upgrade-output", component.PointMultiplier);
}

private void OnVesselInteractUsing(EntityUid uid, AnomalyVesselComponent component, InteractUsingEvent args)
{
if (component.Anomaly != null ||
Expand Down
Loading
Loading