Merge master up to 31/10 (#365)

* Update deathhead_r_leg.png (#21226)

* Add hint for the examine trigger effect (#21166)

* examine locale

* examine trigger desc

* Automatic changelog update

* cornmeal is actually obtainable now (#21162)

* do the thing

* lets find out

* Update Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml

Co-authored-by: ShadowCommander <10494922+ShadowCommander@users.noreply.github.com>

---------

Co-authored-by: ShadowCommander <10494922+ShadowCommander@users.noreply.github.com>

* Automatic changelog update

* Healing skeletons by pouring milk over them (and clean pie remains off their skulls) (#21231)

* mvp done - skellies can heal by spillink regular milk on themselves and clean themselves off creaming with water

* added other types of healing milk, also made a separate reaction to oat milk - it has almost no calcium in it

* fixed indent error, made a dumb mistake

* Automatic changelog update

* Fix anomaly locators frantically beeping when entering detection range. (#21178)

* reset beep timer when out of range

* prevent deficit from impacting beep timing

* Automatic changelog update

* Remove "mk --> mmm, okay" and "u --> you" to chatsan anti slang (#21177)

* Automatic changelog update

* Change ListContainer to send null when selected is removed from the data (#20595)

* fix feeding unremovable items (#21234)

* Automatic changelog update

* Power switchable refactor (#20419)

Co-authored-by: deltanedas <@deltanedas:kde.org>

* simple space mobs cant be flashed (#20784)

Co-authored-by: deltanedas <@deltanedas:kde.org>

* give roundstart borgs names (#20081)

Co-authored-by: deltanedas <@deltanedas:kde.org>

* fix searching on vending machines (#21233)

* syndicate snack box (#21024)

Co-authored-by: deltanedas <@deltanedas:kde.org>

* Fix DockingControl (#21238)

* Shadow Dimension visual pack (#21237)

Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>

* Potato battery update + potato AI (#21142)

Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>

* Adds AttemptEntity(Uns|S)tickEvent. (#20728)

* try-stick

* convert spider charge to attempt-stick-events

* Automatic changelog update

* Automatic changelog update

* Add missing changelog for storage refactor revert (#21259)

* Automatic changelog update

* BBQ rib sandwich (#21180)

* Fix missing toggle fullscreen loc string (#21264)

* Cave Decoration pack  (#21265)

* add chromite chasm

* add desert chasm

* snow chasm

* finish

* fixes and tweaks (#21172)

* Automatic changelog update

* Fix ItemPlacer (#21160)

This is going to lead to many entities being ticked unnecessarily and performance problems.

* headrev spawn music (#21119)

* headrev spawn music

* :trollface:

* skill issue

* double skill issue

* :trollface:

* :trollface:

* :trollface:

* Automatic changelog update

* Techfab resprite + department fab sprites (#21136)

* Fix popup messages appearing when someone tries to open a door without a tool. (#21099)

* The fixTM

* typo fix

* addressing review

* Show "departed and moved on" for when a ghost role is taken (#21092)

* fix ghost role not counting for "departed and moved on"

* I don't think that bit was needed so away it goes

* hopefully finish the upsream merge

* Automatic changelog update

* Implant whitelist/blacklisting (#20678)

* add whitelist and blacklist to implant and implanter components

* handle whitelist and blacklist in systems

* move hardcoded whitelist/blacklist to base implanter + add admeme implanter

* give implants sensible whitelists

* cleaner CheckTarget and fix

* remove unused imports

* network lists

---------

Co-authored-by: deltanedas <@deltanedas:kde.org>

* Automatic changelog update

* Ion storm event (#20277)

* ion storm event prototype + locale

* add lawsets

* use lawsets, make borgs ion storm targets

* ion storm rule and ion storm target

* lawset prototype

* use lawsets

* update silicon law system to use lawsets and support ion storm event

* new toys

* fix

* more fix

* fixy

* ion storm admin logging

* assigning laws makes borg provide its own laws, other stuff

* 1h reoccurence

* 50% chance

* better call saul

* emagLaws is required

* add announcment audio

* fixy

* family friendly gaming

* fixy

* address reviews

* fixy

* more fixy and no erp

* pro

---------

Co-authored-by: deltanedas <@deltanedas:kde.org>

* Automatic changelog update

* A return to foam (foam rework) (#20831)

* Automatic changelog update

* ERT Loadout overhaul + Real deathsquad mobs + ERT fixes (#21230)

* "assist with medical efforts"

* CentComm official description change

* give cburn ert mask

* Ert medic hardsuit uses blood-red medic values

* description changes, they all used to use the blood-red description

* ert engineer hardsuit uses cburn values, good for handling all possible engineering problems.

* janitor hardsuit uses cburn values for extreme messes, otherwise we'd send the non eva variant.

* spawn suffix changes

* shorten suffix

* drop armor from ert jumpsuits

* drop armor from DS jumpsuit

* add more armor to death squad to make up for removed armor in the uniform.

* give sec gas masks armor, give syndicate gas masks armor. ERT gas mask uses syndicate mask values

* add nanotrasen

* removed duplicate

* give centcom IDs their hud icon

* replace all ert bulletproof armor with basic universal armor

* replace all oxygen tanks with air tanks; species is random.

* remove gun and meds from ert engineer kit

* give ert engineer materials

* remove weapons and meds from janitor ert

* give ert janitor light replacer

* remove ert sec pulse weapons, admins will assign loadout. Either the lecter or enforcer, probably.

* Give ert sec the security pistol kit

* typo

* give eva ert sec pistol

* give eva janitor ert gas mask

* give jani purple gloves

* medical gloves for medical ert

* replicate security loadout to leader

* quick ert lecter spawns for lazy admins

* better suffixes to find them easier

* add cburn to ertspawn

* Replace "Spawn" with "role"

* Add death squad. Give ert engineer gas analyzer.

* death squad using wrong equipment

* typo

* missing ghost roles on lecter loadouts

* add freedom implanter to deathsquad

* deathsquad ghost role text

* Operative sounds better

* give Ds flashbang box (why isn't it entirely filled?)

* fix typo. add energy shield to DS

* fix typos

* all centcomm roles are now mindshielded. These cannot be removed.

* Rider didnt include some of the changes ?

* give zipties instead of cuffs for mass arrests!

* upgrade ERT survival boxes to extended capacity

* give cburn extended oxygen too

* Automatic changelog update

* Restore Leviathan's 80 pop cap (#21281)

* Un-revert IPlayerManager refactor (#21244)

* Update engine to v172.0.0 (#21288)

* Hopefully fix Delta commands

* Bandaid tests (#21292)

* rename the rocks (#21275)

* Make crystals noRot (#21279)

IDK might be better. Ideally the anchoring would be offset 0-0 but this is the world we live in atm.

* Fix nukies sound not played  (#21268)

* Play sound and sending greeting message works for nukies now!!!!!

* oops

* silly change

* Automatic changelog update

* Fix hijack objective (#21241)

* Fix hijack

* Max difficulty

* Remove GridModifiedEvent (#21291)

* Update submodule to 173.0.0 (#21296)

* Fix namespace error (#21298)

* Update yaml sequence option in editorconfig (#21297)

* Fix namespace (#21299)

* fix cburn bag issue, make new bag entity for them and filled bag entity (#21295)

* Health analyzer UI improve (#17280)

* Automatic changelog update

* User accessible playtime (#21242)

Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>

* Automatic changelog update

* Moves cloning comp & cloning event to shared (#21253)

* Generalizes solution overflow & slightly increases space lube yield (#21094)

* generalize SolutionSpikeOverflowEvent

* let reactions overflow

* spacelube: 3 -> 5

* restore TryMixAndOverflow threshold cap

* Automatic changelog update

* Move ActorComponent to shared (#21293)

* Update engine to v174.0.0 (#21311)

* Fix planet command help message (#21312)

* Wearable bee plush (#20623)

* add

* fix

* temporary change, needs fixing

* mayb fix

* actually fix FR

* yes

* Automatic changelog update

* remove pulse rifle from ert medic (#21310)

* Automatic changelog update

* Atomic bomb add uranium  (#21143)

* fix: Incendiary bullets no longer deal cold, acid, or shock damage that ignores all armor.

* Atomic bomb

* Action bugfixes (#21321)

* Disable OOC during round (#21323)

* Fix PDA notifications when creating a news entry using the Mass-Media console. (#21320)

* Automatic changelog update

* Update belt.yml (#21317)

changes the chief engineer's belt to remove the lv wires (they take up a lot of space and are easy to get anyways) in exchange for a holofan, a t-ray, and a gas analyzer (first time coding ever this might have to be edited)

* New foam sprites (edge sprites) (#21308)

* New foam sprites (icon smoothing)

* changed to edge sprites for foam

* fix

* edges for metal foams

* fix

* Fix bola stam damage, bring back old construction requirements (#21340)

* Automatic changelog update

* Added thermal insulation to flannel jackets (#21273)

* Automatic changelog update

* Space Asshole Gear (#21243)

* Add Space Asshole Coat

* Add sledgehammer

* Adjust sledgehammer damage values

* Add copyright string to sledgehammer

* Fix broken slot highlight in midnight theme. (#21331)

* Update Patrons.yml (#21344)

* Thicken thindow bounds (#21280)

* Automatic changelog update

* 1984 mouse AI (#21353)

* Automatic changelog update

* Pumpkins, jack o' lanterns and pumpkin hat resprite (#21176)

* Pumpkin textures

* Pumpkin prototypes

* Jack o lantern prototypes and pumpkin cake

* Finishing touches

* Arbitrageloose

* Restore old pumpkin helmet sprites (God I hope it works)

* Update ground_lighting.yml (#21350)

* fix fireaxe swing (#21346)

* Automatic changelog update

* Enable skeletons temporarily for Halloween (#21356)

* Automatic changelog update

* Revert "Enable skeletons temporarily for Halloween (#21356)"

This reverts commit ad1780bec1.

* Automatic changelog update

* Update Changelog.yml

* Pea Plants (#20504)

* Add Pea Plants

* Pea soup

* Update flavor-profiles.ftl

* Update seeds.yml

* Add seeds to vendors

* Make things more expensive to fix free money exploit

* Update textures

* Revert "Update textures"

This reverts commit b1b7046504afc7468742b0722f601d98684a1c89.

Vines dont grow straight into the air.

* Shift up 4 pixels

* Fuck autofix conflitcs

* Shift up 3 more pizels

* I finally got byond working so I made sure they were EXACTLY the same

* Address Reviews? I think?

---------

Co-authored-by: Nemanja <98561806+EmoGarbage404@users.noreply.github.com>

* Automatic changelog update

* fix smoke not transferring (#21332)

* Automatic changelog update

* Fix the organtype (#21347)

* Automatic changelog update

* Candy Bucket for Halloween (#21257)

* Added candy bucket and component to update appearance of held containers akin to it

* cleanup newline

* newline was load-bearing

* moved component to Shared, cleanup

* newline is spooky

* You build and run without errors, stop pretending otherwise

* Updated for new storage system in master branch

* Revert "Candy Bucket for Halloween (#21257)"

This reverts commit 74f1098008e4cd6e13778a385e3f69712e4833d7. That moment when you have to sneak changes in via other commits. I'd literally rather just skip this entire entity instead of trying to change the added stuff.

* Fix whitelist code

* Fix missing namespaces and other errors

* Remove duplicate flavor

* Fix cargo arbitrage

---------

Co-authored-by: Fluffiest Floofers <thebluewulf@gmail.com>
Co-authored-by: liltenhead <104418166+liltenhead@users.noreply.github.com>
Co-authored-by: PJBot <pieterjan.briers+bot@gmail.com>
Co-authored-by: Stealthbomber16 <100171035+Stealthbomber16@users.noreply.github.com>
Co-authored-by: ShadowCommander <10494922+ShadowCommander@users.noreply.github.com>
Co-authored-by: Myakot <30875116+Myakot@users.noreply.github.com>
Co-authored-by: TemporalOroboros <TemporalOroboros@gmail.com>
Co-authored-by: Mr. 27 <45323883+27alaing@users.noreply.github.com>
Co-authored-by: Nemanja <98561806+EmoGarbage404@users.noreply.github.com>
Co-authored-by: deltanedas <39013340+deltanedas@users.noreply.github.com>
Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
Co-authored-by: Ed <96445749+TheShuEd@users.noreply.github.com>
Co-authored-by: Doru991 <75124791+Doru991@users.noreply.github.com>
Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
Co-authored-by: DrSmugleaf <DrSmugleaf@users.noreply.github.com>
Co-authored-by: chromiumboy <50505512+chromiumboy@users.noreply.github.com>
Co-authored-by: faint <46868845+ficcialfaint@users.noreply.github.com>
Co-authored-by: nmajask <nmajask@gmail.com>
Co-authored-by: JoeHammad1844 <130668733+JoeHammad1844@users.noreply.github.com>
Co-authored-by: nikthechampiongr <32041239+nikthechampiongr@users.noreply.github.com>
Co-authored-by: crazybrain23 <44417085+crazybrain23@users.noreply.github.com>
Co-authored-by: Whisper <121047731+QuietlyWhisper@users.noreply.github.com>
Co-authored-by: Chief-Engineer <119664036+Chief-Engineer@users.noreply.github.com>
Co-authored-by: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com>
Co-authored-by: Morb <14136326+Morb0@users.noreply.github.com>
Co-authored-by: Artjom <artjombebenin@gmail.com>
Co-authored-by: Repo <47093363+Titian3@users.noreply.github.com>
Co-authored-by: keronshb <54602815+keronshb@users.noreply.github.com>
Co-authored-by: Ubaser <134914314+UbaserB@users.noreply.github.com>
Co-authored-by: kerisargit <108146620+kerisargit@users.noreply.github.com>
Co-authored-by: Simon <63975668+Simyon264@users.noreply.github.com>
Co-authored-by: Yousifb26 <132729941+Yousifb26@users.noreply.github.com>
Co-authored-by: brainfood1183 <113240905+brainfood1183@users.noreply.github.com>
Co-authored-by: Subversionary <109166122+Subversionary@users.noreply.github.com>
Co-authored-by: Psychpsyo <60073468+Psychpsyo@users.noreply.github.com>
Co-authored-by: Vasilis <vasilis@pikachu.systems>
Co-authored-by: I.K <45953835+notquitehadouken@users.noreply.github.com>
Co-authored-by: ZeroDayDaemon <60460608+ZeroDayDaemon@users.noreply.github.com>
Co-authored-by: LankLTE <135308300+LankLTE@users.noreply.github.com>
Co-authored-by: Bixkitts <72874643+Bixkitts@users.noreply.github.com>
This commit is contained in:
Debug 2023-11-01 09:08:44 +01:00 committed by GitHub
parent 0dcdb561a6
commit df1e3dce7b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
669 changed files with 7000 additions and 2617 deletions

View File

@ -338,5 +338,8 @@ dotnet_naming_symbols.type_parameters_symbols.applicable_kinds = type_parameter
resharper_braces_for_ifelse = required_for_multiline
resharper_keep_existing_attribute_arrangement = true
[*.{csproj,xml,yml,dll.config,msbuildproj,targets}]
[*.{csproj,xml,yml,yaml,dll.config,msbuildproj,targets}]
indent_size = 2
[{*.yaml,*.yml}]
ij_yaml_indent_sequence_value = false

View File

@ -2,7 +2,6 @@ using System.IO;
using System.Linq;
using Content.Shared.Actions;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Client.Player;
using Robust.Shared.ContentPack;
using Robust.Shared.GameStates;
@ -41,8 +40,8 @@ namespace Content.Client.Actions
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<ActionsComponent, PlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<ActionsComponent, PlayerDetachedEvent>(OnPlayerDetached);
SubscribeLocalEvent<ActionsComponent, LocalPlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<ActionsComponent, LocalPlayerDetachedEvent>(OnPlayerDetached);
SubscribeLocalEvent<ActionsComponent, ComponentHandleState>(HandleComponentState);
SubscribeLocalEvent<InstantActionComponent, ComponentHandleState>(OnInstantHandleState);
@ -196,12 +195,12 @@ namespace Content.Client.Actions
return GetActions(user);
}
private void OnPlayerAttached(EntityUid uid, ActionsComponent component, PlayerAttachedEvent args)
private void OnPlayerAttached(EntityUid uid, ActionsComponent component, LocalPlayerAttachedEvent args)
{
LinkAllActions(component);
}
private void OnPlayerDetached(EntityUid uid, ActionsComponent component, PlayerDetachedEvent? args = null)
private void OnPlayerDetached(EntityUid uid, ActionsComponent component, LocalPlayerDetachedEvent? args = null)
{
UnlinkAllActions();
}

View File

@ -4,7 +4,7 @@ using Robust.Client.Console;
using Robust.Client.Player;
using Robust.Shared.ContentPack;
using Robust.Shared.Network;
using Robust.Shared.Players;
using Robust.Shared.Player;
using Robust.Shared.Utility;
namespace Content.Client.Administration.Managers

View File

@ -22,7 +22,7 @@ namespace Content.Client.Administration.UI.CustomControls
private List<PlayerInfo> _playerList = new();
private readonly List<PlayerInfo> _sortedPlayerList = new();
public event Action<PlayerInfo?>? OnSelectionChanged;
public event Action<PlayerInfo>? OnSelectionChanged;
public IReadOnlyList<PlayerInfo> PlayerInfo => _playerList;
public Func<PlayerInfo, string, string>? OverrideText;
@ -46,9 +46,9 @@ namespace Content.Client.Administration.UI.CustomControls
BackgroundPanel.PanelOverride = new StyleBoxFlat {BackgroundColor = new Color(32, 32, 40)};
}
private void PlayerListItemPressed(BaseButton.ButtonEventArgs args, ListData data)
private void PlayerListItemPressed(BaseButton.ButtonEventArgs? args, ListData? data)
{
if (data is not PlayerListData {Info: var selectedPlayer})
if (args == null || data is not PlayerListData {Info: var selectedPlayer})
return;
if (args.Event.Function == EngineKeyFunctions.UIClick)
{

View File

@ -5,7 +5,6 @@ using Robust.Client.Console;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Shared.IoC;
using Robust.Shared.Players;
namespace Content.Client.Administration.UI.Tabs.AdminTab
{

View File

@ -1,7 +1,6 @@
using System.Linq;
using Content.Shared.Alert;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Client.Player;
using Robust.Shared.Prototypes;
@ -22,8 +21,8 @@ public sealed class ClientAlertsSystem : AlertsSystem
{
base.Initialize();
SubscribeLocalEvent<AlertsComponent, PlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<AlertsComponent, PlayerDetachedEvent>(OnPlayerDetached);
SubscribeLocalEvent<AlertsComponent, LocalPlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<AlertsComponent, LocalPlayerDetachedEvent>(OnPlayerDetached);
SubscribeLocalEvent<AlertsComponent, AfterAutoHandleStateEvent>(ClientAlertsHandleState);
}
@ -69,7 +68,7 @@ public sealed class ClientAlertsSystem : AlertsSystem
SyncAlerts?.Invoke(this, component.Alerts);
}
private void OnPlayerAttached(EntityUid uid, AlertsComponent component, PlayerAttachedEvent args)
private void OnPlayerAttached(EntityUid uid, AlertsComponent component, LocalPlayerAttachedEvent args)
{
if (_playerManager.LocalPlayer?.ControlledEntity != uid)
return;
@ -87,7 +86,7 @@ public sealed class ClientAlertsSystem : AlertsSystem
ClearAlerts?.Invoke(this, EventArgs.Empty);
}
private void OnPlayerDetached(EntityUid uid, AlertsComponent component, PlayerDetachedEvent args)
private void OnPlayerDetached(EntityUid uid, AlertsComponent component, LocalPlayerDetachedEvent args)
{
ClearAlerts?.Invoke(this, EventArgs.Empty);
}

View File

@ -1,6 +1,5 @@
using Content.Shared.CharacterInfo;
using Content.Shared.Objectives;
using Robust.Client.GameObjects;
using Robust.Client.Player;
using Robust.Client.UserInterface;
@ -11,14 +10,11 @@ public sealed class CharacterInfoSystem : EntitySystem
[Dependency] private readonly IPlayerManager _players = default!;
public event Action<CharacterData>? OnCharacterUpdate;
public event Action? OnCharacterDetached;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<PlayerAttachSysMessage>(OnPlayerAttached);
SubscribeNetworkEvent<CharacterInfoEvent>(OnCharacterInfoEvent);
}
@ -33,14 +29,6 @@ public sealed class CharacterInfoSystem : EntitySystem
RaiseNetworkEvent(new RequestCharacterInfoEvent(GetNetEntity(entity.Value)));
}
private void OnPlayerAttached(PlayerAttachSysMessage msg)
{
if (msg.AttachedEntity == default)
{
OnCharacterDetached?.Invoke();
}
}
private void OnCharacterInfoEvent(CharacterInfoEvent msg, EntitySessionEventArgs args)
{
var entity = GetEntity(msg.NetEntity);

View File

@ -1,8 +1,6 @@
using Content.Shared.Smoking;
using Robust.Shared.Spawners;
using Content.Shared.Chemistry.Components;
using Robust.Client.Animations;
using Robust.Client.GameObjects;
using Robust.Shared.Network;
using Robust.Shared.Timing;
namespace Content.Client.Chemistry.Visualizers;
@ -18,6 +16,7 @@ public sealed class FoamVisualizerSystem : VisualizerSystem<FoamVisualsComponent
{
base.Initialize();
SubscribeLocalEvent<FoamVisualsComponent, ComponentInit>(OnComponentInit);
SubscribeLocalEvent<FoamVisualsComponent, AnimationCompletedEvent>(OnAnimationComplete);
}
public override void Update(float frameTime)
@ -27,11 +26,11 @@ public sealed class FoamVisualizerSystem : VisualizerSystem<FoamVisualsComponent
if (!_timing.IsFirstTimePredicted)
return;
var query = EntityQueryEnumerator<FoamVisualsComponent, TimedDespawnComponent>();
var query = EntityQueryEnumerator<FoamVisualsComponent, SmokeComponent>();
while (query.MoveNext(out var uid, out var comp, out var despawn))
while (query.MoveNext(out var uid, out var comp, out var smoke))
{
if (despawn.Lifetime > 1f)
if (_timing.CurTime < comp.StartTime + TimeSpan.FromSeconds(smoke.Duration) - TimeSpan.FromSeconds(comp.AnimationTime))
continue;
// Despawn animation.
@ -48,6 +47,7 @@ public sealed class FoamVisualizerSystem : VisualizerSystem<FoamVisualsComponent
/// </summary>
private void OnComponentInit(EntityUid uid, FoamVisualsComponent comp, ComponentInit args)
{
comp.StartTime = _timing.CurTime;
comp.Animation = new Animation
{
Length = TimeSpan.FromSeconds(comp.AnimationTime),
@ -58,12 +58,21 @@ public sealed class FoamVisualizerSystem : VisualizerSystem<FoamVisualsComponent
LayerKey = FoamVisualLayers.Base,
KeyFrames =
{
new AnimationTrackSpriteFlick.KeyFrame(comp.State, 0f)
new AnimationTrackSpriteFlick.KeyFrame(comp.AnimationState, 0f)
}
}
}
};
}
private void OnAnimationComplete(EntityUid uid, FoamVisualsComponent component, AnimationCompletedEvent args)
{
if (args.Key != FoamVisualsComponent.AnimationKey)
return;
if (TryComp<SpriteComponent>(uid, out var sprite))
sprite.Visible = false;
}
}
public enum FoamVisualLayers : byte

View File

@ -1,5 +1,6 @@
using Robust.Client.Animations;
using Robust.Client.Graphics;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
namespace Content.Client.Chemistry.Visualizers;
@ -15,18 +16,21 @@ public sealed partial class FoamVisualsComponent : Component
/// </summary>
public const string AnimationKey = "foamdissolve_animation";
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
public TimeSpan StartTime;
/// <summary>
/// How long the foam visually dissolves for.
/// </summary>
[DataField("animationTime")]
public float AnimationTime = 0.6f;
[DataField]
public float AnimationTime = 0.5f;
/// <summary>
/// The state of the entities base sprite RSI that is displayed when the foam dissolves.
/// Cannot use <see cref="RSI.StateKey"/> because it does not have <see cref="DataDefinitionAttribute"/> and I am not making an engine PR at this time.
/// </summary>
[DataField("animationState")]
public string State = "foam-dissolve";
[DataField]
public string AnimationState = "foam-dissolve";
/// <summary>
/// The animation used while the foam dissolves.

View File

@ -38,7 +38,7 @@ namespace Content.Client.Construction
base.Initialize();
UpdatesOutsidePrediction = true;
SubscribeLocalEvent<PlayerAttachSysMessage>(HandlePlayerAttached);
SubscribeLocalEvent<LocalPlayerAttachedEvent>(HandlePlayerAttached);
SubscribeNetworkEvent<AckStructureConstructionMessage>(HandleAckStructure);
SubscribeNetworkEvent<ResponseConstructionGuide>(OnConstructionGuideReceived);
@ -110,9 +110,9 @@ namespace Content.Client.Construction
ClearGhost(msg.GhostId);
}
private void HandlePlayerAttached(PlayerAttachSysMessage msg)
private void HandlePlayerAttached(LocalPlayerAttachedEvent msg)
{
var available = IsCraftingAvailable(msg.AttachedEntity);
var available = IsCraftingAvailable(msg.Entity);
UpdateCraftingAvailability(available);
}

View File

@ -1,5 +1,4 @@
using Content.Shared.Drugs;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.Player;
@ -24,18 +23,18 @@ public sealed class DrugOverlaySystem : EntitySystem
SubscribeLocalEvent<SeeingRainbowsComponent, ComponentInit>(OnInit);
SubscribeLocalEvent<SeeingRainbowsComponent, ComponentShutdown>(OnShutdown);
SubscribeLocalEvent<SeeingRainbowsComponent, PlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<SeeingRainbowsComponent, PlayerDetachedEvent>(OnPlayerDetached);
SubscribeLocalEvent<SeeingRainbowsComponent, LocalPlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<SeeingRainbowsComponent, LocalPlayerDetachedEvent>(OnPlayerDetached);
_overlay = new();
}
private void OnPlayerAttached(EntityUid uid, SeeingRainbowsComponent component, PlayerAttachedEvent args)
private void OnPlayerAttached(EntityUid uid, SeeingRainbowsComponent component, LocalPlayerAttachedEvent args)
{
_overlayMan.AddOverlay(_overlay);
}
private void OnPlayerDetached(EntityUid uid, SeeingRainbowsComponent component, PlayerDetachedEvent args)
private void OnPlayerDetached(EntityUid uid, SeeingRainbowsComponent component, LocalPlayerDetachedEvent args)
{
_overlay.Intoxication = 0;
_overlayMan.RemoveOverlay(_overlay);

View File

@ -1,5 +1,4 @@
using Content.Shared.Drunk;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.Player;
@ -19,18 +18,18 @@ public sealed class DrunkSystem : SharedDrunkSystem
SubscribeLocalEvent<DrunkComponent, ComponentInit>(OnDrunkInit);
SubscribeLocalEvent<DrunkComponent, ComponentShutdown>(OnDrunkShutdown);
SubscribeLocalEvent<DrunkComponent, PlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<DrunkComponent, PlayerDetachedEvent>(OnPlayerDetached);
SubscribeLocalEvent<DrunkComponent, LocalPlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<DrunkComponent, LocalPlayerDetachedEvent>(OnPlayerDetached);
_overlay = new();
}
private void OnPlayerAttached(EntityUid uid, DrunkComponent component, PlayerAttachedEvent args)
private void OnPlayerAttached(EntityUid uid, DrunkComponent component, LocalPlayerAttachedEvent args)
{
_overlayMan.AddOverlay(_overlay);
}
private void OnPlayerDetached(EntityUid uid, DrunkComponent component, PlayerDetachedEvent args)
private void OnPlayerDetached(EntityUid uid, DrunkComponent component, LocalPlayerDetachedEvent args)
{
_overlay.CurrentBoozePower = 0;
_overlayMan.RemoveOverlay(_overlay);

View File

@ -1,17 +1,7 @@
using Content.Shared.Eye.Blinding;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.Player;
using System;
using System.Collections.Generic;
using System.Linq;
using Content.Shared.Administration;
using Content.Shared.Administration.Events;
using Content.Shared.Eye.Blinding.Components;
using Content.Shared.GameTicking;
using Robust.Shared.GameObjects;
using Robust.Shared.Network;
namespace Content.Client.Eye.Blinding;
@ -31,20 +21,20 @@ public sealed class BlindingSystem : EntitySystem
SubscribeLocalEvent<BlindableComponent, ComponentInit>(OnBlindInit);
SubscribeLocalEvent<BlindableComponent, ComponentShutdown>(OnBlindShutdown);
SubscribeLocalEvent<BlindableComponent, PlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<BlindableComponent, PlayerDetachedEvent>(OnPlayerDetached);
SubscribeLocalEvent<BlindableComponent, LocalPlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<BlindableComponent, LocalPlayerDetachedEvent>(OnPlayerDetached);
SubscribeNetworkEvent<RoundRestartCleanupEvent>(RoundRestartCleanup);
_overlay = new();
}
private void OnPlayerAttached(EntityUid uid, BlindableComponent component, PlayerAttachedEvent args)
private void OnPlayerAttached(EntityUid uid, BlindableComponent component, LocalPlayerAttachedEvent args)
{
_overlayMan.AddOverlay(_overlay);
}
private void OnPlayerDetached(EntityUid uid, BlindableComponent component, PlayerDetachedEvent args)
private void OnPlayerDetached(EntityUid uid, BlindableComponent component, LocalPlayerDetachedEvent args)
{
_overlayMan.RemoveOverlay(_overlay);
_lightManager.Enabled = true;

View File

@ -1,9 +1,6 @@
using Content.Shared.Eye.Blinding;
using Content.Shared.Eye.Blinding.Components;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.Player;
using Robust.Shared.GameStates;
namespace Content.Client.Eye.Blinding;
@ -20,18 +17,18 @@ public sealed class BlurryVisionSystem : EntitySystem
SubscribeLocalEvent<BlurryVisionComponent, ComponentInit>(OnBlurryInit);
SubscribeLocalEvent<BlurryVisionComponent, ComponentShutdown>(OnBlurryShutdown);
SubscribeLocalEvent<BlurryVisionComponent, PlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<BlurryVisionComponent, PlayerDetachedEvent>(OnPlayerDetached);
SubscribeLocalEvent<BlurryVisionComponent, LocalPlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<BlurryVisionComponent, LocalPlayerDetachedEvent>(OnPlayerDetached);
_overlay = new();
}
private void OnPlayerAttached(EntityUid uid, BlurryVisionComponent component, PlayerAttachedEvent args)
private void OnPlayerAttached(EntityUid uid, BlurryVisionComponent component, LocalPlayerAttachedEvent args)
{
_overlayMan.AddOverlay(_overlay);
}
private void OnPlayerDetached(EntityUid uid, BlurryVisionComponent component, PlayerDetachedEvent args)
private void OnPlayerDetached(EntityUid uid, BlurryVisionComponent component, LocalPlayerDetachedEvent args)
{
_overlayMan.RemoveOverlay(_overlay);
}

View File

@ -30,7 +30,7 @@ public sealed class EyeLerpingSystem : EntitySystem
SubscribeLocalEvent<EyeAttachedEvent>(OnAttached);
SubscribeLocalEvent<LerpingEyeComponent, EntParentChangedMessage>(HandleMapChange);
SubscribeLocalEvent<LerpingEyeComponent, PlayerDetachedEvent>(OnDetached);
SubscribeLocalEvent<LerpingEyeComponent, LocalPlayerDetachedEvent>(OnDetached);
UpdatesAfter.Add(typeof(TransformSystem));
UpdatesAfter.Add(typeof(PhysicsSystem));
@ -94,7 +94,7 @@ public sealed class EyeLerpingSystem : EntitySystem
AddEye(ev.Entity, ev.Component, true);
}
private void OnDetached(EntityUid uid, LerpingEyeComponent component, PlayerDetachedEvent args)
private void OnDetached(EntityUid uid, LerpingEyeComponent component, LocalPlayerDetachedEvent args)
{
if (!component.ManuallyAdded)
RemCompDeferred(uid, component);

View File

@ -4,7 +4,7 @@ using Robust.Client.Input;
using Robust.Shared.Input.Binding;
using Robust.Shared;
using Robust.Shared.Configuration;
using Robust.Shared.Players;
using Robust.Shared.Player;
namespace Content.Client.Fullscreen;
public sealed class FullscreenHook

View File

@ -16,7 +16,7 @@ using Robust.Shared.Console;
using Robust.Shared.Input;
using Robust.Shared.Input.Binding;
using Robust.Shared.Map;
using Robust.Shared.Players;
using Robust.Shared.Player;
using Robust.Shared.Timing;
namespace Content.Client.Gameplay

View File

@ -58,10 +58,10 @@ namespace Content.Client.Ghost
SubscribeLocalEvent<GhostComponent, ComponentRemove>(OnGhostRemove);
SubscribeLocalEvent<GhostComponent, AfterAutoHandleStateEvent>(OnGhostState);
SubscribeLocalEvent<GhostComponent, PlayerAttachedEvent>(OnGhostPlayerAttach);
SubscribeLocalEvent<GhostComponent, PlayerDetachedEvent>(OnGhostPlayerDetach);
SubscribeLocalEvent<GhostComponent, LocalPlayerAttachedEvent>(OnGhostPlayerAttach);
SubscribeLocalEvent<GhostComponent, LocalPlayerDetachedEvent>(OnGhostPlayerDetach);
SubscribeLocalEvent<PlayerAttachedEvent>(OnPlayerAttach);
SubscribeLocalEvent<LocalPlayerAttachedEvent>(OnPlayerAttach);
SubscribeNetworkEvent<GhostWarpsResponseEvent>(OnGhostWarpsResponse);
SubscribeNetworkEvent<GhostUpdateGhostRoleCountEvent>(OnUpdateGhostRoleCount);
@ -130,7 +130,7 @@ namespace Content.Client.Ghost
PlayerRemoved?.Invoke(component);
}
private void OnGhostPlayerAttach(EntityUid uid, GhostComponent component, PlayerAttachedEvent playerAttachedEvent)
private void OnGhostPlayerAttach(EntityUid uid, GhostComponent component, LocalPlayerAttachedEvent localPlayerAttachedEvent)
{
if (uid != _playerManager.LocalPlayer?.ControlledEntity)
return;
@ -161,13 +161,13 @@ namespace Content.Client.Ghost
return true;
}
private void OnGhostPlayerDetach(EntityUid uid, GhostComponent component, PlayerDetachedEvent args)
private void OnGhostPlayerDetach(EntityUid uid, GhostComponent component, LocalPlayerDetachedEvent args)
{
if (PlayerDetach(uid))
component.IsAttached = false;
}
private void OnPlayerAttach(PlayerAttachedEvent ev)
private void OnPlayerAttach(LocalPlayerAttachedEvent ev)
{
if (!HasComp<GhostComponent>(ev.Entity))
PlayerDetach(ev.Entity);

View File

@ -42,8 +42,8 @@ namespace Content.Client.Hands.Systems
{
base.Initialize();
SubscribeLocalEvent<HandsComponent, PlayerAttachedEvent>(HandlePlayerAttached);
SubscribeLocalEvent<HandsComponent, PlayerDetachedEvent>(HandlePlayerDetached);
SubscribeLocalEvent<HandsComponent, LocalPlayerAttachedEvent>(HandlePlayerAttached);
SubscribeLocalEvent<HandsComponent, LocalPlayerDetachedEvent>(HandlePlayerDetached);
SubscribeLocalEvent<HandsComponent, ComponentStartup>(OnHandsStartup);
SubscribeLocalEvent<HandsComponent, ComponentShutdown>(OnHandsShutdown);
SubscribeLocalEvent<HandsComponent, ComponentHandleState>(HandleComponentState);
@ -361,12 +361,12 @@ namespace Content.Client.Hands.Systems
#region Gui
private void HandlePlayerAttached(EntityUid uid, HandsComponent component, PlayerAttachedEvent args)
private void HandlePlayerAttached(EntityUid uid, HandsComponent component, LocalPlayerAttachedEvent args)
{
OnPlayerHandsAdded?.Invoke(component);
}
private void HandlePlayerDetached(EntityUid uid, HandsComponent component, PlayerDetachedEvent args)
private void HandlePlayerDetached(EntityUid uid, HandsComponent component, LocalPlayerDetachedEvent args)
{
OnPlayerHandsRemoved?.Invoke();
}

View File

@ -1,9 +1,33 @@
<DefaultWindow xmlns="https://spacestation14.io"
MinSize="250 100"
SetSize="250 100">
<BoxContainer Orientation="Vertical">
<Label
Name="Diagnostics"
Text="{Loc health-analyzer-window-no-patient-data-text}"/>
</BoxContainer>
</DefaultWindow>
SetSize="250 100">
<ScrollContainer
VerticalExpand="True">
<BoxContainer
Name="RootContainer"
Orientation="Vertical">
<Label
Name="NoPatientDataText"
Text="{Loc health-analyzer-window-no-patient-data-text}" />
<BoxContainer
Name="PatientDataContainer"
Orientation="Vertical"
Margin="0 0 5 10">
<Label
Name="PatientName"/>
<Label
Name="Temperature"
Margin="0 5 0 0"/>
<Label
Name="BloodLevel"
Margin="0 5 0 0"/>
<Label
Name="patientDamageAmount"
Margin="0 15 0 0"/>
</BoxContainer>
<BoxContainer
Name="GroupsContainer"
Orientation="Vertical">
</BoxContainer>
</BoxContainer>
</ScrollContainer>
</DefaultWindow>

View File

@ -1,5 +1,5 @@
using System.Linq;
using System.Numerics;
using System.Text;
using Content.Shared.Damage;
using Content.Shared.Damage.Prototypes;
using Content.Shared.FixedPoint;
@ -8,85 +8,182 @@ using Content.Shared.MedicalScanner;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.UserInterface.Controls;
using Robust.Client.ResourceManagement;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
namespace Content.Client.HealthAnalyzer.UI
{
[GenerateTypedNameReferences]
public sealed partial class HealthAnalyzerWindow : DefaultWindow
{
private readonly IEntityManager _entityManager;
private readonly SpriteSystem _spriteSystem;
private readonly IPrototypeManager _prototypes;
private readonly IResourceCache _cache;
private const int AnalyzerHeight = 430;
private const int AnalyzerWidth = 300;
public HealthAnalyzerWindow()
{
RobustXamlLoader.Load(this);
var dependencies = IoCManager.Instance!;
_entityManager = dependencies.Resolve<IEntityManager>();
_spriteSystem = _entityManager.System<SpriteSystem>();
_prototypes = dependencies.Resolve<IPrototypeManager>();
_cache = dependencies.Resolve<IResourceCache>();
}
public void Populate(HealthAnalyzerScannedUserMessage msg)
{
var text = new StringBuilder();
var entities = IoCManager.Resolve<IEntityManager>();
var target = entities.GetEntity(msg.TargetEntity);
GroupsContainer.RemoveAllChildren();
if (msg.TargetEntity != null && entities.TryGetComponent<DamageableComponent>(target, out var damageable))
var target = _entityManager.GetEntity(msg.TargetEntity);
if (target == null
|| !_entityManager.TryGetComponent<DamageableComponent>(target, out var damageable))
{
string entityName = "Unknown";
if (msg.TargetEntity != null &&
entities.HasComponent<MetaDataComponent>(target.Value))
{
entityName = Identity.Name(target.Value, entities);
}
IReadOnlyDictionary<string, FixedPoint2> damagePerGroup = damageable.DamagePerGroup;
IReadOnlyDictionary<string, FixedPoint2> damagePerType = damageable.Damage.DamageDict;
text.Append($"{Loc.GetString("health-analyzer-window-entity-health-text", ("entityName", entityName))}\n\n");
text.Append($"{Loc.GetString("health-analyzer-window-entity-temperature-text", ("temperature", float.IsNaN(msg.Temperature) ? "N/A" : $"{msg.Temperature - 273f:F1} °C"))}\n");
text.Append($"{Loc.GetString("health-analyzer-window-entity-blood-level-text", ("bloodLevel", float.IsNaN(msg.BloodLevel) ? "N/A" : $"{msg.BloodLevel * 100:F1} %"))}\n\n");
// Damage
text.Append($"{Loc.GetString("health-analyzer-window-entity-damage-total-text", ("amount", damageable.TotalDamage))}\n");
HashSet<string> shownTypes = new();
var protos = IoCManager.Resolve<IPrototypeManager>();
// Show the total damage and type breakdown for each damage group.
foreach (var (damageGroupId, damageAmount) in damagePerGroup)
{
if (damageAmount == 0)
{
continue;
}
text.Append($"\n{Loc.GetString("health-analyzer-window-damage-group-text", ("damageGroup", Loc.GetString("health-analyzer-window-damage-group-" + damageGroupId)), ("amount", damageAmount))}");
// Show the damage for each type in that group.
var group = protos.Index<DamageGroupPrototype>(damageGroupId);
foreach (var type in group.DamageTypes)
{
if (damagePerType.TryGetValue(type, out var typeAmount) )
{
// If damage types are allowed to belong to more than one damage group, they may appear twice here. Mark them as duplicate.
if (!shownTypes.Contains(type) && typeAmount > 0)
{
shownTypes.Add(type);
text.Append($"\n- {Loc.GetString("health-analyzer-window-damage-type-text", ("damageType", Loc.GetString("health-analyzer-window-damage-type-" + type)), ("amount", typeAmount))}");
}
}
}
text.AppendLine();
}
Diagnostics.Text = text.ToString();
SetSize = new Vector2(250, 600);
NoPatientDataText.Visible = true;
return;
}
else
NoPatientDataText.Visible = false;
string entityName = Loc.GetString("health-analyzer-window-entity-unknown-text");
if (_entityManager.HasComponent<MetaDataComponent>(target.Value))
{
Diagnostics.Text = Loc.GetString("health-analyzer-window-no-patient-data-text");
SetSize = new Vector2(250, 100);
entityName = Identity.Name(target.Value, _entityManager);
}
PatientName.Text = Loc.GetString(
"health-analyzer-window-entity-health-text",
("entityName", entityName)
);
Temperature.Text = Loc.GetString("health-analyzer-window-entity-temperature-text",
("temperature", float.IsNaN(msg.Temperature) ? "N/A" : $"{msg.Temperature - 273f:F1} °C")
);
BloodLevel.Text = Loc.GetString("health-analyzer-window-entity-blood-level-text",
("bloodLevel", float.IsNaN(msg.BloodLevel) ? "N/A" : $"{msg.BloodLevel * 100:F1} %")
);
patientDamageAmount.Text = Loc.GetString(
"health-analyzer-window-entity-damage-total-text",
("amount", damageable.TotalDamage)
);
var damageSortedGroups =
damageable.DamagePerGroup.OrderBy(damage => damage.Value)
.ToDictionary(x => x.Key, x => x.Value);
IReadOnlyDictionary<string, FixedPoint2> damagePerType = damageable.Damage.DamageDict;
DrawDiagnosticGroups(damageSortedGroups, damagePerType);
SetHeight = AnalyzerHeight;
SetWidth = AnalyzerWidth;
}
private void DrawDiagnosticGroups(
Dictionary<string, FixedPoint2> groups, IReadOnlyDictionary<string, FixedPoint2> damageDict)
{
HashSet<string> shownTypes = new();
// Show the total damage and type breakdown for each damage group.
foreach (var (damageGroupId, damageAmount) in groups.Reverse())
{
if (damageAmount == 0)
continue;
var groupTitleText = $"{Loc.GetString(
"health-analyzer-window-damage-group-text",
("damageGroup", Loc.GetString("health-analyzer-window-damage-group-" + damageGroupId)),
("amount", damageAmount)
)}";
var groupContainer = new BoxContainer
{
Margin = new Thickness(0, 0, 0, 15),
Align = BoxContainer.AlignMode.Begin,
Orientation = BoxContainer.LayoutOrientation.Vertical,
};
groupContainer.AddChild(CreateDiagnosticGroupTitle(groupTitleText, damageGroupId, damageAmount.Int()));
GroupsContainer.AddChild(groupContainer);
// Show the damage for each type in that group.
var group = _prototypes.Index<DamageGroupPrototype>(damageGroupId);
foreach (var type in group.DamageTypes)
{
if (damageDict.TryGetValue(type, out var typeAmount) && typeAmount > 0)
{
// If damage types are allowed to belong to more than one damage group,
// they may appear twice here. Mark them as duplicate.
if (shownTypes.Contains(type))
continue;
shownTypes.Add(type);
var damageString = Loc.GetString(
"health-analyzer-window-damage-type-text",
("damageType", Loc.GetString("health-analyzer-window-damage-type-" + type)),
("amount", typeAmount)
);
groupContainer.AddChild(CreateDiagnosticItemLabel(damageString.Insert(0, "- ")));
}
}
}
}
private Texture GetTexture(string texture)
{
var rsiPath = new ResPath("/Textures/Objects/Devices/health_analyzer.rsi");
var rsiSprite = new SpriteSpecifier.Rsi(rsiPath, texture);
var rsi = _cache.GetResource<RSIResource>(rsiSprite.RsiPath).RSI;
if (!rsi.TryGetState(rsiSprite.RsiState, out var state))
{
rsiSprite = new SpriteSpecifier.Rsi(rsiPath, "unknown");
}
return _spriteSystem.Frame0(rsiSprite);
}
private static Label CreateDiagnosticItemLabel(string text)
{
return new Label
{
Margin = new Thickness(2, 2),
Text = text,
};
}
private BoxContainer CreateDiagnosticGroupTitle(string text, string id, int damageAmount)
{
var rootContainer = new BoxContainer
{
VerticalAlignment = VAlignment.Bottom,
Orientation = BoxContainer.LayoutOrientation.Horizontal
};
rootContainer.AddChild(new TextureRect
{
Margin = new Thickness(0, 3),
SetSize = new Vector2(30, 30),
Texture = GetTexture(id.ToLower())
});
rootContainer.AddChild(CreateDiagnosticItemLabel(text));
return rootContainer;
}
}
}

View File

@ -3,8 +3,8 @@ using Content.Shared.Damage;
using Content.Shared.GameTicking;
using Content.Shared.Mobs.Components;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.Player;
namespace Content.Client.HealthOverlay
{
@ -13,9 +13,9 @@ namespace Content.Client.HealthOverlay
{
[Dependency] private readonly IEyeManager _eyeManager = default!;
[Dependency] private readonly IEntityManager _entities = default!;
[Dependency] private readonly IPlayerManager _player = default!;
private readonly Dictionary<EntityUid, HealthOverlayGui> _guis = new();
private EntityUid? _attachedEntity;
private bool _enabled;
public bool Enabled
@ -42,7 +42,6 @@ namespace Content.Client.HealthOverlay
base.Initialize();
SubscribeNetworkEvent<RoundRestartCleanupEvent>(Reset);
SubscribeLocalEvent<PlayerAttachSysMessage>(HandlePlayerAttached);
}
public void Reset(RoundRestartCleanupEvent ev)
@ -53,12 +52,6 @@ namespace Content.Client.HealthOverlay
}
_guis.Clear();
_attachedEntity = default;
}
private void HandlePlayerAttached(PlayerAttachSysMessage message)
{
_attachedEntity = message.AttachedEntity;
}
public override void FrameUpdate(float frameTime)
@ -70,7 +63,7 @@ namespace Content.Client.HealthOverlay
return;
}
if (_attachedEntity is not {} ent || Deleted(ent))
if (_player.LocalEntity is not {} ent || Deleted(ent))
{
return;
}

View File

@ -0,0 +1,39 @@
using Robust.Client.AutoGenerated;
using Robust.Client.Graphics;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
namespace Content.Client.Info.PlaytimeStats;
[GenerateTypedNameReferences]
public sealed partial class PlaytimeStatsEntry : ContainerButton
{
public TimeSpan Playtime { get; private set; } // new TimeSpan property
public PlaytimeStatsEntry(string role, TimeSpan playtime, StyleBox styleBox)
{
RobustXamlLoader.Load(this);
RoleLabel.Text = role;
Playtime = playtime; // store the TimeSpan value directly
PlaytimeLabel.Text = ConvertTimeSpanToHoursMinutes(playtime); // convert to string for display
BackgroundColorPanel.PanelOverride = styleBox;
}
private static string ConvertTimeSpanToHoursMinutes(TimeSpan timeSpan)
{
var hours = (int)timeSpan.TotalHours;
var minutes = timeSpan.Minutes;
var formattedTimeLoc = Loc.GetString("ui-playtime-time-format", ("hours", hours), ("minutes", minutes));
return formattedTimeLoc;
}
public void UpdateShading(StyleBoxFlat styleBox)
{
BackgroundColorPanel.PanelOverride = styleBox;
}
public string? PlaytimeText => PlaytimeLabel.Text;
public string? RoleText => RoleLabel.Text;
}

View File

@ -0,0 +1,20 @@
<ContainerButton xmlns="https://spacestation14.io"
xmlns:customControls1="clr-namespace:Content.Client.Administration.UI.CustomControls"
EnableAllKeybinds="True">
<PanelContainer Name="BackgroundColorPanel"/>
<BoxContainer Orientation="Horizontal"
HorizontalExpand="True"
SeparationOverride="4">
<Label Name="RoleLabel"
SizeFlagsStretchRatio="3"
HorizontalExpand="True"
ClipText="True"
Margin="5,5,5,5"/>
<customControls1:VSeparator/>
<Label Name="PlaytimeLabel"
SizeFlagsStretchRatio="3"
HorizontalExpand="True"
ClipText="True"
Margin="5,5,5,5"/>
</BoxContainer>
</ContainerButton>

View File

@ -0,0 +1,86 @@
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Input;
namespace Content.Client.Info.PlaytimeStats;
[GenerateTypedNameReferences]
public sealed partial class PlaytimeStatsHeader : ContainerButton
{
public event Action<Header, SortDirection>? OnHeaderClicked;
private SortDirection _roleDirection = SortDirection.Ascending;
private SortDirection _playtimeDirection = SortDirection.Descending;
public PlaytimeStatsHeader()
{
RobustXamlLoader.Load(this);
RoleLabel.OnKeyBindDown += RoleClicked;
PlaytimeLabel.OnKeyBindDown += PlaytimeClicked;
UpdateLabels();
}
public enum Header : byte
{
Role,
Playtime
}
public enum SortDirection : byte
{
Ascending,
Descending
}
private void HeaderClicked(GUIBoundKeyEventArgs args, Header header)
{
if (args.Function != EngineKeyFunctions.UIClick)
{
return;
}
switch (header)
{
case Header.Role:
_roleDirection = _roleDirection == SortDirection.Ascending ? SortDirection.Descending : SortDirection.Ascending;
break;
case Header.Playtime:
_playtimeDirection = _playtimeDirection == SortDirection.Ascending ? SortDirection.Descending : SortDirection.Ascending;
break;
}
UpdateLabels();
OnHeaderClicked?.Invoke(header, header == Header.Role ? _roleDirection : _playtimeDirection);
args.Handle();
}
private void UpdateLabels()
{
RoleLabel.Text = Loc.GetString("ui-playtime-header-role-type") +
(_roleDirection == SortDirection.Ascending ? " ↓" : " ↑");
PlaytimeLabel.Text = Loc.GetString("ui-playtime-header-role-time") +
(_playtimeDirection == SortDirection.Ascending ? " ↓" : " ↑");
}
private void RoleClicked(GUIBoundKeyEventArgs args)
{
HeaderClicked(args, Header.Role);
}
private void PlaytimeClicked(GUIBoundKeyEventArgs args)
{
HeaderClicked(args, Header.Playtime);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
RoleLabel.OnKeyBindDown -= RoleClicked;
PlaytimeLabel.OnKeyBindDown -= PlaytimeClicked;
}
}
}

View File

@ -0,0 +1,29 @@
<ContainerButton xmlns="https://spacestation14.io"
xmlns:customControls="clr-namespace:Content.Client.Administration.UI.CustomControls"
EnableAllKeybinds="True">
<PanelContainer Name="BackgroundColorPlaytimePanel" Access="Public"/>
<BoxContainer Orientation="Vertical"
HorizontalExpand="True">
<BoxContainer Orientation="Horizontal"
HorizontalExpand="True"
SeparationOverride="4">
<Label Name="RoleLabel"
SizeFlagsStretchRatio="3"
HorizontalExpand="True"
ClipText="True"
Text="{Loc ui-playtime-header-role-type}"
MouseFilter="Pass"
Margin="5,5,5,5"/>
<customControls:VSeparator/>
<Label Name="PlaytimeLabel"
SizeFlagsStretchRatio="3"
HorizontalExpand="True"
ClipText="True"
Text="{Loc ui-playtime-header-role-time}"
MouseFilter="Pass"
Margin="5,5,5,5"/>
</BoxContainer>
<!-- Horizontal Separator -->
<customControls:HSeparator/>
</BoxContainer>
</ContainerButton>

View File

@ -0,0 +1,146 @@
using System.Linq;
using System.Text.RegularExpressions;
using Content.Client.Players.PlayTimeTracking;
using Content.Client.UserInterface.Controls;
using Robust.Client.AutoGenerated;
using Robust.Client.Graphics;
using Robust.Client.UserInterface.XAML;
namespace Content.Client.Info.PlaytimeStats;
[GenerateTypedNameReferences]
public sealed partial class PlaytimeStatsWindow : FancyWindow
{
[Dependency] private readonly JobRequirementsManager _jobRequirementsManager = default!;
private ISawmill _sawmill = Logger.GetSawmill("PlaytimeStatsWindow");
private readonly Color _altColor = Color.FromHex("#292B38");
private readonly Color _defaultColor = Color.FromHex("#2F2F3B");
private bool _useAltColor;
public PlaytimeStatsWindow()
{
IoCManager.InjectDependencies(this);
RobustXamlLoader.Load(this);
PopulatePlaytimeHeader();
PopulatePlaytimeData();
}
private void PopulatePlaytimeHeader()
{
var header = new PlaytimeStatsHeader();
header.OnHeaderClicked += HeaderClicked;
header.BackgroundColorPlaytimePanel.PanelOverride = new StyleBoxFlat(_altColor);
RolesPlaytimeList.AddChild(header);
}
private void HeaderClicked(PlaytimeStatsHeader.Header header, PlaytimeStatsHeader.SortDirection direction)
{
switch (header)
{
case PlaytimeStatsHeader.Header.Role:
SortByRole(direction);
break;
case PlaytimeStatsHeader.Header.Playtime:
SortByPlaytime(direction);
break;
}
}
private void SortByRole(PlaytimeStatsHeader.SortDirection direction)
{
var header = RolesPlaytimeList.GetChild(0) as PlaytimeStatsHeader;
var entries = RolesPlaytimeList.Children.OfType<PlaytimeStatsEntry>().ToList();
RolesPlaytimeList.RemoveAllChildren();
if (header != null)
RolesPlaytimeList.AddChild(header);
var sortedEntries = (direction == PlaytimeStatsHeader.SortDirection.Ascending)
? entries.OrderBy(entry => entry.RoleText).ToList()
: entries.OrderByDescending(entry => entry.RoleText).ToList();
_useAltColor = false;
foreach (var entry in sortedEntries)
{
var styleBox = new StyleBoxFlat { BackgroundColor = _useAltColor ? _altColor : _defaultColor };
entry.UpdateShading(styleBox);
RolesPlaytimeList.AddChild(entry);
_useAltColor ^= true;
}
}
private void SortByPlaytime(PlaytimeStatsHeader.SortDirection direction)
{
var header = RolesPlaytimeList.GetChild(0) as PlaytimeStatsHeader;
var entries = RolesPlaytimeList.Children.OfType<PlaytimeStatsEntry>().ToList();
RolesPlaytimeList.RemoveAllChildren();
if (header != null)
RolesPlaytimeList.AddChild(header);
var sortedEntries = (direction == PlaytimeStatsHeader.SortDirection.Ascending)
? entries.OrderBy(entry => entry.Playtime).ToList()
: entries.OrderByDescending(entry => entry.Playtime).ToList();
_useAltColor = false;
foreach (var entry in sortedEntries)
{
var styleBox = new StyleBoxFlat { BackgroundColor = _useAltColor ? _altColor : _defaultColor };
entry.UpdateShading(styleBox);
RolesPlaytimeList.AddChild(entry);
_useAltColor ^= true;
}
}
private void PopulatePlaytimeData()
{
var overallPlaytime = _jobRequirementsManager.FetchOverallPlaytime();
var formattedPlaytime = ConvertTimeSpanToHoursMinutes(overallPlaytime);
OverallPlaytimeLabel.Text = Loc.GetString("ui-playtime-overall", ("time", formattedPlaytime));
var rolePlaytimes = _jobRequirementsManager.FetchPlaytimeByRoles();
RolesPlaytimeList.RemoveAllChildren();
PopulatePlaytimeHeader();
foreach (var rolePlaytime in rolePlaytimes)
{
var role = rolePlaytime.Key;
var playtime = rolePlaytime.Value;
AddRolePlaytimeEntryToTable(Loc.GetString(role), playtime.ToString());
}
}
private void AddRolePlaytimeEntryToTable(string role, string playtimeString)
{
if (TimeSpan.TryParse(playtimeString, out var playtime))
{
var entry = new PlaytimeStatsEntry(role, playtime,
new StyleBoxFlat(_useAltColor ? _altColor : _defaultColor));
RolesPlaytimeList.AddChild(entry);
_useAltColor ^= true;
}
else
{
_sawmill.Error($"The provided playtime string '{playtimeString}' is not in the correct format.");
}
}
private static string ConvertTimeSpanToHoursMinutes(TimeSpan timeSpan)
{
var hours = (int) timeSpan.TotalHours;
var minutes = timeSpan.Minutes;
var formattedTimeLoc = Loc.GetString("ui-playtime-time-format", ("hours", hours), ("minutes", minutes));
return formattedTimeLoc;
}
}

View File

@ -0,0 +1,25 @@
<ui:FancyWindow xmlns="https://spacestation14.io"
xmlns:ui="clr-namespace:Content.Client.UserInterface.Controls"
xmlns:pt="clr-namespace:Content.Client.Info.PlaytimeStats"
xmlns:customControls="clr-namespace:Content.Client.Administration.UI.CustomControls"
VerticalExpand="True" HorizontalExpand="True"
Title="{Loc ui-playtime-stats-title}"
SetSize="600 400">
<Control>
<BoxContainer Name="statsBox" Orientation="Vertical" Margin="10,10,10,10">
<!-- Overall Playtime -->
<Label Name="OverallPlaytimeLabel" HorizontalExpand="True" Text="{Loc ui-playtime-overall-base}" />
<Control MinSize="0 5" />
<!-- Table for roles -->
<ScrollContainer HorizontalExpand="True" VerticalExpand="True">
<BoxContainer Orientation="Vertical" Name="RolesPlaytimeList">
<!-- Table Header -->
<pt:PlaytimeStatsHeader Name="ListHeader" />
<customControls:HSeparator />
</BoxContainer>
</ScrollContainer>
</BoxContainer>
</Control>
</ui:FancyWindow>

View File

@ -10,7 +10,6 @@ using Content.Shared.Inventory;
using Content.Shared.Inventory.Events;
using Content.Shared.Storage;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Client.Player;
using Robust.Client.UserInterface;
using Robust.Shared.Containers;
@ -43,8 +42,8 @@ namespace Content.Client.Inventory
UpdatesOutsidePrediction = true;
base.Initialize();
SubscribeLocalEvent<InventorySlotsComponent, PlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<InventorySlotsComponent, PlayerDetachedEvent>(OnPlayerDetached);
SubscribeLocalEvent<InventorySlotsComponent, LocalPlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<InventorySlotsComponent, LocalPlayerDetachedEvent>(OnPlayerDetached);
SubscribeLocalEvent<InventoryComponent, ComponentShutdown>(OnShutdown);
@ -113,12 +112,12 @@ namespace Content.Client.Inventory
OnUnlinkInventory?.Invoke();
}
private void OnPlayerDetached(EntityUid uid, InventorySlotsComponent component, PlayerDetachedEvent args)
private void OnPlayerDetached(EntityUid uid, InventorySlotsComponent component, LocalPlayerDetachedEvent args)
{
OnUnlinkInventory?.Invoke();
}
private void OnPlayerAttached(EntityUid uid, InventorySlotsComponent component, PlayerAttachedEvent args)
private void OnPlayerAttached(EntityUid uid, InventorySlotsComponent component, LocalPlayerAttachedEvent args)
{
if (TryGetSlots(uid, out var definitions))
{

View File

@ -19,22 +19,17 @@ public sealed partial class DogVisionSystem : EntitySystem
SubscribeLocalEvent<DogVisionComponent, ComponentInit>(OnDogVisionInit);
SubscribeLocalEvent<DogVisionComponent, ComponentShutdown>(OnDogVisionShutdown);
SubscribeLocalEvent<DogVisionComponent, PlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<DogVisionComponent, PlayerDetachedEvent>(OnPlayerDetached);
_player.LocalPlayerAttached += OnAttachedChanged;
_player.LocalPlayerDetached += OnAttachedChanged;
_overlay = new();
}
private void OnPlayerAttached(EntityUid uid, DogVisionComponent component, PlayerAttachedEvent args)
private void OnAttachedChanged(EntityUid uid)
{
_overlayMan.AddOverlay(_overlay);
}
private void OnPlayerDetached(EntityUid uid, DogVisionComponent component, PlayerDetachedEvent args)
{
_overlayMan.RemoveOverlay(_overlay);
}
private void OnDogVisionInit(EntityUid uid, DogVisionComponent component, ComponentInit args)
{
if (_player.LocalPlayer?.ControlledEntity == uid)

View File

@ -1,7 +1,6 @@
using Content.Shared.GameTicking;
using Content.Shared.Inventory;
using Content.Shared.Inventory.Events;
using Robust.Client.GameObjects;
using Robust.Client.Player;
namespace Content.Client.Overlays;
@ -24,8 +23,8 @@ public abstract class EquipmentHudSystem<T> : EntitySystem where T : IComponent
SubscribeLocalEvent<T, ComponentStartup>(OnStartup);
SubscribeLocalEvent<T, ComponentRemove>(OnRemove);
SubscribeLocalEvent<PlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<PlayerDetachedEvent>(OnPlayerDetached);
SubscribeLocalEvent<LocalPlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<LocalPlayerDetachedEvent>(OnPlayerDetached);
SubscribeLocalEvent<T, GotEquippedEvent>(OnCompEquip);
SubscribeLocalEvent<T, GotUnequippedEvent>(OnCompUnequip);
@ -65,12 +64,12 @@ public abstract class EquipmentHudSystem<T> : EntitySystem where T : IComponent
RefreshOverlay(uid);
}
private void OnPlayerAttached(PlayerAttachedEvent args)
private void OnPlayerAttached(LocalPlayerAttachedEvent args)
{
RefreshOverlay(args.Entity);
}
private void OnPlayerDetached(PlayerDetachedEvent args)
private void OnPlayerDetached(LocalPlayerDetachedEvent args)
{
if (_player.LocalPlayer?.ControlledEntity == null)
Deactivate();

View File

@ -1,7 +1,6 @@
using Content.Shared.Movement.Components;
using Content.Shared.Movement.Systems;
using Content.Shared.Pulling.Components;
using Robust.Client.GameObjects;
using Robust.Client.Physics;
using Robust.Client.Player;
using Robust.Shared.Physics.Components;
@ -17,10 +16,10 @@ namespace Content.Client.Physics.Controllers
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<RelayInputMoverComponent, PlayerAttachedEvent>(OnRelayPlayerAttached);
SubscribeLocalEvent<RelayInputMoverComponent, PlayerDetachedEvent>(OnRelayPlayerDetached);
SubscribeLocalEvent<InputMoverComponent, PlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<InputMoverComponent, PlayerDetachedEvent>(OnPlayerDetached);
SubscribeLocalEvent<RelayInputMoverComponent, LocalPlayerAttachedEvent>(OnRelayPlayerAttached);
SubscribeLocalEvent<RelayInputMoverComponent, LocalPlayerDetachedEvent>(OnRelayPlayerDetached);
SubscribeLocalEvent<InputMoverComponent, LocalPlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<InputMoverComponent, LocalPlayerDetachedEvent>(OnPlayerDetached);
SubscribeLocalEvent<InputMoverComponent, UpdateIsPredictedEvent>(OnUpdatePredicted);
SubscribeLocalEvent<MovementRelayTargetComponent, UpdateIsPredictedEvent>(OnUpdateRelayTargetPredicted);
@ -54,7 +53,7 @@ namespace Content.Client.Physics.Controllers
// What if the entity is being pulled by a vehicle controlled by the player?
}
private void OnRelayPlayerAttached(EntityUid uid, RelayInputMoverComponent component, PlayerAttachedEvent args)
private void OnRelayPlayerAttached(EntityUid uid, RelayInputMoverComponent component, LocalPlayerAttachedEvent args)
{
Physics.UpdateIsPredicted(uid);
Physics.UpdateIsPredicted(component.RelayEntity);
@ -62,7 +61,7 @@ namespace Content.Client.Physics.Controllers
SetMoveInput(inputMover, MoveButtons.None);
}
private void OnRelayPlayerDetached(EntityUid uid, RelayInputMoverComponent component, PlayerDetachedEvent args)
private void OnRelayPlayerDetached(EntityUid uid, RelayInputMoverComponent component, LocalPlayerDetachedEvent args)
{
Physics.UpdateIsPredicted(uid);
Physics.UpdateIsPredicted(component.RelayEntity);
@ -70,12 +69,12 @@ namespace Content.Client.Physics.Controllers
SetMoveInput(inputMover, MoveButtons.None);
}
private void OnPlayerAttached(EntityUid uid, InputMoverComponent component, PlayerAttachedEvent args)
private void OnPlayerAttached(EntityUid uid, InputMoverComponent component, LocalPlayerAttachedEvent args)
{
SetMoveInput(component, MoveButtons.None);
}
private void OnPlayerDetached(EntityUid uid, InputMoverComponent component, PlayerDetachedEvent args)
private void OnPlayerDetached(EntityUid uid, InputMoverComponent component, LocalPlayerDetachedEvent args)
{
SetMoveInput(component, MoveButtons.None);
}

View File

@ -1,6 +1,4 @@
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;
using Content.Shared.CCVar;
using Content.Shared.Players;
using Content.Shared.Players.PlayTimeTracking;
@ -123,4 +121,24 @@ public sealed partial class JobRequirementsManager
reason = reasons.Count == 0 ? null : FormattedMessage.FromMarkup(string.Join('\n', reasons));
return reason == null;
}
public TimeSpan FetchOverallPlaytime()
{
return _roles.TryGetValue("Overall", out var overallPlaytime) ? overallPlaytime : TimeSpan.Zero;
}
public IEnumerable<KeyValuePair<string, TimeSpan>> FetchPlaytimeByRoles()
{
var jobsToMap = _prototypes.EnumeratePrototypes<JobPrototype>();
foreach (var job in jobsToMap)
{
if (_roles.TryGetValue(job.PlayTimeTracker, out var locJobName))
{
yield return new KeyValuePair<string, TimeSpan>(job.Name, locJobName);
}
}
}
}

View File

@ -1,11 +1,11 @@
using Content.Shared.Players;
using Robust.Shared.Players;
using Robust.Shared.Player;
namespace Content.Client.Players;
public sealed class PlayerSystem : SharedPlayerSystem
{
public override PlayerData? ContentData(ICommonSession? session)
public override ContentPlayerData? ContentData(ICommonSession? session)
{
return null;
}

View File

@ -9,7 +9,6 @@ using Robust.Client.UserInterface;
using Robust.Shared.Configuration;
using Robust.Shared.Map;
using Robust.Shared.Player;
using Robust.Shared.Players;
using Robust.Shared.Prototypes;
using Robust.Shared.Replays;
using Robust.Shared.Timing;

View File

@ -14,6 +14,7 @@ public sealed partial class GeneratorWindow : FancyWindow
[Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly ILocalizationManager _loc = default!;
private readonly SharedPowerSwitchableSystem _switchable;
private readonly FuelGeneratorComponent? _component;
private PortableGeneratorComponentBuiState? _lastState;
@ -24,6 +25,7 @@ public sealed partial class GeneratorWindow : FancyWindow
IoCManager.InjectDependencies(this);
_entityManager.TryGetComponent(entity, out _component);
_switchable = _entityManager.System<SharedPowerSwitchableSystem>();
EntityView.SetEntity(entity);
TargetPower.IsValid += IsValid;
@ -99,17 +101,16 @@ public sealed partial class GeneratorWindow : FancyWindow
StatusLabel.SetOnlyStyleClass("Danger");
}
var canSwitch = _entityManager.TryGetComponent(_entity, out PowerSwitchableGeneratorComponent? switchable);
var canSwitch = _entityManager.TryGetComponent(_entity, out PowerSwitchableComponent? switchable);
OutputSwitchLabel.Visible = canSwitch;
OutputSwitchButton.Visible = canSwitch;
if (canSwitch)
if (switchable != null)
{
var isHV = switchable!.ActiveOutput == PowerSwitchableGeneratorOutput.HV;
OutputSwitchLabel.Text =
Loc.GetString(isHV ? "portable-generator-ui-switch-hv" : "portable-generator-ui-switch-mv");
OutputSwitchButton.Text =
Loc.GetString(isHV ? "portable-generator-ui-switch-to-mv" : "portable-generator-ui-switch-to-hv");
var voltage = _switchable.VoltageString(_switchable.GetVoltage(_entity, switchable));
OutputSwitchLabel.Text = Loc.GetString("portable-generator-ui-current-output", ("voltage", voltage));
var nextVoltage = _switchable.VoltageString(_switchable.GetNextVoltage(_entity, switchable));
OutputSwitchButton.Text = Loc.GetString("power-switchable-switch-voltage", ("voltage", nextVoltage));
OutputSwitchButton.Disabled = state.On;
}

View File

@ -0,0 +1,7 @@
using Content.Shared.Power.Generator;
namespace Content.Client.Power.Generator;
public sealed class PowerSwitchableSystem : SharedPowerSwitchableSystem
{
}

View File

@ -10,10 +10,13 @@
<Label Text="{Loc 'character-setup-gui-character-setup-label'}"
Margin="8 0 0 0" VAlign="Center"
StyleClasses="LabelHeadingBigger" />
<Button Name="RulesButton" HorizontalExpand="True"
Text="{Loc 'character-setup-gui-character-setup-rules-button'}"
<Button Name="StatsButton" HorizontalExpand="True"
Text="{Loc 'character-setup-gui-character-setup-stats-button'}"
StyleClasses="ButtonBig"
HorizontalAlignment="Right" />
<Button Name="RulesButton"
Text="{Loc 'character-setup-gui-character-setup-rules-button'}"
StyleClasses="ButtonBig"/>
<Button Name="SaveButton"
Access="Public"
Text="{Loc 'character-setup-gui-character-setup-save-button'}"

View File

@ -2,6 +2,7 @@ using System.Linq;
using System.Numerics;
using Content.Client.Humanoid;
using Content.Client.Info;
using Content.Client.Info.PlaytimeStats;
using Content.Client.Lobby.UI;
using Content.Client.Resources;
using Content.Client.Stylesheets;
@ -80,6 +81,8 @@ namespace Content.Client.Preferences.UI
UpdateUI();
RulesButton.OnPressed += _ => new RulesAndInfoWindow().Open();
StatsButton.OnPressed += _ => new PlaytimeStatsWindow().OpenCentered();
preferencesManager.OnServerDataLoaded += UpdateUI;
}

View File

@ -2,7 +2,7 @@ using Content.Shared.Movement.Components;
using Robust.Shared.Input;
using Robust.Shared.Input.Binding;
using Robust.Shared.Map;
using Robust.Shared.Players;
using Robust.Shared.Player;
namespace Content.Client.Replay.Spectator;

View File

@ -1,5 +1,5 @@
using Content.Shared.Movement.Components;
using Robust.Client.GameObjects;
using Robust.Client.Player;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using Robust.Shared.Network;
@ -79,7 +79,7 @@ public sealed partial class ReplaySpectatorSystem
public void SetSpectatorPosition(SpectatorData data)
{
if (_player.LocalPlayer == null)
if (_player.LocalSession == null)
return;
if (data.Controller != null
@ -87,13 +87,13 @@ public sealed partial class ReplaySpectatorSystem
&& Exists(session.AttachedEntity)
&& Transform(session.AttachedEntity.Value).MapID != MapId.Nullspace)
{
_player.LocalPlayer.AttachEntity(session.AttachedEntity.Value, EntityManager, _client);
_player.SetAttachedEntity(_player.LocalSession, session.AttachedEntity);
return;
}
if (Exists(data.Entity) && Transform(data.Entity).MapID != MapId.Nullspace)
{
_player.LocalPlayer.AttachEntity(data.Entity, EntityManager, _client);
_player.SetAttachedEntity(_player.LocalSession, data.Entity);
return;
}
@ -118,7 +118,7 @@ public sealed partial class ReplaySpectatorSystem
return;
}
if (data.Eye != null && TryComp(_player.LocalPlayer.ControlledEntity, out InputMoverComponent? newMover))
if (data.Eye != null && TryComp(_player.LocalSession.AttachedEntity, out InputMoverComponent? newMover))
{
newMover.RelativeEntity = data.Eye.Value.Ent;
newMover.TargetRelativeRotation = newMover.RelativeRotation = data.Eye.Value.Rot;
@ -177,7 +177,7 @@ public sealed partial class ReplaySpectatorSystem
SetSpectatorPosition(default);
}
private void OnDetached(EntityUid uid, ReplaySpectatorComponent component, PlayerDetachedEvent args)
private void OnDetached(EntityUid uid, ReplaySpectatorComponent component, LocalPlayerDetachedEvent args)
{
if (IsClientSide(uid))
QueueDel(uid);

View File

@ -32,10 +32,10 @@ public sealed partial class ReplaySpectatorSystem
public void SpectateEntity(EntityUid target)
{
if (_player.LocalPlayer == null)
if (_player.LocalSession == null)
return;
var old = _player.LocalPlayer.ControlledEntity;
var old = _player.LocalSession.AttachedEntity;
if (old == target)
{
@ -44,7 +44,7 @@ public sealed partial class ReplaySpectatorSystem
return;
}
_player.LocalPlayer.AttachEntity(target, EntityManager, _client);
_player.SetAttachedEntity(_player.LocalSession, target);
EnsureComp<ReplaySpectatorComponent>(target);
_stateMan.RequestStateChange<ReplaySpectateEntityState>();
@ -59,10 +59,10 @@ public sealed partial class ReplaySpectatorSystem
public TransformComponent SpawnSpectatorGhost(EntityCoordinates coords, bool gridAttach)
{
if (_player.LocalPlayer == null)
if (_player.LocalSession == null)
throw new InvalidOperationException();
var old = _player.LocalPlayer.ControlledEntity;
var old = _player.LocalSession.AttachedEntity;
var ent = Spawn("ReplayObserver", coords);
_eye.SetMaxZoom(ent, Vector2.One * 5);
@ -73,7 +73,7 @@ public sealed partial class ReplaySpectatorSystem
if (gridAttach)
_transform.AttachToGridOrMap(ent);
_player.LocalPlayer.AttachEntity(ent, EntityManager, _client);
_player.SetAttachedEntity(_player.LocalSession, ent);
if (old != null)
{
@ -93,7 +93,7 @@ public sealed partial class ReplaySpectatorSystem
{
if (args.Length == 0)
{
if (_player.LocalPlayer?.ControlledEntity is { } current)
if (_player.LocalSession?.AttachedEntity is { } current)
SpawnSpectatorGhost(new EntityCoordinates(current, default), true);
else
SpawnSpectatorGhost(default, true);

View File

@ -6,7 +6,6 @@ using Robust.Client.Player;
using Robust.Client.Replays.Playback;
using Robust.Client.State;
using Robust.Shared.Console;
using Robust.Shared.Network;
using Robust.Shared.Serialization.Markdown.Mapping;
namespace Content.Client.Replay.Spectator;
@ -40,7 +39,7 @@ public sealed partial class ReplaySpectatorSystem : EntitySystem
SubscribeLocalEvent<GetVerbsEvent<AlternativeVerb>>(OnGetAlternativeVerbs);
SubscribeLocalEvent<ReplaySpectatorComponent, EntityTerminatingEvent>(OnTerminating);
SubscribeLocalEvent<ReplaySpectatorComponent, PlayerDetachedEvent>(OnDetached);
SubscribeLocalEvent<ReplaySpectatorComponent, LocalPlayerDetachedEvent>(OnDetached);
SubscribeLocalEvent<ReplaySpectatorComponent, EntParentChangedMessage>(OnParentChanged);
InitializeBlockers();

View File

@ -5,7 +5,7 @@ using Robust.Client.Console;
using Robust.Client.Placement;
using Robust.Client.Placement.Modes;
using Robust.Shared.Map;
using Robust.Shared.Players;
using Robust.Shared.Player;
namespace Content.Client.Sandbox
{

View File

@ -89,7 +89,7 @@ public class DockingControl : Control
// Draw the fixtures around the dock before drawing it
if (_entManager.TryGetComponent<FixturesComponent>(GridEntity, out var fixtures))
{
foreach (var (_, fixture) in fixtures.Fixtures)
foreach (var fixture in fixtures.Fixtures.Values)
{
var poly = (PolygonShape) fixture.Shape;
@ -151,7 +151,7 @@ public class DockingControl : Control
var xformQuery = _entManager.GetEntityQuery<TransformComponent>();
_grids.Clear();
_mapManager.FindGridsIntersecting(gridXform.MapID, new Box2(worldPos - RangeVector, worldPos + RangeVector));
_mapManager.FindGridsIntersecting(gridXform.MapID, new Box2(worldPos - RangeVector, worldPos + RangeVector), ref _grids);
foreach (var grid in _grids)
{

View File

@ -61,9 +61,9 @@ namespace Content.Client.Storage
_window?.BuildEntityList(uid, component);
}
public void InteractWithItem(BaseButton.ButtonEventArgs args, ListData cData)
public void InteractWithItem(BaseButton.ButtonEventArgs? args, ListData? cData)
{
if (cData is not EntityListData { Uid: var entity })
if (args == null || cData is not EntityListData { Uid: var entity })
return;
if (args.Event.Function == EngineKeyFunctions.UIClick)

View File

@ -1,8 +1,6 @@
using System.Numerics;
using Content.Shared.Traits.Assorted;
using Content.Client.Camera;
using Robust.Shared.Random;
using Robust.Client.GameObjects;
using Robust.Client.Player;
using Robust.Shared.Timing;
@ -19,7 +17,7 @@ public sealed class ParacusiaSystem : SharedParacusiaSystem
{
base.Initialize();
SubscribeLocalEvent<ParacusiaComponent, ComponentStartup>(OnComponentStartup);
SubscribeLocalEvent<ParacusiaComponent, PlayerDetachedEvent>(OnPlayerDetach);
SubscribeLocalEvent<ParacusiaComponent, LocalPlayerDetachedEvent>(OnPlayerDetach);
}
public override void Update(float frameTime)
@ -40,7 +38,7 @@ public sealed class ParacusiaSystem : SharedParacusiaSystem
component.NextIncidentTime = _timing.CurTime + TimeSpan.FromSeconds(_random.NextFloat(component.MinTimeBetweenIncidents, component.MaxTimeBetweenIncidents));
}
private void OnPlayerDetach(EntityUid uid, ParacusiaComponent component, PlayerDetachedEvent args)
private void OnPlayerDetach(EntityUid uid, ParacusiaComponent component, LocalPlayerDetachedEvent args)
{
component.Stream?.Stop();
}

View File

@ -22,7 +22,7 @@ public sealed class ListContainer : Control
}
public bool Toggle { get; set; }
public Action<ListData, ListContainerButton>? GenerateItem;
public Action<BaseButton.ButtonEventArgs, ListData>? ItemPressed;
public Action<BaseButton.ButtonEventArgs?, ListData?>? ItemPressed;
public IReadOnlyList<ListData> Data => _data;
private const int DefaultSeparation = 3;
@ -92,6 +92,12 @@ public sealed class ListContainer : Control
_data = data.ToList();
_updateChildren = true;
InvalidateArrange();
if (_selected != null && !data.Contains(_selected))
{
_selected = null;
ItemPressed?.Invoke(null, null);
}
}
public void DirtyList()

View File

@ -8,6 +8,7 @@ using Content.Client.UserInterface.Systems.Objectives.Controls;
using Content.Shared.Input;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Client.Player;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controllers;
using Robust.Client.UserInterface.Controls;
@ -21,6 +22,7 @@ namespace Content.Client.UserInterface.Systems.Character;
[UsedImplicitly]
public sealed class CharacterUIController : UIController, IOnStateEntered<GameplayState>, IOnStateExited<GameplayState>, IOnSystemChanged<CharacterInfoSystem>
{
[Dependency] private readonly IPlayerManager _player = default!;
[UISystemDependency] private readonly CharacterInfoSystem _characterInfo = default!;
[UISystemDependency] private readonly SpriteSystem _sprite = default!;
@ -56,13 +58,13 @@ public sealed class CharacterUIController : UIController, IOnStateEntered<Gamepl
public void OnSystemLoaded(CharacterInfoSystem system)
{
system.OnCharacterUpdate += CharacterUpdated;
system.OnCharacterDetached += CharacterDetached;
_player.LocalPlayerDetached += CharacterDetached;
}
public void OnSystemUnloaded(CharacterInfoSystem system)
{
system.OnCharacterUpdate -= CharacterUpdated;
system.OnCharacterDetached -= CharacterDetached;
_player.LocalPlayerDetached -= CharacterDetached;
}
public void UnloadButton()
@ -160,7 +162,7 @@ public sealed class CharacterUIController : UIController, IOnStateEntered<Gamepl
_window.RolePlaceholder.Visible = briefing == null && !controls.Any() && !objectives.Any();
}
private void CharacterDetached()
private void CharacterDetached(EntityUid uid)
{
CloseWindow();
}

View File

@ -167,7 +167,8 @@ public sealed class ChatUIController : UIController
_sawmill.Level = LogLevel.Info;
_admin.AdminStatusUpdated += UpdateChannelPermissions;
_manager.PermissionsUpdated += UpdateChannelPermissions; //Nyano - Summary: the event for when permissions are updated for psionics.
_player.LocalPlayerChanged += OnLocalPlayerChanged;
_player.LocalPlayerAttached += OnAttachedChanged;
_player.LocalPlayerDetached += OnAttachedChanged;
_state.OnStateChanged += StateChanged;
_net.RegisterNetMessage<MsgChatMessage>(OnChatMessage);
_net.RegisterNetMessage<MsgDeleteChatMessagesBy>(OnDeleteChatMessagesBy);
@ -175,7 +176,7 @@ public sealed class ChatUIController : UIController
_speechBubbleRoot = new LayoutContainer();
OnLocalPlayerChanged(new LocalPlayerChangedEventArgs(null, _player.LocalPlayer));
UpdateChannelPermissions();
_input.SetInputCommand(ContentKeyFunctions.FocusChat,
InputCmdHandler.FromDelegate(_ => FocusChat()));
@ -368,29 +369,7 @@ public sealed class ChatUIController : UIController
_speechBubbleRoot.SetPositionLast();
}
private void OnLocalPlayerChanged(LocalPlayerChangedEventArgs obj)
{
if (obj.OldPlayer != null)
{
obj.OldPlayer.EntityAttached -= OnLocalPlayerEntityAttached;
obj.OldPlayer.EntityDetached -= OnLocalPlayerEntityDetached;
}
if (obj.NewPlayer != null)
{
obj.NewPlayer.EntityAttached += OnLocalPlayerEntityAttached;
obj.NewPlayer.EntityDetached += OnLocalPlayerEntityDetached;
}
UpdateChannelPermissions();
}
private void OnLocalPlayerEntityAttached(EntityAttachedEventArgs obj)
{
UpdateChannelPermissions();
}
private void OnLocalPlayerEntityDetached(EntityDetachedEventArgs obj)
private void OnAttachedChanged(EntityUid uid)
{
UpdateChannelPermissions();
}
@ -532,7 +511,7 @@ public sealed class ChatUIController : UIController
FilterableChannels |= ChatChannel.Telepathic; //Nyano - Summary: makes admins able to see psionic chat.
}
// Nyano - Summary: - Begin modified code block to add telepathic as a channel for a psionic user.
// Nyano - Summary: - Begin modified code block to add telepathic as a channel for a psionic user.
if (_psionic != null && _psionic.IsPsionic)
{
FilterableChannels |= ChatChannel.Telepathic;

View File

@ -1,11 +1,9 @@
using Content.Client.Alerts;
using Content.Shared.Damage;
using Content.Shared.FixedPoint;
using Content.Shared.Mobs;
using Content.Shared.Mobs.Components;
using Content.Shared.Mobs.Systems;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.Player;
using Robust.Client.UserInterface;
@ -25,13 +23,13 @@ public sealed class DamageOverlayUiController : UIController
public override void Initialize()
{
_overlay = new Overlays.DamageOverlay();
SubscribeLocalEvent<PlayerAttachedEvent>(OnPlayerAttach);
SubscribeLocalEvent<PlayerDetachedEvent>(OnPlayerDetached);
SubscribeLocalEvent<LocalPlayerAttachedEvent>(OnPlayerAttach);
SubscribeLocalEvent<LocalPlayerDetachedEvent>(OnPlayerDetached);
SubscribeLocalEvent<MobStateChangedEvent>(OnMobStateChanged);
SubscribeLocalEvent<MobThresholdChecked>(OnThresholdCheck);
}
private void OnPlayerAttach(PlayerAttachedEvent args)
private void OnPlayerAttach(LocalPlayerAttachedEvent args)
{
ClearOverlay();
if (!EntityManager.TryGetComponent<MobStateComponent>(args.Entity, out var mobState))
@ -41,7 +39,7 @@ public sealed class DamageOverlayUiController : UIController
_overlayManager.AddOverlay(_overlay);
}
private void OnPlayerDetached(PlayerDetachedEvent args)
private void OnPlayerDetached(LocalPlayerDetachedEvent args)
{
_overlayManager.RemoveOverlay(_overlay);
ClearOverlay();

View File

@ -17,7 +17,7 @@ using Robust.Client.UserInterface.Controllers;
using Robust.Client.UserInterface.Controllers.Implementations;
using Robust.Shared.Input.Binding;
using Robust.Shared.Map;
using Robust.Shared.Players;
using Robust.Shared.Player;
using Robust.Shared.Utility;
using static Robust.Client.UserInterface.Controls.BaseButton;

View File

@ -1,6 +1,6 @@
<DefaultWindow xmlns="https://spacestation14.io">
<BoxContainer Orientation="Vertical">
<LineEdit Name="SearchBar" PlaceHolder="{Loc 'vending-machine-component-search-filter'}" HorizontalExpand="True" Margin ="0 4"/>
<LineEdit Name="SearchBar" PlaceHolder="{Loc 'vending-machine-component-search-filter'}" HorizontalExpand="True" Margin ="0 4" Access="Public"/>
<ItemList Name="VendingContents"
SizeFlagsStretchRatio="8"
VerticalExpand="True">

View File

@ -6,7 +6,6 @@ using Robust.Client.Graphics;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Graphics;
using Robust.Shared.Prototypes;
namespace Content.Client.VendingMachines.UI
@ -32,7 +31,6 @@ namespace Content.Client.VendingMachines.UI
VendingContents.OnItemSelected += args =>
{
SearchBar.Text = string.Empty;
OnItemSelected?.Invoke(args);
};
}
@ -41,8 +39,10 @@ namespace Content.Client.VendingMachines.UI
/// Populates the list of available items on the vending machine interface
/// and sets icons based on their prototypes
/// </summary>
public void Populate(List<VendingMachineInventoryEntry> inventory, string? filter = null)
public void Populate(List<VendingMachineInventoryEntry> inventory, out List<int> filteredInventory, string? filter = null)
{
filteredInventory = new();
if (inventory.Count == 0)
{
VendingContents.Clear();
@ -93,6 +93,7 @@ namespace Content.Client.VendingMachines.UI
vendingItem.Text = $"{itemName} [{entry.Amount}]";
vendingItem.Icon = icon;
filteredInventory.Add(i);
}
SetSizeAfterUpdate(longestEntry.Length, inventory.Count);

View File

@ -1,6 +1,5 @@
using Content.Client.VendingMachines.UI;
using Content.Shared.VendingMachines;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface.Controls;
using System.Linq;
@ -14,6 +13,9 @@ namespace Content.Client.VendingMachines
[ViewVariables]
private List<VendingMachineInventoryEntry> _cachedInventory = new();
[ViewVariables]
private List<int> _cachedFilteredIndex = new();
public VendingMachineBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
}
@ -32,7 +34,7 @@ namespace Content.Client.VendingMachines
_menu.OnItemSelected += OnItemSelected;
_menu.OnSearchChanged += OnSearchChanged;
_menu.Populate(_cachedInventory);
_menu.Populate(_cachedInventory, out _cachedFilteredIndex);
_menu.OpenCentered();
}
@ -46,7 +48,7 @@ namespace Content.Client.VendingMachines
_cachedInventory = newState.Inventory;
_menu?.Populate(_cachedInventory);
_menu?.Populate(_cachedInventory, out _cachedFilteredIndex, _menu.SearchBar.Text);
}
private void OnItemSelected(ItemList.ItemListSelectedEventArgs args)
@ -54,7 +56,7 @@ namespace Content.Client.VendingMachines
if (_cachedInventory.Count == 0)
return;
var selectedItem = _cachedInventory.ElementAtOrDefault(args.ItemIndex);
var selectedItem = _cachedInventory.ElementAtOrDefault(_cachedFilteredIndex.ElementAtOrDefault(args.ItemIndex));
if (selectedItem == null)
return;
@ -78,7 +80,7 @@ namespace Content.Client.VendingMachines
private void OnSearchChanged(string? filter)
{
_menu?.Populate(_cachedInventory, filter);
_menu?.Populate(_cachedInventory, out _cachedFilteredIndex, filter);
}
}
}

View File

@ -16,7 +16,8 @@ using Robust.Client.State;
using Robust.Shared.Input;
using Robust.Shared.Map;
using Robust.Shared.Player;
using Robust.Shared.Players;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
namespace Content.Client.Weapons.Melee;

View File

@ -3,13 +3,11 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using Content.Server.GameTicking;
using Content.Server.Players;
using Content.Shared.Mind;
using Content.Shared.Players;
using Robust.Server.Player;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Network;
using Robust.Shared.Player;
using Robust.Shared.Timing;
using Robust.UnitTesting;
@ -30,8 +28,8 @@ public sealed partial class TestPair
public RobustIntegrationTest.ServerIntegrationInstance Server { get; private set; } = default!;
public RobustIntegrationTest.ClientIntegrationInstance Client { get; private set; } = default!;
public IPlayerSession? Player => (IPlayerSession?) Server.PlayerMan.Sessions.FirstOrDefault();
public PlayerData? PlayerData => Player?.Data.ContentData();
public ICommonSession? Player => Server.PlayerMan.Sessions.FirstOrDefault();
public ContentPlayerData? PlayerData => Player?.Data.ContentData();
public PoolTestLogHandler ServerLogHandler { get; private set; } = default!;
public PoolTestLogHandler ClientLogHandler { get; private set; } = default!;

View File

@ -3,8 +3,6 @@ using Content.Shared.Actions;
using Content.Shared.CombatMode;
using Robust.Server.Player;
using Robust.Shared.GameObjects;
using Robust.Shared.Players;
using PlayerManager = Robust.Client.Player.PlayerManager;
namespace Content.IntegrationTests.Tests.Actions;
@ -26,7 +24,7 @@ public sealed class ActionsAddedTest
var sEntMan = server.ResolveDependency<IEntityManager>();
var cEntMan = client.ResolveDependency<IEntityManager>();
var clientSession = client.ResolveDependency<Robust.Client.Player.IPlayerManager>().LocalPlayer?.Session;
var serverSession = server.ResolveDependency<IPlayerManager>().ServerSessions.Single();
var serverSession = server.ResolveDependency<IPlayerManager>().Sessions.Single();
var sActionSystem = server.System<SharedActionsSystem>();
var cActionSystem = client.System<SharedActionsSystem>();

View File

@ -7,8 +7,6 @@ using Content.Shared.Administration.Logs;
using Content.Shared.Database;
using Robust.Server.Player;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Utility;
namespace Content.IntegrationTests.Tests.Administration.Logs;
@ -177,7 +175,7 @@ public sealed class AddTests
await server.WaitPost(() =>
{
var player = sPlayers.ServerSessions.First();
var player = sPlayers.Sessions.First();
playerGuid = player.UserId;
Assert.DoesNotThrow(() =>
@ -280,7 +278,7 @@ public sealed class AddTests
await server.WaitPost(() =>
{
var player = sPlayers.ServerSessions.Single();
var player = sPlayers.Sessions.Single();
sAdminLogSystem.Add(LogType.Unknown, $"{player} {player} test log: {guid}");
});
@ -318,7 +316,7 @@ public sealed class AddTests
await server.WaitPost(() =>
{
var player = sPlayers.ServerSessions.Single();
var player = sPlayers.Sessions.Single();
sAdminLogSystem.Add(LogType.Unknown, $"{player:first} {player:second} test log: {guid}");
});

View File

@ -5,6 +5,7 @@ using Content.Server.GameTicking;
using Content.Shared.Database;
using Robust.Server.Player;
using Robust.Shared.GameObjects;
using Robust.Shared.Player;
namespace Content.IntegrationTests.Tests.Administration.Logs;
@ -27,11 +28,11 @@ public sealed class QueryTests
var date = DateTime.UtcNow;
var guid = Guid.NewGuid();
IPlayerSession player = default;
ICommonSession player = default;
await server.WaitPost(() =>
{
player = sPlayers.ServerSessions.First();
player = sPlayers.Sessions.First();
sAdminLogSystem.Add(LogType.Unknown, $"{player.AttachedEntity:Entity} test log: {guid}");
});

View File

@ -49,7 +49,7 @@ public sealed class CargoTest
await pair.CleanReturnAsync();
}
[Test]
public async Task NoCargoBountyArbitageTest()
public async Task NoCargoBountyArbitrageTest()
{
await using var pair = await PoolManager.GetServerClient();
var server = pair.Server;

View File

@ -25,7 +25,7 @@ public sealed class EuiManagerTest
await server.WaitAssertion(() =>
{
var clientSession = sPlayerManager.ServerSessions.Single();
var clientSession = sPlayerManager.Sessions.Single();
var ui = new AdminAnnounceEui();
eui.OpenEui(ui, clientSession);
});

View File

@ -14,6 +14,7 @@ using Content.Shared.Hands.Components;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Interaction;
using Content.Shared.Mind;
using Content.Shared.Players;
using Robust.Client.Input;
using Robust.Client.UserInterface;
using Robust.Server.GameObjects;
@ -21,7 +22,7 @@ using Robust.Server.Player;
using Robust.Shared.GameObjects;
using Robust.Shared.Log;
using Robust.Shared.Map;
using Robust.Shared.Players;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
using Robust.UnitTesting;
@ -67,7 +68,7 @@ public abstract partial class InteractionTest
protected NetEntity Player;
protected ICommonSession ClientSession = default!;
protected IPlayerSession ServerSession = default!;
protected ICommonSession ServerSession = default!;
public EntityUid? ClientTarget;

View File

@ -5,6 +5,7 @@ using Content.Server.Ghost.Roles.Components;
using Content.Server.Players;
using Content.Shared.Ghost;
using Content.Shared.Mind;
using Content.Shared.Players;
using Robust.Shared.Console;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
@ -43,7 +44,7 @@ public sealed class GhostRoleTests
var sPlayerMan = server.ResolveDependency<Robust.Server.Player.IPlayerManager>();
var conHost = client.ResolveDependency<IConsoleHost>();
var mindSystem = entMan.System<SharedMindSystem>();
var session = sPlayerMan.ServerSessions.Single();
var session = sPlayerMan.Sessions.Single();
var originalMindId = session.ContentData()!.Mind!.Value;
// Spawn player entity & attach

View File

@ -2,6 +2,7 @@ using System.Linq;
using Content.Server.Players;
using Content.Shared.Ghost;
using Content.Shared.Mind;
using Content.Shared.Players;
using Robust.Server.Console;
using Robust.Server.GameObjects;
using Robust.Server.Player;
@ -35,7 +36,7 @@ public sealed partial class MindTests
MindComponent mind = default!;
await server.WaitAssertion(() =>
{
var player = playerMan.ServerSessions.Single();
var player = playerMan.Sessions.Single();
playerEnt = entMan.SpawnEntity(null, MapCoordinates.Nullspace);
visitEnt = entMan.SpawnEntity(null, MapCoordinates.Nullspace);
@ -81,7 +82,7 @@ public sealed partial class MindTests
var entMan = server.ResolveDependency<IServerEntityManager>();
var mapManager = server.ResolveDependency<IMapManager>();
var playerMan = server.ResolveDependency<IPlayerManager>();
var player = playerMan.ServerSessions.Single();
var player = playerMan.Sessions.Single();
var mindSystem = entMan.EntitySysManager.GetEntitySystem<SharedMindSystem>();
@ -128,7 +129,7 @@ public sealed partial class MindTests
var entMan = server.ResolveDependency<IServerEntityManager>();
var playerMan = server.ResolveDependency<IPlayerManager>();
var player = playerMan.ServerSessions.Single();
var player = playerMan.Sessions.Single();
Assert.That(!entMan.HasComponent<GhostComponent>(player.AttachedEntity), "Player was initially a ghost?");
@ -162,7 +163,7 @@ public sealed partial class MindTests
var mindSystem = entMan.EntitySysManager.GetEntitySystem<SharedMindSystem>();
var mind = GetMind(pair);
var player = playerMan.ServerSessions.Single();
var player = playerMan.Sessions.Single();
#pragma warning disable NUnit2045 // Interdependent assertions.
Assert.That(player.AttachedEntity, Is.Not.Null);
Assert.That(entMan.EntityExists(player.AttachedEntity));
@ -218,7 +219,7 @@ public sealed partial class MindTests
var playerMan = server.ResolveDependency<IPlayerManager>();
var serverConsole = server.ResolveDependency<IServerConsoleHost>();
var player = playerMan.ServerSessions.Single();
var player = playerMan.Sessions.Single();
var ghost = await BecomeGhost(pair);
@ -263,7 +264,7 @@ public sealed partial class MindTests
var playerMan = server.ResolveDependency<IPlayerManager>();
var serverConsole = server.ResolveDependency<IServerConsoleHost>();
var player = playerMan.ServerSessions.Single();
var player = playerMan.Sessions.Single();
EntityUid ghost = default!;

View File

@ -1,14 +1,17 @@
using System.Linq;
using Content.IntegrationTests.Pair;
using Content.Server.Mind;
using Content.Server.Players;
using Content.Shared.Ghost;
using Content.Shared.Mind;
using Content.Shared.Players;
using Robust.Server.GameObjects;
using Robust.Server.Player;
using Robust.Shared.Enums;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Network;
using Robust.Shared.Player;
namespace Content.IntegrationTests.Tests.Minds;
@ -36,7 +39,7 @@ public sealed partial class MindTests
var playerMan = pair.Server.ResolveDependency<IPlayerManager>();
var mindSys = entMan.System<SharedMindSystem>();
var player = playerMan.ServerSessions.Single();
var player = playerMan.Sessions.Single();
EntityUid entity = default;
EntityUid mindId = default!;
@ -71,7 +74,7 @@ public sealed partial class MindTests
EntityUid mindId = default!;
MindComponent mind = default!;
var player = playerMan.ServerSessions.Single();
var player = playerMan.Sessions.Single();
await pair.Server.WaitAssertion(() =>
{
var oldUid = player.AttachedEntity;
@ -116,20 +119,25 @@ public sealed partial class MindTests
/// </summary>
private static (EntityUid Id, MindComponent Comp) GetMind(Pair.TestPair pair)
{
var playerMan = pair.Server.ResolveDependency<IPlayerManager>();
var entMan = pair.Server.ResolveDependency<IEntityManager>();
var player = playerMan.ServerSessions.SingleOrDefault();
var playerMan = pair.Server.PlayerMan;
var entMan = pair.Server.EntMan;
var player = playerMan.Sessions.SingleOrDefault();
Assert.That(player, Is.Not.Null);
var mindId = player.ContentData()!.Mind!.Value;
Assert.That(mindId, Is.Not.EqualTo(default(EntityUid)));
var mind = entMan.GetComponent<MindComponent>(mindId);
ActorComponent actor = default!;
Assert.Multiple(() =>
{
Assert.That(player, Is.EqualTo(mind.Session), "Player session does not match mind session");
Assert.That(entMan.System<MindSystem>().GetMind(player.UserId), Is.EqualTo(mindId));
Assert.That(player.AttachedEntity, Is.EqualTo(mind.CurrentEntity), "Player is not attached to the mind's current entity.");
Assert.That(entMan.EntityExists(mind.OwnedEntity), "The mind's current entity does not exist");
Assert.That(mind.VisitingEntity == null || entMan.EntityExists(mind.VisitingEntity), "The minds visited entity does not exist.");
Assert.That(entMan.TryGetComponent(mind.CurrentEntity, out actor));
});
Assert.That(actor.PlayerSession, Is.EqualTo(mind.Session));
return (mindId, mind);
}
@ -139,7 +147,7 @@ public sealed partial class MindTests
var netManager = pair.Client.ResolveDependency<IClientNetManager>();
var playerMan = pair.Server.ResolveDependency<IPlayerManager>();
var entMan = pair.Server.ResolveDependency<IEntityManager>();
var player = playerMan.ServerSessions.Single();
var player = playerMan.Sessions.Single();
var mindId = player.ContentData()!.Mind!.Value;
var mind = entMan.GetComponent<MindComponent>(mindId);
@ -161,21 +169,21 @@ public sealed partial class MindTests
{
var netManager = pair.Client.ResolveDependency<IClientNetManager>();
var playerMan = pair.Server.ResolveDependency<IPlayerManager>();
Assert.That(!playerMan.ServerSessions.Any());
Assert.That(!playerMan.Sessions.Any());
await Task.WhenAll(pair.Client.WaitIdleAsync(), pair.Client.WaitIdleAsync());
pair.Client.SetConnectTarget(pair.Server);
await pair.Client.WaitPost(() => netManager.ClientConnect(null!, 0, username));
await pair.RunTicksSync(5);
var player = playerMan.ServerSessions.Single();
var player = playerMan.Sessions.Single();
Assert.That(player.Status, Is.EqualTo(SessionStatus.InGame));
}
private static async Task<IPlayerSession> DisconnectReconnect(Pair.TestPair pair)
private static async Task<ICommonSession> DisconnectReconnect(Pair.TestPair pair)
{
var playerMan = pair.Server.ResolveDependency<IPlayerManager>();
var player = playerMan.ServerSessions.Single();
var player = playerMan.Sessions.Single();
var name = player.Name;
var id = player.UserId;
@ -183,7 +191,7 @@ public sealed partial class MindTests
await Connect(pair, name);
// Session has changed
var newSession = playerMan.ServerSessions.Single();
var newSession = playerMan.Sessions.Single();
Assert.Multiple(() =>
{
Assert.That(newSession, Is.Not.EqualTo(player));

View File

@ -1,6 +1,8 @@
using System.Linq;
using Content.Shared.Ghost;
using Content.Shared.Mind;
using NUnit.Framework.Interfaces;
using Robust.Server.GameObjects;
using Robust.Server.Player;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
@ -49,7 +51,7 @@ public sealed partial class MindTests
var mind = GetMind(pair);
var playerMan = pair.Server.ResolveDependency<IPlayerManager>();
var player = playerMan.ServerSessions.Single();
var player = playerMan.Sessions.Single();
var name = player.Name;
var user = player.UserId;
Assert.That(mind.Comp.OwnedEntity, Is.Not.Null);
@ -72,7 +74,7 @@ public sealed partial class MindTests
// Reconnect
await Connect(pair, name);
player = playerMan.ServerSessions.Single();
player = playerMan.Sessions.Single();
Assert.Multiple(() =>
{
Assert.That(user, Is.EqualTo(player.UserId));
@ -127,8 +129,10 @@ public sealed partial class MindTests
var mindSys = entMan.System<SharedMindSystem>();
var mind = GetMind(pair);
Assert.Null(mind.Comp.VisitingEntity);
// Make player visit a new mob
var original = mind.Comp.CurrentEntity;
var original = mind.Comp.OwnedEntity;
EntityUid visiting = default;
await pair.Server.WaitAssertion(() =>
{
@ -137,6 +141,7 @@ public sealed partial class MindTests
});
await pair.RunTicksSync(5);
Assert.That(mind.Comp.VisitingEntity, Is.EqualTo(visiting));
await DisconnectReconnect(pair);
// Player is back in control of the visited mob, mind was preserved
@ -150,4 +155,32 @@ public sealed partial class MindTests
await pair.CleanReturnAsync();
}
// This test will do the following
// - connect as a normal player
// - disconnect
// - reconnect
// - assert that they return to the original entity.
[Test]
public async Task TestReconnect()
{
await using var pair = await SetupPair();
var mind = GetMind(pair);
Assert.Null(mind.Comp.VisitingEntity);
Assert.NotNull(mind.Comp.OwnedEntity);
var entity = mind.Comp.OwnedEntity;
await pair.RunTicksSync(5);
await DisconnectReconnect(pair);
await pair.RunTicksSync(5);
var newMind = GetMind(pair);
Assert.Null(newMind.Comp.VisitingEntity);
Assert.That(newMind.Comp.OwnedEntity, Is.EqualTo(entity));
Assert.That(newMind.Id, Is.EqualTo(mind.Id));
await pair.CleanReturnAsync();
}
}

View File

@ -11,6 +11,7 @@ using Content.Shared.Damage.Prototypes;
using Content.Shared.FixedPoint;
using Content.Shared.Mind;
using Content.Shared.Mind.Components;
using Content.Shared.Players;
using Content.Shared.Roles;
using Content.Shared.Roles.Jobs;
using Robust.Server.Console;
@ -345,7 +346,7 @@ public sealed partial class MindTests
EntityUid entity = default!;
EntityUid mindId = default!;
MindComponent mind = default!;
var player = playerMan.ServerSessions.Single();
var player = playerMan.Sessions.Single();
await server.WaitAssertion(() =>
{
@ -406,12 +407,6 @@ public sealed partial class MindTests
await pair.CleanReturnAsync();
}
// TODO Implement
/*[Test]
public async Task TestPlayerCanReturnFromGhostWhenDead()
{
}*/
[Test]
public async Task TestGhostDoesNotInfiniteLoop()
{
@ -432,7 +427,7 @@ public sealed partial class MindTests
EntityUid ghost = default!;
EntityUid mindId = default!;
MindComponent mind = default!;
var player = playerMan.ServerSessions.Single();
var player = playerMan.Sessions.Single();
await server.WaitAssertion(() =>
{

View File

@ -2,8 +2,7 @@
using System.Collections.Generic;
using Content.IntegrationTests.Pair;
using Content.Server.Administration.Managers;
using Robust.Server.Player;
using Robust.Shared.Players;
using Robust.Shared.Player;
using Robust.Shared.Toolshed;
using Robust.Shared.Toolshed.Errors;
using Robust.Shared.Toolshed.Syntax;
@ -60,7 +59,7 @@ public abstract class ToolshedTest : IInvocationContext
AdminManager = Server.ResolveDependency<IAdminManager>();
}
protected bool InvokeCommand(string command, out object? result, IPlayerSession? session = null)
protected bool InvokeCommand(string command, out object? result, ICommonSession? session = null)
{
return Toolshed.InvokeCommand(this, command, null, out result);
}
@ -95,7 +94,7 @@ public abstract class ToolshedTest : IInvocationContext
return true;
}
protected IPlayerSession? InvocationSession { get; set; }
protected ICommonSession? InvocationSession { get; set; }
public ICommonSession? Session
{

View File

@ -68,7 +68,7 @@ namespace Content.MapRenderer.Painters
await server.WaitPost(() =>
{
var playerEntity = sPlayerManager.ServerSessions.Single().AttachedEntity;
var playerEntity = sPlayerManager.Sessions.Single().AttachedEntity;
if (playerEntity.HasValue)
{

View File

@ -80,7 +80,7 @@ foreach (var record in reader.GetRecords<Row>())
var tier = tiers[0];
var tierName = content.Included.SingleOrDefault(i => i.Id == tier.Id && i.Type == tier.Type)?.Attributes.Title;
if (tierName == null)
if (tierName == null || tierName == "Free")
continue;
if (record.Trigger == "members:delete")

View File

@ -9,6 +9,7 @@ using Content.Shared.Interaction;
using JetBrains.Annotations;
using Robust.Server.GameObjects;
using Robust.Shared.Containers;
using Robust.Shared.Player;
using static Content.Shared.Access.Components.AccessOverriderComponent;
namespace Content.Server.Access.Systems;

View File

@ -1,5 +1,5 @@
using Content.Shared.Administration;
using Robust.Server.Player;
using Robust.Shared.Player;
namespace Content.Server.Administration
{
@ -8,7 +8,7 @@ namespace Content.Server.Administration
/// </summary>
public sealed class AdminPermsChangedEventArgs : EventArgs
{
public AdminPermsChangedEventArgs(IPlayerSession player, AdminFlags? flags)
public AdminPermsChangedEventArgs(ICommonSession player, AdminFlags? flags)
{
Player = player;
Flags = flags;
@ -17,7 +17,7 @@ namespace Content.Server.Administration
/// <summary>
/// The player that had their admin permissions changed.
/// </summary>
public IPlayerSession Player { get; }
public ICommonSession Player { get; }
/// <summary>
/// The admin flags of the player. Null if the player is no longer an admin.

View File

@ -2,7 +2,6 @@
using Content.Shared.Administration;
using Content.Shared.Ghost;
using Content.Shared.Mind;
using Robust.Server.Player;
using Robust.Shared.Console;
namespace Content.Server.Administration.Commands
@ -18,7 +17,7 @@ namespace Content.Server.Administration.Commands
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var player = shell.Player as IPlayerSession;
var player = shell.Player;
if (player == null)
{
shell.WriteLine("Nah");

View File

@ -2,7 +2,6 @@
using Content.Server.Administration.Managers;
using Content.Server.Afk;
using Content.Shared.Administration;
using Robust.Server.Player;
using Robust.Shared.Console;
using Robust.Shared.Utility;
@ -35,7 +34,7 @@ public sealed class AdminWhoCommand : IConsoleCommand
if (adminData.Title is { } title)
sb.Append($": [{title}]");
if (shell.Player is IPlayerSession player && adminMgr.HasAdminFlag(player, AdminFlags.Admin))
if (shell.Player is { } player && adminMgr.HasAdminFlag(player, AdminFlags.Admin))
{
if (afk.IsAfk(admin))
sb.Append(" [AFK]");

View File

@ -1,7 +1,6 @@
using Content.Server.Administration.UI;
using Content.Server.EUI;
using Content.Shared.Administration;
using Robust.Server.Player;
using Robust.Shared.Console;
namespace Content.Server.Administration.Commands
@ -17,7 +16,7 @@ namespace Content.Server.Administration.Commands
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var player = shell.Player as IPlayerSession;
var player = shell.Player;
if (player == null)
{
shell.WriteLine("This does not work from the server console.");

View File

@ -1,15 +1,8 @@
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using Content.Server.Administration.Managers;
using Content.Server.Administration.Notes;
using Content.Server.Database;
using Content.Server.GameTicking;
using Content.Shared.Administration;
using Content.Shared.CCVar;
using Content.Shared.Database;
using Content.Shared.Players.PlayTimeTracking;
using Robust.Server.Player;
using Robust.Shared.Configuration;
using Robust.Shared.Console;
@ -84,7 +77,7 @@ public sealed class BanCommand : LocalizedCommands
}
var located = await _locator.LookupIdByNameOrIdAsync(target);
var player = shell.Player as IPlayerSession;
var player = shell.Player;
if (located == null)
{
@ -102,7 +95,7 @@ public sealed class BanCommand : LocalizedCommands
{
if (args.Length == 1)
{
var options = _playerManager.ServerSessions.Select(c => c.Name).OrderBy(c => c).ToArray();
var options = _playerManager.Sessions.Select(c => c.Name).OrderBy(c => c).ToArray();
return CompletionResult.FromHintOptions(options, LocalizationManager.GetString("cmd-ban-hint"));
}

View File

@ -36,7 +36,7 @@ public sealed class BanListCommand : LocalizedCommands
return;
}
if (shell.Player is not IPlayerSession player)
if (shell.Player is not { } player)
{
var bans = await _dbManager.GetServerBansAsync(data.LastAddress, data.UserId, data.LastHWId, false);
@ -67,7 +67,7 @@ public sealed class BanListCommand : LocalizedCommands
return CompletionResult.Empty;
var playerMgr = IoCManager.Resolve<IPlayerManager>();
var options = playerMgr.ServerSessions.Select(c => c.Name).OrderBy(c => c).ToArray();
var options = playerMgr.Sessions.Select(c => c.Name).OrderBy(c => c).ToArray();
return CompletionResult.FromHintOptions(options, Loc.GetString("cmd-banlist-hint"));
}
}

View File

@ -1,12 +1,6 @@
using Content.Shared.Administration;
using Robust.Shared.Console;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Content.Server.EUI;
using Robust.Server.Player;
namespace Content.Server.Administration.Commands;
@ -21,7 +15,7 @@ public sealed class BanPanelCommand : LocalizedCommands
public override async void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (shell.Player is not IPlayerSession player)
if (shell.Player is not { } player)
{
shell.WriteError(Loc.GetString("cmd-banpanel-server"));
return;

View File

@ -1,6 +1,5 @@
using Content.Server.Mind;
using Content.Shared.Administration;
using Robust.Server.Player;
using Robust.Shared.Console;
namespace Content.Server.Administration.Commands
@ -16,7 +15,7 @@ namespace Content.Server.Administration.Commands
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (shell.Player is not IPlayerSession player)
if (shell.Player is not { } player)
{
shell.WriteLine("shell-server-cannot");
return;

View File

@ -1,7 +1,5 @@
using Content.Server.Chat;
using Content.Server.Chat.Systems;
using Content.Shared.Administration;
using Robust.Server.Player;
using Robust.Shared.Console;
namespace Content.Server.Administration.Commands
@ -17,7 +15,7 @@ namespace Content.Server.Administration.Commands
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var player = shell.Player as IPlayerSession;
var player = shell.Player;
if (player == null)
{
shell.WriteLine("shell-only-players-can-run-this-command");

View File

@ -1,10 +1,8 @@
using Content.Server.Administration.Managers;
using Content.Shared.Administration;
using JetBrains.Annotations;
using Robust.Server.Player;
using Robust.Shared.Console;
namespace Content.Server.Administration.Commands
{
[UsedImplicitly]
@ -17,7 +15,7 @@ namespace Content.Server.Administration.Commands
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var player = shell.Player as IPlayerSession;
var player = shell.Player;
if (player == null)
{
shell.WriteLine("You cannot use this command from the server console.");

View File

@ -3,7 +3,6 @@ using Content.Server.EUI;
using Content.Server.Explosion.EntitySystems;
using Content.Shared.Administration;
using Content.Shared.Explosion;
using Robust.Server.Player;
using Robust.Shared.Console;
using Robust.Shared.Map;
using Robust.Shared.Prototypes;
@ -21,7 +20,7 @@ public sealed class OpenExplosionEui : IConsoleCommand
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var player = shell.Player as IPlayerSession;
var player = shell.Player;
if (player == null)
{
shell.WriteError("This does not work from the server console.");

View File

@ -1,7 +1,6 @@
using Content.Server.EUI;
using Content.Server.Fax.AdminUI;
using Content.Shared.Administration;
using Robust.Server.Player;
using Robust.Shared.Console;
namespace Content.Server.Administration.Commands;
@ -16,7 +15,7 @@ public sealed class FaxUiCommand : IConsoleCommand
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var player = shell.Player as IPlayerSession;
var player = shell.Player;
if (player == null)
{
shell.WriteLine("shell-only-players-can-run-this-command");

View File

@ -1,7 +1,6 @@
using Content.Server.Administration.Logs;
using Content.Server.EUI;
using Content.Shared.Administration;
using Robust.Server.Player;
using Robust.Shared.Console;
namespace Content.Server.Administration.Commands;
@ -15,7 +14,7 @@ public sealed class OpenAdminLogsCommand : IConsoleCommand
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (shell.Player is not IPlayerSession player)
if (shell.Player is not { } player)
{
shell.WriteLine("This does not work from the server console.");
return;

View File

@ -1,7 +1,5 @@
using Content.Server.Administration.Notes;
using Content.Server.Database;
using Content.Shared.Administration;
using Robust.Server.Player;
using Robust.Shared.Console;
namespace Content.Server.Administration.Commands;
@ -17,7 +15,7 @@ public sealed class OpenAdminNotesCommand : IConsoleCommand
public async void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (shell.Player is not IPlayerSession player)
if (shell.Player is not { } player)
{
shell.WriteError("This does not work from the server console.");
return;

View File

@ -1,10 +1,8 @@
using Content.Server.Administration.UI;
using Content.Server.EUI;
using Content.Shared.Administration;
using Robust.Server.Player;
using Robust.Shared.Console;
namespace Content.Server.Administration.Commands
{
[AdminCommand(AdminFlags.Permissions)]
@ -16,7 +14,7 @@ namespace Content.Server.Administration.Commands
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var player = shell.Player as IPlayerSession;
var player = shell.Player;
if (player == null)
{
shell.WriteLine("This does not work from the server console.");

View File

@ -1,7 +1,6 @@
using Content.Server.Administration.Notes;
using Content.Shared.Administration;
using Content.Shared.CCVar;
using Robust.Server.Player;
using Robust.Shared.Configuration;
using Robust.Shared.Console;
@ -27,7 +26,7 @@ public sealed class OpenUserVisibleNotesCommand : IConsoleCommand
return;
}
if (shell.Player is not IPlayerSession player)
if (shell.Player is not { } player)
{
shell.WriteError("This does not work from the server console.");
return;

View File

@ -1,7 +1,6 @@
using System.Text;
using Content.Server.Database;
using Content.Shared.Administration;
using Robust.Server.Player;
using Robust.Shared.Console;
namespace Content.Server.Administration.Commands
@ -15,7 +14,7 @@ namespace Content.Server.Administration.Commands
public async void Execute(IConsoleShell shell, string argStr, string[] args)
{
var player = shell.Player as IPlayerSession;
var player = shell.Player;
var dbMan = IoCManager.Resolve<IServerDbManager>();
if (args.Length != 1)

View File

@ -6,7 +6,6 @@ using Robust.Shared.Audio;
using Robust.Shared.Console;
using Robust.Shared.ContentPack;
using Robust.Shared.Player;
using Robust.Shared.Players;
using Robust.Shared.Prototypes;
namespace Content.Server.Administration.Commands;

View File

@ -1,9 +1,7 @@
using Content.Server.Administration.Managers;
using Content.Shared.Administration;
using Robust.Server.Player;
using Robust.Shared.Console;
namespace Content.Server.Administration.Commands
{
[AnyCommand]
@ -15,7 +13,7 @@ namespace Content.Server.Administration.Commands
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var player = shell.Player as IPlayerSession;
var player = shell.Player;
if (player == null)
{
shell.WriteLine("You cannot use this command from the server console.");

View File

@ -1,8 +1,6 @@
using Content.Server.Database;
using Content.Server.Preferences.Managers;
using Content.Shared.Administration;
using Robust.Server.Player;
using Robust.Shared.Console;
namespace Content.Server.Administration.Commands
@ -16,7 +14,7 @@ namespace Content.Server.Administration.Commands
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (!(shell.Player is IPlayerSession))
if (shell.Player == null)
{
shell.WriteError(Loc.GetString("shell-only-players-can-run-this-command"));
return;

View File

@ -2,6 +2,7 @@ using Content.Server.Players;
using Content.Shared.Administration;
using Content.Shared.Mind;
using Content.Shared.Mind.Components;
using Content.Shared.Players;
using Robust.Server.Player;
using Robust.Shared.Console;

View File

@ -9,9 +9,8 @@ using Content.Shared.Inventory;
using Content.Shared.PDA;
using Content.Shared.Preferences;
using Content.Shared.Roles;
using Robust.Server.GameObjects;
using Robust.Server.Player;
using Robust.Shared.Console;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
namespace Content.Server.Administration.Commands
@ -57,7 +56,7 @@ namespace Content.Server.Administration.Commands
if (args.Length == 1)
{
if (shell.Player is not IPlayerSession player)
if (shell.Player is not { } player)
{
shell.WriteError(Loc.GetString("set-outfit-command-is-not-player-error"));
return;

View File

@ -4,11 +4,9 @@ using Content.Server.Warps;
using Content.Shared.Administration;
using Content.Shared.Follower;
using Content.Shared.Ghost;
using Robust.Server.Player;
using Robust.Shared.Console;
using Robust.Shared.Enums;
using Robust.Shared.Map;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Systems;
@ -28,7 +26,7 @@ namespace Content.Server.Administration.Commands
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var player = shell.Player as IPlayerSession;
var player = shell.Player;
if (player == null)
{
shell.WriteLine("Only players can use this command");

View File

@ -1,8 +1,8 @@
using Content.Server.Database;
using Content.Shared.CCVar;
using Robust.Server.Player;
using Robust.Server.Upload;
using Robust.Shared.Configuration;
using Robust.Shared.Player;
using Robust.Shared.Upload;
namespace Content.Server.Administration;
@ -22,7 +22,7 @@ public sealed class ContentNetworkResourceManager
_netRes.OnResourceUploaded += OnUploadResource;
}
private async void OnUploadResource(IPlayerSession session, NetworkResourceUploadMessage msg)
private async void OnUploadResource(ICommonSession session, NetworkResourceUploadMessage msg)
{
if (StoreUploaded)
await _serverDb.AddUploadedResourceLogAsync(session.UserId, DateTime.Now, msg.RelativePath.ToString(), msg.Data);

View File

@ -3,8 +3,8 @@ using System.Text.Json;
using System.Text.Json.Serialization;
using Content.Server.Administration.Logs.Converters;
using Robust.Server.GameObjects;
using Robust.Server.Player;
using Robust.Shared.Map;
using Robust.Shared.Player;
namespace Content.Server.Administration.Logs;
@ -44,7 +44,7 @@ public sealed partial class AdminLogManager
var value = properties[key];
value = value switch
{
IPlayerSession player => new SerializablePlayer(player),
ICommonSession player => new SerializablePlayer(player),
EntityCoordinates entityCoordinates => new SerializableEntityCoordinates(_entityManager, entityCoordinates),
_ => value
};
@ -56,7 +56,7 @@ public sealed partial class AdminLogManager
{
EntityUid id => id,
EntityStringRepresentation rep => rep.Uid,
IPlayerSession {AttachedEntity: {Valid: true}} session => session.AttachedEntity,
ICommonSession {AttachedEntity: {Valid: true}} session => session.AttachedEntity,
IComponent component => component.Owner,
_ => null
};

View File

@ -1,5 +1,5 @@
using System.Text.Json;
using Robust.Server.GameObjects;
using Robust.Shared.Player;
namespace Content.Server.Administration.Logs.Converters;

View File

@ -1,5 +1,5 @@
using System.Text.Json;
using Robust.Server.Player;
using Robust.Shared.Player;
namespace Content.Server.Administration.Logs.Converters;
@ -36,9 +36,9 @@ public sealed class PlayerSessionConverter : AdminLogConverter<SerializablePlaye
public readonly struct SerializablePlayer
{
public readonly IPlayerSession Player;
public readonly ICommonSession Player;
public SerializablePlayer(IPlayerSession player)
public SerializablePlayer(ICommonSession player)
{
Player = player;
}

View File

@ -7,15 +7,15 @@ using Content.Server.Database;
using Content.Server.Players;
using Content.Shared.Administration;
using Content.Shared.CCVar;
using Content.Shared.Players;
using Robust.Server.Console;
using Robust.Server.Player;
using Robust.Shared.Configuration;
using Robust.Shared.Console;
using Robust.Shared.ContentPack;
using Robust.Shared.Enums;
using Robust.Shared.Map;
using Robust.Shared.Network;
using Robust.Shared.Players;
using Robust.Shared.Player;
using Robust.Shared.Toolshed;
using Robust.Shared.Toolshed.Errors;
using Robust.Shared.Utility;
@ -35,16 +35,16 @@ namespace Content.Server.Administration.Managers
[Dependency] private readonly IChatManager _chat = default!;
[Dependency] private readonly ToolshedManager _toolshed = default!;
private readonly Dictionary<IPlayerSession, AdminReg> _admins = new();
private readonly Dictionary<ICommonSession, AdminReg> _admins = new();
private readonly HashSet<NetUserId> _promotedPlayers = new();
public event Action<AdminPermsChangedEventArgs>? OnPermsChanged;
public IEnumerable<IPlayerSession> ActiveAdmins => _admins
public IEnumerable<ICommonSession> ActiveAdmins => _admins
.Where(p => p.Value.Data.Active)
.Select(p => p.Key);
public IEnumerable<IPlayerSession> AllAdmins => _admins.Select(p => p.Key);
public IEnumerable<ICommonSession> AllAdmins => _admins.Select(p => p.Key);
private readonly AdminCommandPermissions _commandPermissions = new();
private readonly AdminCommandPermissions _toolshedCommandPermissions = new();
@ -56,7 +56,7 @@ namespace Content.Server.Administration.Managers
public AdminData? GetAdminData(ICommonSession session, bool includeDeAdmin = false)
{
if (_admins.TryGetValue((IPlayerSession)session, out var reg) && (reg.Data.Active || includeDeAdmin))
if (_admins.TryGetValue(session, out var reg) && (reg.Data.Active || includeDeAdmin))
{
return reg.Data;
}
@ -66,13 +66,13 @@ namespace Content.Server.Administration.Managers
public AdminData? GetAdminData(EntityUid uid, bool includeDeAdmin = false)
{
if (_playerManager.TryGetSessionByEntity(uid, out var session) && session is IPlayerSession playerSession)
return GetAdminData(playerSession, includeDeAdmin);
if (_playerManager.TryGetSessionByEntity(uid, out var session))
return GetAdminData(session, includeDeAdmin);
return null;
}
public void DeAdmin(IPlayerSession session)
public void DeAdmin(ICommonSession session)
{
if (!_admins.TryGetValue(session, out var reg))
{
@ -95,7 +95,7 @@ namespace Content.Server.Administration.Managers
UpdateAdminStatus(session);
}
public void ReAdmin(IPlayerSession session)
public void ReAdmin(ICommonSession session)
{
if (!_admins.TryGetValue(session, out var reg))
{
@ -119,7 +119,7 @@ namespace Content.Server.Administration.Managers
UpdateAdminStatus(session);
}
public async void ReloadAdmin(IPlayerSession player)
public async void ReloadAdmin(ICommonSession player)
{
var data = await LoadAdminData(player);
var curAdmin = _admins.GetValueOrDefault(player);
@ -236,7 +236,7 @@ namespace Content.Server.Administration.Managers
_toolshed.ActivePermissionController = this;
}
public void PromoteHost(IPlayerSession player)
public void PromoteHost(ICommonSession player)
{
_promotedPlayers.Add(player.UserId);
@ -250,7 +250,7 @@ namespace Content.Server.Administration.Managers
}
// NOTE: Also sends commands list for non admins..
private void UpdateAdminStatus(IPlayerSession session)
private void UpdateAdminStatus(ICommonSession session)
{
var msg = new MsgUpdateAdminStatus();
@ -290,7 +290,7 @@ namespace Content.Server.Administration.Managers
}
}
private async void LoginAdminMaybe(IPlayerSession session)
private async void LoginAdminMaybe(ICommonSession session)
{
var adminDat = await LoadAdminData(session);
if (adminDat == null)
@ -323,7 +323,7 @@ namespace Content.Server.Administration.Managers
UpdateAdminStatus(session);
}
private async Task<(AdminData dat, int? rankId, bool specialLogin)?> LoadAdminData(IPlayerSession session)
private async Task<(AdminData dat, int? rankId, bool specialLogin)?> LoadAdminData(ICommonSession session)
{
var promoteHost = IsLocal(session) && _cfg.GetCVar(CCVars.ConsoleLoginLocal)
|| _promotedPlayers.Contains(session.UserId)
@ -387,7 +387,7 @@ namespace Content.Server.Administration.Managers
}
}
private static bool IsLocal(IPlayerSession player)
private static bool IsLocal(ICommonSession player)
{
var ep = player.ConnectedClient.RemoteEndPoint;
var addr = ep.Address;
@ -419,7 +419,7 @@ namespace Content.Server.Administration.Managers
return false;
}
public bool CanCommand(IPlayerSession session, string cmdName)
public bool CanCommand(ICommonSession session, string cmdName)
{
if (_commandPermissions.AnyCommands.Contains(cmdName))
{
@ -474,7 +474,7 @@ namespace Content.Server.Administration.Managers
return true;
}
var data = GetAdminData((IPlayerSession)user);
var data = GetAdminData(user);
if (data == null)
{
// Player isn't an admin.
@ -520,32 +520,32 @@ namespace Content.Server.Administration.Managers
return (attribs.Length != 0, attribs);
}
public bool CanViewVar(IPlayerSession session)
public bool CanViewVar(ICommonSession session)
{
return CanCommand(session, "vv");
}
public bool CanAdminPlace(IPlayerSession session)
public bool CanAdminPlace(ICommonSession session)
{
return GetAdminData(session)?.CanAdminPlace() ?? false;
}
public bool CanScript(IPlayerSession session)
public bool CanScript(ICommonSession session)
{
return GetAdminData(session)?.CanScript() ?? false;
}
public bool CanAdminMenu(IPlayerSession session)
public bool CanAdminMenu(ICommonSession session)
{
return GetAdminData(session)?.CanAdminMenu() ?? false;
}
public bool CanAdminReloadPrototypes(IPlayerSession session)
public bool CanAdminReloadPrototypes(ICommonSession session)
{
return GetAdminData(session)?.CanAdminReloadPrototypes() ?? false;
}
private void SendPermsChangedEvent(IPlayerSession session)
private void SendPermsChangedEvent(ICommonSession session)
{
var flags = GetAdminData(session)?.Flags;
OnPermsChanged?.Invoke(new AdminPermsChangedEventArgs(session, flags));
@ -553,7 +553,7 @@ namespace Content.Server.Administration.Managers
private sealed class AdminReg
{
public readonly IPlayerSession Session;
public readonly ICommonSession Session;
public AdminData Data;
public int? RankId;
@ -561,7 +561,7 @@ namespace Content.Server.Administration.Managers
// Such as console.loginlocal or promotehost
public bool IsSpecialLogin;
public AdminReg(IPlayerSession session, AdminData data)
public AdminReg(ICommonSession session, AdminData data)
{
Data = data;
Session = session;

Some files were not shown because too many files have changed in this diff Show More