mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-15 03:30:53 +01:00
Compare commits
90 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1904207358 | ||
|
|
939840ddab | ||
|
|
a6c295b89c | ||
|
|
165913a4de | ||
|
|
675dfdaabd | ||
|
|
fab172d6f6 | ||
|
|
e75c1659f6 | ||
|
|
0c440a8fc9 | ||
|
|
0c2c8f352a | ||
|
|
0a4a2b7a36 | ||
|
|
b5b59c1d2f | ||
|
|
f4f0967fdc | ||
|
|
3d69766112 | ||
|
|
d1eb3438d5 | ||
|
|
8f6b189d29 | ||
|
|
ef8b278b47 | ||
|
|
c53ce2c907 | ||
|
|
f063aa3ea1 | ||
|
|
30f63254ef | ||
|
|
30a5b6152c | ||
|
|
910a7f8bff | ||
|
|
526a88293e | ||
|
|
22cd840b83 | ||
|
|
415c518bc7 | ||
|
|
2417dbb0e0 | ||
|
|
005673a957 | ||
|
|
942db3120c | ||
|
|
c0a5fab19e | ||
|
|
d16c62b132 | ||
|
|
7da22557fe | ||
|
|
92f47c0f20 | ||
|
|
9576d0739f | ||
|
|
10f25faabf | ||
|
|
74831a177e | ||
|
|
88d3168913 | ||
|
|
902519093c | ||
|
|
366266a8ae | ||
|
|
a22cce7783 | ||
|
|
e5e738b8cd | ||
|
|
b8f6e83473 | ||
|
|
c5fb186c57 | ||
|
|
131d7f5422 | ||
|
|
217996f1ed | ||
|
|
fc718d68a5 | ||
|
|
d7d9578803 | ||
|
|
9bbeb54569 | ||
|
|
1ea7071ffb | ||
|
|
196028b619 | ||
|
|
c102da052f | ||
|
|
5d46cdcfa4 | ||
|
|
cd646d3b07 | ||
|
|
922165fa19 | ||
|
|
4879252e99 | ||
|
|
0e21f5727a | ||
|
|
3ce8a00389 | ||
|
|
9a283fe541 | ||
|
|
f3e3e64db3 | ||
|
|
4a4a135089 | ||
|
|
e323a67806 | ||
|
|
3a328ffdd5 | ||
|
|
bc5107e297 | ||
|
|
2abf33c9be | ||
|
|
71c46828c2 | ||
|
|
814d6fe2d0 | ||
|
|
77b98b8308 | ||
|
|
34b0a7fc6d | ||
|
|
1b6123c79f | ||
|
|
1476f9d462 | ||
|
|
d62efe7301 | ||
|
|
6af0c88f27 | ||
|
|
5f05b0aa2a | ||
|
|
e6c335b6cd | ||
|
|
5cd8e8276e | ||
|
|
22aeec45f9 | ||
|
|
aed53fb63d | ||
|
|
5ebe97aec1 | ||
|
|
3ff374a4af | ||
|
|
c5bcf853ac | ||
|
|
0624ac36cd | ||
|
|
dd906e9b01 | ||
|
|
7f99b44e5c | ||
|
|
268eb862ea | ||
|
|
467f518421 | ||
|
|
4666a87aa5 | ||
|
|
25007a743f | ||
|
|
8ce3a03136 | ||
|
|
c4d6690a71 | ||
|
|
5486bc7686 | ||
|
|
cdf44ef3d9 | ||
|
|
49ec5b9ca3 |
16
.github/CODEOWNERS
vendored
16
.github/CODEOWNERS
vendored
@@ -1,21 +1,7 @@
|
||||
# Last match in file takes precedence.
|
||||
|
||||
# Ping for all PRs
|
||||
* @Acruid @PJB3005 @ZoldorfTheWizard
|
||||
|
||||
/Robust.Client.NameGenerator @PaulRitter
|
||||
/Robust.Client.Injectors @PaulRitter
|
||||
/Robust.Generators @PaulRitter
|
||||
/Robust.Analyzers @PaulRitter
|
||||
/Robust.*/GameStates @PaulRitter
|
||||
/Robust.Shared/Analyzers @PaulRitter
|
||||
/Robust.*/Serialization @PaulRitter @DrSmugleaf
|
||||
/Robust.*/Prototypes @PaulRitter
|
||||
/Robust.Shared/GameObjects/ComponentDependencies @PaulRitter
|
||||
/Robust.*/Containers @PaulRitter
|
||||
|
||||
# Be they Fluent translations or Freemarker templates, I know them both!
|
||||
*.ftl @RemieRichards
|
||||
* @PJB3005 @DrSmugleaf
|
||||
|
||||
# commands commands commands commands
|
||||
**/Toolshed/** @moonheart08
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<Project>
|
||||
|
||||
<!-- This file automatically reset by Tools/version.py -->
|
||||
<!-- This file automatically reset by Tools/version.py -->
|
||||
|
||||
|
||||
183
RELEASE-NOTES.md
183
RELEASE-NOTES.md
@@ -54,6 +54,189 @@ END TEMPLATE-->
|
||||
*None yet*
|
||||
|
||||
|
||||
## 162.2.2
|
||||
|
||||
|
||||
## 162.2.1
|
||||
|
||||
|
||||
## 162.2.0
|
||||
|
||||
### New features
|
||||
|
||||
* Add support for automatically networking entity lists and sets.
|
||||
* Add nullable conversion operators for ProtoIds.
|
||||
* Add LocId serializer for validation.
|
||||
|
||||
### Bugfixes
|
||||
|
||||
* Fix deleting a contact inside of collision events throwing.
|
||||
* Localize VV.
|
||||
|
||||
### Internal
|
||||
|
||||
* Use CollectionsMarshal in GameStateManager.
|
||||
|
||||
|
||||
## 162.1.1
|
||||
|
||||
### Bugfixes
|
||||
|
||||
* Fixes "NoSpawn" entities appearing in the spawn menu.
|
||||
|
||||
|
||||
## 162.1.0
|
||||
|
||||
### New features
|
||||
|
||||
* Mark ProtoId as NetSerializable.
|
||||
|
||||
### Bugfixes
|
||||
|
||||
* Temporarily revert NetForceAckThreshold change as it can lead to client stalling.
|
||||
* Fix eye visibility layers not updating on children when a parent changes.
|
||||
|
||||
### Internal
|
||||
|
||||
* Use CollectionsMarshal in RobustTree and AddComponentInternal.
|
||||
|
||||
|
||||
## 162.0.0
|
||||
|
||||
### New features
|
||||
|
||||
* Add entity categories for prototypes and deprecate the `noSpawn` tag.
|
||||
* Add missing proxy method for `TryGetEntityData`.
|
||||
* Add NetForceAckThreshold cvar to forcibly update acks for late clients.
|
||||
|
||||
### Internal
|
||||
|
||||
* Use CollectionMarshals in PVS and DynamicTree.
|
||||
* Make the proxy methods use MetaQuery / TransformQuery.
|
||||
|
||||
|
||||
## 161.1.0
|
||||
|
||||
### New features
|
||||
|
||||
* Add more DebugTools assert variations.
|
||||
|
||||
### Bugfixes
|
||||
|
||||
* Don't attempt to insert entities into deleted containers.
|
||||
* Try to fix oldestAck not being set correctly leading to deletion history getting bloated for pvs.
|
||||
|
||||
|
||||
## 161.0.0
|
||||
|
||||
### Breaking changes
|
||||
|
||||
* Point light animations now need to use different component fields in order to animate the lights. `Enabled` should be replaced with `AnimatedEnable` and `Radius` should be replaced with `AnimatedRadius`
|
||||
|
||||
### New features
|
||||
|
||||
* EntProtoId is now net-serializable
|
||||
* Added print_pvs_ack command to debug PVS issues.
|
||||
|
||||
### Bugfixes
|
||||
|
||||
* Fixes AngleTypeParser not using InvariantCulture
|
||||
* Fixed a bug that was causing `MetaDataComponent.LastComponentRemoved` to be updated improperly.
|
||||
|
||||
### Other
|
||||
|
||||
* The string representation of client-side entities now looks nicer and simply uses a 'c' prefix.
|
||||
|
||||
|
||||
## 160.1.0
|
||||
|
||||
### New features
|
||||
|
||||
* Add optional MetaDataComponent args to Entitymanager methods.
|
||||
|
||||
### Internal
|
||||
|
||||
* Move _netComponents onto MetaDataComponent.
|
||||
* Remove some component resolves internally on adding / removing components.
|
||||
|
||||
|
||||
## 160.0.2
|
||||
|
||||
### Other
|
||||
|
||||
* Transform component and containers have new convenience fields to make using VIewVariables easier.
|
||||
|
||||
|
||||
## 160.0.0
|
||||
|
||||
### Breaking changes
|
||||
|
||||
* ComponentReference has now been entirely removed.
|
||||
* Sensor / non-hard physics bodies are now included in EntityLookup by default.
|
||||
|
||||
|
||||
## 159.1.0
|
||||
|
||||
|
||||
## 159.0.3
|
||||
|
||||
### Bugfixes
|
||||
|
||||
* Fix potentially deleted entities having states re-applied when NetEntities come in.
|
||||
|
||||
|
||||
## 159.0.2
|
||||
|
||||
### Bugfixes
|
||||
|
||||
* Fix PointLight state handling not queueing ComponentTree updates.
|
||||
|
||||
|
||||
## 159.0.1
|
||||
|
||||
### Bugfixes
|
||||
|
||||
* Fix pending entity states not being removed when coming in (only on entity deletion).
|
||||
|
||||
### Internal
|
||||
|
||||
* Remove PhysicsComponent ref from Fixture.
|
||||
|
||||
|
||||
## 159.0.0
|
||||
|
||||
### Breaking changes
|
||||
|
||||
* Remove ComponentReference from PointLights.
|
||||
* Move more of UserInterfaceSystem to shared.
|
||||
* Mark some EntitySystem proxy methods as protected instead of public.
|
||||
|
||||
### New features
|
||||
|
||||
* Make entity deletion take in a nullable EntityUid.
|
||||
* Added a method to send predicted messages via BUIs.
|
||||
|
||||
### Other
|
||||
|
||||
* Add Obsoletions to more sourcegen serv4 methods.
|
||||
* Remove inactive reviewers from CODEOWNERs.
|
||||
|
||||
|
||||
## 158.0.0
|
||||
|
||||
### Breaking changes
|
||||
|
||||
* Remove SharedEyeComponent.
|
||||
* Add Tile Overlay edge priority.
|
||||
|
||||
|
||||
## 157.1.0
|
||||
|
||||
### New features
|
||||
|
||||
* UI tooltips now use rich text labels.
|
||||
|
||||
|
||||
## 157.0.0
|
||||
|
||||
### Breaking changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
- type: entity
|
||||
id: debugRotation
|
||||
abstract: true
|
||||
suffix: DEBUG
|
||||
categories: [ debug ]
|
||||
components:
|
||||
- type: Sprite
|
||||
netsync: false
|
||||
|
||||
17
Resources/EnginePrototypes/entityCategory.yml
Normal file
17
Resources/EnginePrototypes/entityCategory.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
# debug related entities
|
||||
- type: entityCategory
|
||||
id: debug
|
||||
name: entity-category-name-debug
|
||||
description: entity-category-desc-debug
|
||||
|
||||
# entities that spawn other entities
|
||||
- type: entityCategory
|
||||
id: spawner
|
||||
name: entity-category-name-spawner
|
||||
description: entity-category-desc-spawner
|
||||
|
||||
# entities that should be hidden from the spawn menu
|
||||
- type: entityCategory
|
||||
id: hideSpawnMenu
|
||||
name: entity-category-name-hide
|
||||
description: entity-category-desc-hide
|
||||
8
Resources/Locale/en-US/entity-category.ftl
Normal file
8
Resources/Locale/en-US/entity-category.ftl
Normal file
@@ -0,0 +1,8 @@
|
||||
entity-category-name-debug = Debug
|
||||
entity-category-desc-debug = Entity prototypes intended for debugging & testing.
|
||||
|
||||
entity-category-name-spawner = Spawner
|
||||
entity-category-desc-spawner = Entity prototypes that spawn other entities.
|
||||
|
||||
entity-category-name-hide = Hidden
|
||||
entity-category-desc-hide = Entity prototypes that should be hidden from the spawn menu
|
||||
@@ -1,5 +1,6 @@
|
||||
## ViewVariablesInstanceEntity
|
||||
|
||||
view-variables = View Variables
|
||||
view-variable-instance-entity-server-components-add-component-button-placeholder = Add Component
|
||||
view-variable-instance-entity-client-variables-tab-title = Client Variables
|
||||
view-variable-instance-entity-client-components-tab-title = Client Components
|
||||
@@ -8,4 +9,4 @@ view-variable-instance-entity-server-components-tab-title = Server Components
|
||||
view-variable-instance-entity-client-components-search-bar-placeholder = Search
|
||||
view-variable-instance-entity-server-components-search-bar-placeholder = Search
|
||||
view-variable-instance-entity-add-window-server-components = Add Component [S]
|
||||
view-variable-instance-entity-add-window-client-components = Add Component [C]
|
||||
view-variable-instance-entity-add-window-client-components = Add Component [C]
|
||||
|
||||
@@ -2,11 +2,13 @@ using Robust.Client.GameObjects;
|
||||
using Robust.Shared.ComponentTrees;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Physics;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Robust.Client.ComponentTrees;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class LightTreeComponent: Component, IComponentTreeComponent<PointLightComponent>
|
||||
{
|
||||
[ViewVariables]
|
||||
public DynamicTree<ComponentTreeEntry<PointLightComponent>> Tree { get; set; } = default!;
|
||||
}
|
||||
|
||||
@@ -78,14 +78,7 @@ namespace Robust.Client.Console.Commands
|
||||
message.Append($"net ID: {registration.NetID}");
|
||||
}
|
||||
|
||||
message.Append($", References:");
|
||||
|
||||
shell.WriteLine(message.ToString());
|
||||
|
||||
foreach (var type in registration.References)
|
||||
{
|
||||
shell.WriteLine($" {type}");
|
||||
}
|
||||
}
|
||||
catch (UnknownComponentException)
|
||||
{
|
||||
|
||||
@@ -35,14 +35,14 @@ public sealed partial class ClientEntityManager
|
||||
|
||||
if (NetEntityLookup.TryGetValue(nEntity, out var entity))
|
||||
{
|
||||
return entity;
|
||||
return entity.Item1;
|
||||
}
|
||||
|
||||
// Flag the callerEntity to have their state potentially re-run later.
|
||||
var pending = PendingNetEntityStates.GetOrNew(nEntity);
|
||||
pending.Add((typeof(T), callerEntity));
|
||||
|
||||
return entity;
|
||||
return entity.Item1;
|
||||
}
|
||||
|
||||
public override EntityCoordinates EnsureCoordinates<T>(NetCoordinates netCoordinates, EntityUid callerEntity)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Prometheus;
|
||||
using Robust.Client.GameStates;
|
||||
using Robust.Client.Player;
|
||||
@@ -65,9 +66,12 @@ namespace Robust.Client.GameObjects
|
||||
base.DirtyEntity(uid, meta);
|
||||
}
|
||||
|
||||
public override void QueueDeleteEntity(EntityUid uid)
|
||||
public override void QueueDeleteEntity(EntityUid? uid)
|
||||
{
|
||||
if (IsClientSide(uid))
|
||||
if (uid == null)
|
||||
return;
|
||||
|
||||
if (IsClientSide(uid.Value))
|
||||
{
|
||||
base.QueueDeleteEntity(uid);
|
||||
return;
|
||||
@@ -78,7 +82,7 @@ namespace Robust.Client.GameObjects
|
||||
|
||||
// Client-side entity deletion is not supported and will cause errors.
|
||||
if (_client.RunLevel == ClientRunLevel.Connected || _client.RunLevel == ClientRunLevel.InGame)
|
||||
LogManager.RootSawmill.Error($"Predicting the queued deletion of a networked entity: {ToPrettyString(uid)}. Trace: {Environment.StackTrace}");
|
||||
LogManager.RootSawmill.Error($"Predicting the queued deletion of a networked entity: {ToPrettyString(uid.Value)}. Trace: {Environment.StackTrace}");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -89,12 +93,16 @@ namespace Robust.Client.GameObjects
|
||||
base.Dirty(uid, component, meta);
|
||||
}
|
||||
|
||||
public override EntityStringRepresentation ToPrettyString(EntityUid uid)
|
||||
[return: NotNullIfNotNull("uid")]
|
||||
public override EntityStringRepresentation? ToPrettyString(EntityUid? uid)
|
||||
{
|
||||
if (uid == null)
|
||||
return null;
|
||||
|
||||
if (_playerManager.LocalPlayer?.ControlledEntity == uid)
|
||||
return base.ToPrettyString(uid) with { Session = _playerManager.LocalPlayer.Session };
|
||||
else
|
||||
return base.ToPrettyString(uid);
|
||||
return base.ToPrettyString(uid).Value with { Session = _playerManager.LocalPlayer.Session };
|
||||
|
||||
return base.ToPrettyString(uid);
|
||||
}
|
||||
|
||||
public override void RaisePredictiveEvent<T>(T msg)
|
||||
|
||||
@@ -1,136 +0,0 @@
|
||||
using System.Numerics;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Robust.Client.GameObjects
|
||||
{
|
||||
[RegisterComponent, ComponentReference(typeof(SharedEyeComponent))]
|
||||
public sealed partial class EyeComponent : SharedEyeComponent
|
||||
{
|
||||
[Dependency] private readonly IEyeManager _eyeManager = default!;
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
|
||||
[ViewVariables] internal Eye? _eye = default!;
|
||||
|
||||
// Horrible hack to get around ordering issues.
|
||||
internal bool _setCurrentOnInitialize;
|
||||
[DataField("drawFov")] internal bool _setDrawFovOnInitialize = true;
|
||||
[DataField("zoom")] internal Vector2 _setZoomOnInitialize = Vector2.One;
|
||||
|
||||
/// <summary>
|
||||
/// If not null, this entity is used to update the eye's position instead of just using the component's owner.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is useful for things like vehicles that effectively need to hijack the eye. This allows them to do
|
||||
/// that without messing with the main viewport's eye. This is important as there are some overlays that are
|
||||
/// only be drawn if that viewport's eye belongs to the currently controlled entity.
|
||||
/// </remarks>
|
||||
[ViewVariables]
|
||||
public EntityUid? Target;
|
||||
|
||||
public IEye? Eye => _eye;
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public bool Current
|
||||
{
|
||||
get => _eyeManager.CurrentEye == _eye;
|
||||
set
|
||||
{
|
||||
if (_eye == null)
|
||||
{
|
||||
_setCurrentOnInitialize = value;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_eyeManager.CurrentEye == _eye == value)
|
||||
return;
|
||||
|
||||
if (value)
|
||||
{
|
||||
_eyeManager.CurrentEye = _eye;
|
||||
}
|
||||
else
|
||||
{
|
||||
_eyeManager.ClearCurrentEye();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override Vector2 Zoom
|
||||
{
|
||||
get => _eye?.Zoom ?? _setZoomOnInitialize;
|
||||
set
|
||||
{
|
||||
if (_eye == null)
|
||||
{
|
||||
_setZoomOnInitialize = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
_eye.Zoom = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override Angle Rotation
|
||||
{
|
||||
get => _eye?.Rotation ?? Angle.Zero;
|
||||
set
|
||||
{
|
||||
if (_eye != null)
|
||||
_eye.Rotation = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override Vector2 Offset
|
||||
{
|
||||
get => _eye?.Offset ?? default;
|
||||
set
|
||||
{
|
||||
if (_eye != null)
|
||||
_eye.Offset = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool DrawFov
|
||||
{
|
||||
get => _eye?.DrawFov ?? _setDrawFovOnInitialize;
|
||||
set
|
||||
{
|
||||
if (_eye == null)
|
||||
{
|
||||
_setDrawFovOnInitialize = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
_eye.DrawFov = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[ViewVariables]
|
||||
public MapCoordinates? Position => _eye?.Position;
|
||||
|
||||
/// <summary>
|
||||
/// Updates the Eye of this entity with the transform position. This has to be called every frame to
|
||||
/// keep the view following the entity.
|
||||
/// </summary>
|
||||
public void UpdateEyePosition()
|
||||
{
|
||||
if (_eye == null) return;
|
||||
|
||||
if (!_entityManager.TryGetComponent(Target, out TransformComponent? xform))
|
||||
{
|
||||
xform = _entityManager.GetComponent<TransformComponent>(Owner);
|
||||
Target = null;
|
||||
}
|
||||
|
||||
_eye.Position = xform.MapPosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.Animations;
|
||||
using Robust.Shared.ComponentTrees;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Physics;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Robust.Client.GameObjects
|
||||
{
|
||||
[RegisterComponent]
|
||||
[ComponentReference(typeof(SharedPointLightComponent))]
|
||||
public sealed partial class PointLightComponent : SharedPointLightComponent, IComponentTreeEntry<PointLightComponent>
|
||||
{
|
||||
public EntityUid? TreeUid { get; set; }
|
||||
|
||||
public DynamicTree<ComponentTreeEntry<PointLightComponent>>? Tree { get; set; }
|
||||
|
||||
public bool AddToTree => Enabled && !ContainerOccluded;
|
||||
public bool TreeUpdateQueued { get; set; }
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[Animatable]
|
||||
public override Color Color
|
||||
{
|
||||
get => _color;
|
||||
set => base.Color = value;
|
||||
}
|
||||
|
||||
[Access(typeof(PointLightSystem))]
|
||||
public bool ContainerOccluded;
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the light mask should automatically rotate with the entity. (like a flashlight)
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public bool MaskAutoRotate
|
||||
{
|
||||
get => _maskAutoRotate;
|
||||
set => _maskAutoRotate = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Local rotation of the light mask around the center origin
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[Animatable]
|
||||
public Angle Rotation
|
||||
{
|
||||
get => _rotation;
|
||||
set => _rotation = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The resource path to the mask texture the light will use.
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public string? MaskPath
|
||||
{
|
||||
get => _maskPath;
|
||||
set
|
||||
{
|
||||
if (_maskPath?.Equals(value) != false) return;
|
||||
_maskPath = value;
|
||||
EntitySystem.Get<PointLightSystem>().UpdateMask(this);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set a mask texture that will be applied to the light while rendering.
|
||||
/// The mask's red channel will be linearly multiplied.p
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public Texture? Mask { get; set; }
|
||||
|
||||
[DataField("autoRot")]
|
||||
private bool _maskAutoRotate;
|
||||
private Angle _rotation;
|
||||
|
||||
[DataField("mask")]
|
||||
internal string? _maskPath;
|
||||
}
|
||||
}
|
||||
38
Robust.Client/GameObjects/Components/PointLightComponent.cs
Normal file
38
Robust.Client/GameObjects/Components/PointLightComponent.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.ComponentTrees;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Physics;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Robust.Client.GameObjects;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class PointLightComponent : SharedPointLightComponent, IComponentTreeEntry<PointLightComponent>
|
||||
{
|
||||
#region Component Tree
|
||||
|
||||
/// <inheritdoc />
|
||||
[ViewVariables]
|
||||
public EntityUid? TreeUid { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
[ViewVariables]
|
||||
public DynamicTree<ComponentTreeEntry<PointLightComponent>>? Tree { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
[ViewVariables]
|
||||
public bool AddToTree => Enabled && !ContainerOccluded;
|
||||
|
||||
/// <inheritdoc />
|
||||
[ViewVariables]
|
||||
public bool TreeUpdateQueued { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Set a mask texture that will be applied to the light while rendering.
|
||||
/// The mask's red channel will be linearly multiplied.
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
internal Texture? Mask;
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
using System.Numerics;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Graphics.RSI;
|
||||
using Robust.Shared.Maths;
|
||||
|
||||
namespace Robust.Client.GameObjects
|
||||
@@ -24,7 +26,7 @@ namespace Robust.Client.GameObjects
|
||||
int AnimationFrame { get; }
|
||||
bool AutoAnimated { get; set; }
|
||||
|
||||
RSI.State.Direction EffectiveDirection(Angle worldRotation);
|
||||
RsiDirection EffectiveDirection(Angle worldRotation);
|
||||
|
||||
/// <summary>
|
||||
/// Layer size in pixels.
|
||||
|
||||
@@ -12,6 +12,8 @@ using Robust.Shared;
|
||||
using Robust.Shared.Animations;
|
||||
using Robust.Shared.ComponentTrees;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Graphics.RSI;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Map;
|
||||
@@ -26,8 +28,8 @@ using Robust.Shared.Utility;
|
||||
using Robust.Shared.ViewVariables;
|
||||
using static Robust.Client.ComponentTrees.SpriteTreeSystem;
|
||||
using DrawDepthTag = Robust.Shared.GameObjects.DrawDepth;
|
||||
using RSIDirection = Robust.Client.Graphics.RSI.State.Direction;
|
||||
using static Robust.Shared.Serialization.TypeSerializers.Implementations.SpriteSpecifierSerializer;
|
||||
using Direction = Robust.Shared.Maths.Direction;
|
||||
|
||||
namespace Robust.Client.GameObjects
|
||||
{
|
||||
@@ -1347,11 +1349,11 @@ namespace Robust.Client.GameObjects
|
||||
state = GetFallbackState(resourceCache);
|
||||
}
|
||||
|
||||
return state.Directions switch
|
||||
return state.RsiDirections switch
|
||||
{
|
||||
RSI.State.DirectionType.Dir1 => 1,
|
||||
RSI.State.DirectionType.Dir4 => 4,
|
||||
RSI.State.DirectionType.Dir8 => 8,
|
||||
RsiDirectionType.Dir1 => 1,
|
||||
RsiDirectionType.Dir4 => 4,
|
||||
RsiDirectionType.Dir8 => 8,
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
};
|
||||
}
|
||||
@@ -1389,7 +1391,7 @@ namespace Robust.Client.GameObjects
|
||||
builder.AppendFormat(
|
||||
"vis/depth/scl/rot/ofs/col/norot/override/dir: {0}/{1}/{2}/{3}/{4}/{5}/{6}/{8}/{7}\n",
|
||||
Visible, DrawDepth, Scale, Rotation, Offset,
|
||||
Color, NoRotation, entities.GetComponent<TransformComponent>(Owner).WorldRotation.ToRsiDirection(RSI.State.DirectionType.Dir8),
|
||||
Color, NoRotation, entities.GetComponent<TransformComponent>(Owner).WorldRotation.ToRsiDirection(RsiDirectionType.Dir8),
|
||||
DirectionOverride
|
||||
);
|
||||
|
||||
@@ -1689,7 +1691,7 @@ namespace Robust.Client.GameObjects
|
||||
|
||||
int ISpriteLayer.AnimationFrame => AnimationFrame;
|
||||
|
||||
public RSIDirection EffectiveDirection(Angle worldRotation)
|
||||
public RsiDirection EffectiveDirection(Angle worldRotation)
|
||||
{
|
||||
if (State == default)
|
||||
{
|
||||
@@ -1710,23 +1712,23 @@ namespace Robust.Client.GameObjects
|
||||
return default;
|
||||
}
|
||||
|
||||
public RSIDirection EffectiveDirection(RSI.State state, Angle worldRotation,
|
||||
public RsiDirection EffectiveDirection(RSI.State state, Angle worldRotation,
|
||||
Direction? overrideDirection)
|
||||
{
|
||||
if (state.Directions == RSI.State.DirectionType.Dir1)
|
||||
if (state.RsiDirections == RsiDirectionType.Dir1)
|
||||
{
|
||||
return RSIDirection.South;
|
||||
return RsiDirection.South;
|
||||
}
|
||||
else
|
||||
{
|
||||
RSIDirection dir;
|
||||
RsiDirection dir;
|
||||
if (overrideDirection != null)
|
||||
{
|
||||
dir = overrideDirection.Value.Convert(state.Directions);
|
||||
dir = overrideDirection.Value.Convert(state.RsiDirections);
|
||||
}
|
||||
else
|
||||
{
|
||||
dir = worldRotation.ToRsiDirection(state.Directions);
|
||||
dir = worldRotation.ToRsiDirection(state.RsiDirections);
|
||||
}
|
||||
|
||||
return dir.OffsetRsiDir(DirOffset);
|
||||
@@ -1882,20 +1884,20 @@ namespace Robust.Client.GameObjects
|
||||
else if (_parent.SnapCardinals && (!_parent.GranularLayersRendering || RenderingStrategy == LayerRenderingStrategy.UseSpriteStrategy)
|
||||
|| _parent.GranularLayersRendering && RenderingStrategy == LayerRenderingStrategy.SnapToCardinals)
|
||||
{
|
||||
DebugTools.Assert(_actualState == null || _actualState.Directions == RSI.State.DirectionType.Dir1);
|
||||
DebugTools.Assert(_actualState == null || _actualState.RsiDirections == RsiDirectionType.Dir1);
|
||||
size = new Vector2(longestSide, longestSide);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Build the bounding box based on how many directions the sprite has
|
||||
size = (_actualState?.Directions) switch
|
||||
size = (_actualState?.RsiDirections) switch
|
||||
{
|
||||
// If we have four cardinal directions, take the longest side of our texture and square it, then turn that into our bounding box.
|
||||
// This accounts for all possible rotations.
|
||||
RSI.State.DirectionType.Dir4 => new Vector2(longestSide, longestSide),
|
||||
RsiDirectionType.Dir4 => new Vector2(longestSide, longestSide),
|
||||
|
||||
// If we have eight directions, find the maximum length of the texture (accounting for rotation), then square it to make
|
||||
RSI.State.DirectionType.Dir8 => new Vector2(longestRotatedSide, longestRotatedSide),
|
||||
RsiDirectionType.Dir8 => new Vector2(longestRotatedSide, longestRotatedSide),
|
||||
|
||||
// If we have only one direction or an invalid RSI state, create a simple bounding box with the size of the texture.
|
||||
_ => textureSize
|
||||
@@ -1929,9 +1931,9 @@ namespace Robust.Client.GameObjects
|
||||
/// Given the apparent rotation of an entity on screen (world + eye rotation), get layer's matrix for drawing &
|
||||
/// relevant RSI direction.
|
||||
/// </summary>
|
||||
public void GetLayerDrawMatrix(RSIDirection dir, out Matrix3 layerDrawMatrix)
|
||||
public void GetLayerDrawMatrix(RsiDirection dir, out Matrix3 layerDrawMatrix)
|
||||
{
|
||||
if (_parent.NoRotation || dir == RSIDirection.South)
|
||||
if (_parent.NoRotation || dir == RsiDirection.South)
|
||||
layerDrawMatrix = LocalMatrix;
|
||||
else
|
||||
{
|
||||
@@ -1956,11 +1958,11 @@ namespace Robust.Client.GameObjects
|
||||
/// Converts an angle (between 0 and 2pi) to an RSI direction. This will slightly bias the angle to avoid flickering for
|
||||
/// 4-directional sprites.
|
||||
/// </summary>
|
||||
public static RSIDirection GetDirection(RSI.State.DirectionType dirType, Angle angle)
|
||||
public static RsiDirection GetDirection(RsiDirectionType dirType, Angle angle)
|
||||
{
|
||||
if (dirType == RSI.State.DirectionType.Dir1)
|
||||
return RSIDirection.South;
|
||||
else if (dirType == RSI.State.DirectionType.Dir8)
|
||||
if (dirType == RsiDirectionType.Dir1)
|
||||
return RsiDirection.South;
|
||||
else if (dirType == RsiDirectionType.Dir8)
|
||||
return angle.GetDir().Convert(dirType);
|
||||
|
||||
// For 4-directional sprites, as entities are often moving & facing diagonally, we will slightly bias the
|
||||
@@ -1973,10 +1975,10 @@ namespace Robust.Client.GameObjects
|
||||
|
||||
return ((int)Math.Round(modTheta / MathHelper.PiOver2) % 4) switch
|
||||
{
|
||||
0 => RSIDirection.South,
|
||||
1 => RSIDirection.East,
|
||||
2 => RSIDirection.North,
|
||||
_ => RSIDirection.West,
|
||||
0 => RsiDirection.South,
|
||||
1 => RsiDirection.East,
|
||||
2 => RsiDirection.North,
|
||||
_ => RsiDirection.West,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1988,7 +1990,7 @@ namespace Robust.Client.GameObjects
|
||||
if (!Visible || Blank)
|
||||
return;
|
||||
|
||||
var dir = _actualState == null ? RSIDirection.South : GetDirection(_actualState.Directions, angle);
|
||||
var dir = _actualState == null ? RsiDirection.South : GetDirection(_actualState.RsiDirections, angle);
|
||||
|
||||
// Set the drawing transform for this layer
|
||||
GetLayerDrawMatrix(dir, out var layerMatrix);
|
||||
@@ -1998,7 +2000,7 @@ namespace Robust.Client.GameObjects
|
||||
// The direction used to draw the sprite can differ from the one that the angle would naively suggest,
|
||||
// due to direction overrides or offsets.
|
||||
if (overrideDirection != null && _actualState != null)
|
||||
dir = overrideDirection.Value.Convert(_actualState.Directions);
|
||||
dir = overrideDirection.Value.Convert(_actualState.RsiDirections);
|
||||
dir = dir.OffsetRsiDir(DirOffset);
|
||||
|
||||
// Get the correct directional texture from the state, and draw it!
|
||||
@@ -2021,7 +2023,7 @@ namespace Robust.Client.GameObjects
|
||||
drawingHandle.UseShader(null);
|
||||
}
|
||||
|
||||
private Texture GetRenderTexture(RSI.State? state, RSIDirection dir)
|
||||
private Texture GetRenderTexture(RSI.State? state, RsiDirection dir)
|
||||
{
|
||||
if (state == null)
|
||||
return Texture ?? _parent.resourceCache.GetFallback<TextureResource>().Texture;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Physics;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.IoC;
|
||||
|
||||
namespace Robust.Client.GameObjects;
|
||||
@@ -13,8 +15,35 @@ public sealed class EyeSystem : SharedEyeSystem
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<EyeComponent, ComponentInit>(OnInit);
|
||||
SubscribeLocalEvent<EyeComponent, ComponentRemove>(OnRemove);
|
||||
SubscribeLocalEvent<EyeComponent, ComponentHandleState>(OnHandleState);
|
||||
SubscribeLocalEvent<EyeComponent, PlayerDetachedEvent>(OnEyeDetached);
|
||||
SubscribeLocalEvent<EyeComponent, PlayerAttachedEvent>(OnEyeAttached);
|
||||
SubscribeLocalEvent<EyeComponent, AfterAutoHandleStateEvent>(OnEyeAutoState);
|
||||
|
||||
// Make sure this runs *after* entities have been moved by interpolation and movement.
|
||||
UpdatesAfter.Add(typeof(TransformSystem));
|
||||
UpdatesAfter.Add(typeof(PhysicsSystem));
|
||||
}
|
||||
|
||||
private void OnEyeAutoState(EntityUid uid, EyeComponent component, ref AfterAutoHandleStateEvent args)
|
||||
{
|
||||
UpdateEye(component);
|
||||
}
|
||||
|
||||
private void OnEyeAttached(EntityUid uid, EyeComponent component, PlayerAttachedEvent args)
|
||||
{
|
||||
// TODO: This probably shouldn't be nullable bruv.
|
||||
if (component._eye != null)
|
||||
{
|
||||
_eyeManager.CurrentEye = component._eye;
|
||||
}
|
||||
|
||||
var ev = new EyeAttachedEvent(uid, component);
|
||||
RaiseLocalEvent(uid, ref ev, true);
|
||||
}
|
||||
|
||||
private void OnEyeDetached(EntityUid uid, EyeComponent component, PlayerDetachedEvent args)
|
||||
{
|
||||
_eyeManager.ClearCurrentEye();
|
||||
}
|
||||
|
||||
private void OnInit(EntityUid uid, EyeComponent component, ComponentInit args)
|
||||
@@ -22,39 +51,35 @@ public sealed class EyeSystem : SharedEyeSystem
|
||||
component._eye = new Eye
|
||||
{
|
||||
Position = Transform(uid).MapPosition,
|
||||
Zoom = component._setZoomOnInitialize,
|
||||
DrawFov = component._setDrawFovOnInitialize
|
||||
Zoom = component.Zoom,
|
||||
DrawFov = component.DrawFov,
|
||||
Rotation = component.Rotation,
|
||||
};
|
||||
|
||||
if ((_eyeManager.CurrentEye == component._eye) != component._setCurrentOnInitialize)
|
||||
{
|
||||
if (component._setCurrentOnInitialize)
|
||||
{
|
||||
_eyeManager.ClearCurrentEye();
|
||||
}
|
||||
else
|
||||
{
|
||||
_eyeManager.CurrentEye = component._eye;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnRemove(EntityUid uid, EyeComponent component, ComponentRemove args)
|
||||
/// <inheritdoc />
|
||||
public override void FrameUpdate(float frameTime)
|
||||
{
|
||||
component.Current = false;
|
||||
}
|
||||
var query = AllEntityQuery<EyeComponent>();
|
||||
|
||||
private void OnHandleState(EntityUid uid, EyeComponent component, ref ComponentHandleState args)
|
||||
{
|
||||
if (args.Current is not EyeComponentState state)
|
||||
while (query.MoveNext(out var uid, out var eyeComponent))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (eyeComponent._eye == null)
|
||||
continue;
|
||||
|
||||
component.DrawFov = state.DrawFov;
|
||||
// TODO: Should be a way for content to override lerping and lerp the zoom
|
||||
component.Zoom = state.Zoom;
|
||||
component.Offset = state.Offset;
|
||||
component.VisibilityMask = state.VisibilityMask;
|
||||
if (!TryComp<TransformComponent>(eyeComponent.Target, out var xform))
|
||||
{
|
||||
xform = Transform(uid);
|
||||
eyeComponent.Target = null;
|
||||
}
|
||||
|
||||
eyeComponent._eye.Position = xform.MapPosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raised on an entity when it is attached to one with an <see cref="EyeComponent"/>
|
||||
/// </summary>
|
||||
[ByRefEvent]
|
||||
public readonly record struct EyeAttachedEvent(EntityUid Entity, EyeComponent Component);
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
using System;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Physics;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Input;
|
||||
using Robust.Shared.Input.Binding;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Robust.Client.GameObjects
|
||||
{
|
||||
/// <summary>
|
||||
/// Updates the position of every Eye every frame, so that the camera follows the player around.
|
||||
/// </summary>
|
||||
[UsedImplicitly]
|
||||
public sealed class EyeUpdateSystem : EntitySystem
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
// Make sure this runs *after* entities have been moved by interpolation and movement.
|
||||
UpdatesAfter.Add(typeof(TransformSystem));
|
||||
UpdatesAfter.Add(typeof(PhysicsSystem));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void FrameUpdate(float frameTime)
|
||||
{
|
||||
foreach (var eyeComponent in EntityManager.EntityQuery<EyeComponent>(true))
|
||||
{
|
||||
eyeComponent.UpdateEyePosition();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Robust.Client.ComponentTrees;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Maths;
|
||||
|
||||
@@ -15,59 +17,108 @@ namespace Robust.Client.GameObjects
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<PointLightComponent, ComponentInit>(HandleInit);
|
||||
SubscribeLocalEvent<PointLightComponent, ComponentHandleState>(OnLightHandleState);
|
||||
}
|
||||
|
||||
private void OnLightHandleState(EntityUid uid, PointLightComponent component, ref ComponentHandleState args)
|
||||
{
|
||||
if (args.Current is not PointLightComponentState state)
|
||||
return;
|
||||
|
||||
component.Enabled = state.Enabled;
|
||||
component.Offset = state.Offset;
|
||||
component.Softness = state.Softness;
|
||||
component.CastShadows = state.CastShadows;
|
||||
component.Energy = state.Energy;
|
||||
component.Radius = state.Radius;
|
||||
component.Color = state.Color;
|
||||
|
||||
_lightTree.QueueTreeUpdate(uid, component);
|
||||
}
|
||||
|
||||
public override SharedPointLightComponent EnsureLight(EntityUid uid)
|
||||
{
|
||||
return EnsureComp<PointLightComponent>(uid);
|
||||
}
|
||||
|
||||
public override bool ResolveLight(EntityUid uid, [NotNullWhen(true)] ref SharedPointLightComponent? component)
|
||||
{
|
||||
if (component is not null)
|
||||
return true;
|
||||
|
||||
TryComp<PointLightComponent>(uid, out var comp);
|
||||
component = comp;
|
||||
return component != null;
|
||||
}
|
||||
|
||||
public override bool TryGetLight(EntityUid uid, [NotNullWhen(true)] out SharedPointLightComponent? component)
|
||||
{
|
||||
if (TryComp<PointLightComponent>(uid, out var comp))
|
||||
{
|
||||
component = comp;
|
||||
return true;
|
||||
}
|
||||
|
||||
component = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool RemoveLightDeferred(EntityUid uid)
|
||||
{
|
||||
return RemCompDeferred<PointLightComponent>(uid);
|
||||
}
|
||||
|
||||
private void HandleInit(EntityUid uid, PointLightComponent component, ComponentInit args)
|
||||
{
|
||||
UpdateMask(component);
|
||||
SetMask(component.MaskPath, component);
|
||||
}
|
||||
|
||||
internal void UpdateMask(PointLightComponent component)
|
||||
public void SetMask(string? maskPath, PointLightComponent component)
|
||||
{
|
||||
if (component._maskPath is not null)
|
||||
component.Mask = _resourceCache.GetResource<TextureResource>(component._maskPath);
|
||||
if (maskPath is not null)
|
||||
component.Mask = _resourceCache.GetResource<TextureResource>(maskPath);
|
||||
else
|
||||
component.Mask = null;
|
||||
}
|
||||
|
||||
#region Setters
|
||||
public void SetContainerOccluded(EntityUid uid, bool occluded, PointLightComponent? comp = null)
|
||||
|
||||
public void SetContainerOccluded(EntityUid uid, bool occluded, SharedPointLightComponent? comp = null)
|
||||
{
|
||||
if (!Resolve(uid, ref comp) || occluded == comp.ContainerOccluded)
|
||||
if (!ResolveLight(uid, ref comp) || occluded == comp.ContainerOccluded || comp is not PointLightComponent clientComp)
|
||||
return;
|
||||
|
||||
comp.ContainerOccluded = occluded;
|
||||
Dirty(uid, comp);
|
||||
|
||||
if (comp.Enabled)
|
||||
_lightTree.QueueTreeUpdate(uid, comp);
|
||||
_lightTree.QueueTreeUpdate(uid, clientComp);
|
||||
}
|
||||
|
||||
public override void SetEnabled(EntityUid uid, bool enabled, SharedPointLightComponent? comp = null)
|
||||
{
|
||||
if (!Resolve(uid, ref comp) || enabled == comp.Enabled)
|
||||
if (!ResolveLight(uid, ref comp) || enabled == comp.Enabled || comp is not PointLightComponent clientComp)
|
||||
return;
|
||||
|
||||
comp._enabled = enabled;
|
||||
comp.Enabled = enabled;
|
||||
RaiseLocalEvent(uid, new PointLightToggleEvent(comp.Enabled));
|
||||
Dirty(uid, comp);
|
||||
|
||||
var cast = (PointLightComponent)comp;
|
||||
if (!cast.ContainerOccluded)
|
||||
_lightTree.QueueTreeUpdate(uid, cast);
|
||||
if (!comp.ContainerOccluded)
|
||||
_lightTree.QueueTreeUpdate(uid, clientComp);
|
||||
}
|
||||
|
||||
public override void SetRadius(EntityUid uid, float radius, SharedPointLightComponent? comp = null)
|
||||
{
|
||||
if (!Resolve(uid, ref comp) || MathHelper.CloseToPercent(radius, comp.Radius))
|
||||
if (!ResolveLight(uid, ref comp) || MathHelper.CloseToPercent(radius, comp.Radius) ||
|
||||
comp is not PointLightComponent clientComp)
|
||||
return;
|
||||
|
||||
comp._radius = radius;
|
||||
comp.Radius = radius;
|
||||
Dirty(uid, comp);
|
||||
|
||||
var cast = (PointLightComponent)comp;
|
||||
if (cast.TreeUid != null)
|
||||
_lightTree.QueueTreeUpdate(uid, cast);
|
||||
if (clientComp.TreeUid != null)
|
||||
_lightTree.QueueTreeUpdate(uid, clientComp);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ using JetBrains.Annotations;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Client.Utility;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations;
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Reflection;
|
||||
using System;
|
||||
using UserInterfaceComponent = Robust.Shared.GameObjects.UserInterfaceComponent;
|
||||
|
||||
namespace Robust.Client.GameObjects
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public sealed class UserInterfaceSystem : SharedUserInterfaceSystem
|
||||
{
|
||||
[Dependency] private readonly IDynamicTypeFactory _dynamicTypeFactory = default!;
|
||||
@@ -19,39 +18,19 @@ namespace Robust.Client.GameObjects
|
||||
base.Initialize();
|
||||
|
||||
SubscribeNetworkEvent<BoundUIWrapMessage>(MessageReceived);
|
||||
SubscribeLocalEvent<ClientUserInterfaceComponent, ComponentInit>(OnUserInterfaceInit);
|
||||
SubscribeLocalEvent<ClientUserInterfaceComponent, ComponentShutdown>(OnUserInterfaceShutdown);
|
||||
}
|
||||
|
||||
private void OnUserInterfaceInit(EntityUid uid, ClientUserInterfaceComponent component, ComponentInit args)
|
||||
{
|
||||
component._interfaces.Clear();
|
||||
|
||||
foreach (var data in component._interfaceData)
|
||||
{
|
||||
component._interfaces[data.UiKey] = data;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnUserInterfaceShutdown(EntityUid uid, ClientUserInterfaceComponent component, ComponentShutdown args)
|
||||
{
|
||||
foreach (var bui in component.OpenInterfaces.Values)
|
||||
{
|
||||
bui.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private void MessageReceived(BoundUIWrapMessage ev)
|
||||
{
|
||||
var uid = GetEntity(ev.Entity);
|
||||
|
||||
if (!TryComp<ClientUserInterfaceComponent>(uid, out var cmp))
|
||||
if (!TryComp<UserInterfaceComponent>(uid, out var cmp))
|
||||
return;
|
||||
|
||||
var uiKey = ev.UiKey;
|
||||
var message = ev.Message;
|
||||
// This should probably not happen at this point, but better make extra sure!
|
||||
if(_playerManager.LocalPlayer != null)
|
||||
if (_playerManager.LocalPlayer != null)
|
||||
message.Session = _playerManager.LocalPlayer.Session;
|
||||
|
||||
message.Entity = GetNetEntity(uid);
|
||||
@@ -67,7 +46,7 @@ namespace Robust.Client.GameObjects
|
||||
break;
|
||||
|
||||
case CloseBoundInterfaceMessage _:
|
||||
TryCloseUi(uid, uiKey, remoteCall: true, uiComp: cmp);
|
||||
TryCloseUi(message.Session, uid, uiKey, remoteCall: true, uiComp: cmp);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -78,7 +57,7 @@ namespace Robust.Client.GameObjects
|
||||
}
|
||||
}
|
||||
|
||||
private bool TryOpenUi(EntityUid uid, Enum uiKey, ClientUserInterfaceComponent? uiComp = null)
|
||||
private bool TryOpenUi(EntityUid uid, Enum uiKey, UserInterfaceComponent? uiComp = null)
|
||||
{
|
||||
if (!Resolve(uid, ref uiComp))
|
||||
return false;
|
||||
@@ -86,7 +65,7 @@ namespace Robust.Client.GameObjects
|
||||
if (uiComp.OpenInterfaces.ContainsKey(uiKey))
|
||||
return false;
|
||||
|
||||
var data = uiComp._interfaces[uiKey];
|
||||
var data = uiComp.MappedInterfaceData[uiKey];
|
||||
|
||||
// TODO: This type should be cached, but I'm too lazy.
|
||||
var type = _reflectionManager.LooseGetType(data.ClientType);
|
||||
@@ -97,36 +76,13 @@ namespace Robust.Client.GameObjects
|
||||
uiComp.OpenInterfaces[uiKey] = boundInterface;
|
||||
|
||||
var playerSession = _playerManager.LocalPlayer?.Session;
|
||||
if(playerSession != null)
|
||||
if (playerSession != null)
|
||||
{
|
||||
uiComp.Interfaces[uiKey]._subscribedSessions.Add(playerSession);
|
||||
RaiseLocalEvent(uid, new BoundUIOpenedEvent(uiKey, uid, playerSession), true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal bool TryCloseUi(EntityUid uid, Enum uiKey, bool remoteCall = false, ClientUserInterfaceComponent? uiComp = null)
|
||||
{
|
||||
if (!Resolve(uid, ref uiComp))
|
||||
return false;
|
||||
|
||||
if (!uiComp.OpenInterfaces.TryGetValue(uiKey, out var boundUserInterface))
|
||||
return false;
|
||||
|
||||
if (!remoteCall)
|
||||
SendUiMessage(boundUserInterface, new CloseBoundInterfaceMessage());
|
||||
|
||||
uiComp.OpenInterfaces.Remove(uiKey);
|
||||
boundUserInterface.Dispose();
|
||||
|
||||
var playerSession = _playerManager.LocalPlayer?.Session;
|
||||
if(playerSession != null)
|
||||
RaiseLocalEvent(uid, new BoundUIClosedEvent(uiKey, uid, playerSession), true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal void SendUiMessage(BoundUserInterface bui, BoundUserInterfaceMessage msg)
|
||||
{
|
||||
RaiseNetworkEvent(new BoundUIWrapMessage(GetNetEntity(bui.Owner), msg, bui.UiKey));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using Robust.Client.Timing;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Utility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -54,7 +53,7 @@ public sealed class ClientDirtySystem : EntitySystem
|
||||
|
||||
var uid = args.BaseArgs.Owner;
|
||||
var comp = args.BaseArgs.Component;
|
||||
if (!_timing.InPrediction || !comp.NetSyncEnabled || IsClientSide(uid))
|
||||
if (!_timing.InPrediction || !comp.NetSyncEnabled || IsClientSide(uid, args.Meta))
|
||||
return;
|
||||
|
||||
// Was this component added during prediction? If yes, then there is no need to re-add it when resetting.
|
||||
|
||||
@@ -4,6 +4,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Input;
|
||||
@@ -47,7 +48,7 @@ namespace Robust.Client.GameStates
|
||||
= new();
|
||||
|
||||
// Game state dictionaries that get used every tick.
|
||||
private readonly Dictionary<EntityUid, (bool EnteringPvs, GameTick LastApplied, EntityState? curState, EntityState? nextState)> _toApply = new();
|
||||
private readonly Dictionary<EntityUid, (NetEntity NetEntity, MetaDataComponent Meta, bool EnteringPvs, GameTick LastApplied, EntityState? curState, EntityState? nextState)> _toApply = new();
|
||||
private readonly Dictionary<NetEntity, EntityState> _toCreate = new();
|
||||
private readonly Dictionary<ushort, (IComponent Component, ComponentState? curState, ComponentState? nextState)> _compStateWork = new();
|
||||
private readonly Dictionary<EntityUid, HashSet<Type>> _pendingReapplyNetStates = new();
|
||||
@@ -497,11 +498,7 @@ namespace Robust.Client.GameStates
|
||||
|
||||
countReset += 1;
|
||||
|
||||
var netComps = _entityManager.GetNetComponentsOrNull(entity);
|
||||
if (netComps == null)
|
||||
continue;
|
||||
|
||||
foreach (var (netId, comp) in netComps.Value)
|
||||
foreach (var (netId, comp) in meta.NetComponents)
|
||||
{
|
||||
if (!comp.NetSyncEnabled)
|
||||
continue;
|
||||
@@ -549,13 +546,13 @@ namespace Robust.Client.GameStates
|
||||
{
|
||||
foreach (var netId in netIds)
|
||||
{
|
||||
if (_entities.HasComponent(entity, netId))
|
||||
if (meta.NetComponents.ContainsKey(netId))
|
||||
continue;
|
||||
|
||||
if (!last.TryGetValue(netId, out var state))
|
||||
continue;
|
||||
|
||||
var comp = _entityManager.AddComponent(entity, netId);
|
||||
var comp = _entityManager.AddComponent(entity, netId, meta);
|
||||
|
||||
if (_sawmill.Level <= LogLevel.Debug)
|
||||
_sawmill.Debug($" A component was removed: {comp.GetType()}");
|
||||
@@ -597,11 +594,11 @@ namespace Robust.Client.GameStates
|
||||
|
||||
foreach (var netEntity in createdEntities)
|
||||
{
|
||||
var createdEntity = _entityManager.GetEntity(netEntity);
|
||||
var (createdEntity, meta) = _entityManager.GetEntityData(netEntity);
|
||||
var compData = new Dictionary<ushort, ComponentState>();
|
||||
outputData.Add(netEntity, compData);
|
||||
|
||||
foreach (var (netId, component) in _entityManager.GetNetComponents(createdEntity))
|
||||
foreach (var (netId, component) in meta.NetComponents)
|
||||
{
|
||||
if (!component.NetSyncEnabled)
|
||||
continue;
|
||||
@@ -692,9 +689,9 @@ namespace Robust.Client.GameStates
|
||||
|
||||
var uid = _entities.CreateEntity(metaState.PrototypeId);
|
||||
_toCreate.Add(es.NetEntity, es);
|
||||
_toApply.Add(uid, (false, GameTick.Zero, es, null));
|
||||
|
||||
var newMeta = metas.GetComponent(uid);
|
||||
_toApply.Add(uid, (es.NetEntity, newMeta, false, GameTick.Zero, es, null));
|
||||
|
||||
|
||||
// Client creates a client-side net entity for the newly created entity.
|
||||
// We need to clear this mapping before assigning the real net id.
|
||||
@@ -712,6 +709,8 @@ namespace Robust.Client.GameStates
|
||||
var pending = _pendingReapplyNetStates.GetOrNew(owner);
|
||||
pending.Add(type);
|
||||
}
|
||||
|
||||
_entityManager.PendingNetEntityStates.Remove(es.NetEntity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -720,12 +719,13 @@ namespace Robust.Client.GameStates
|
||||
|
||||
foreach (var es in curSpan)
|
||||
{
|
||||
if (_toCreate.ContainsKey(es.NetEntity))
|
||||
continue;
|
||||
|
||||
var uid = _entityManager.GetEntity(es.NetEntity);
|
||||
|
||||
if (!metas.TryGetComponent(uid, out var meta) || _toCreate.ContainsKey(es.NetEntity))
|
||||
{
|
||||
if (!metas.TryGetComponent(uid, out var meta))
|
||||
continue;
|
||||
}
|
||||
|
||||
bool isEnteringPvs = (meta.Flags & MetaDataFlags.Detached) != 0;
|
||||
if (isEnteringPvs)
|
||||
@@ -739,7 +739,7 @@ namespace Robust.Client.GameStates
|
||||
continue;
|
||||
}
|
||||
|
||||
_toApply.Add(uid, (isEnteringPvs, meta.LastStateApplied, es, null));
|
||||
_toApply.Add(uid, (es.NetEntity, meta, isEnteringPvs, meta.LastStateApplied, es, null));
|
||||
meta.LastStateApplied = curState.ToSequence;
|
||||
}
|
||||
|
||||
@@ -753,29 +753,36 @@ namespace Robust.Client.GameStates
|
||||
{
|
||||
foreach (var es in nextState.EntityStates.Span)
|
||||
{
|
||||
if (!_entityManager.TryGetEntity(es.NetEntity, out var uid))
|
||||
if (!_entityManager.TryGetEntityData(es.NetEntity, out var uid, out var meta))
|
||||
continue;
|
||||
|
||||
DebugTools.Assert(metas.HasComponent(uid));
|
||||
|
||||
// Does the next state actually have any future information about this entity that could be used for interpolation?
|
||||
if (es.EntityLastModified != nextState.ToSequence)
|
||||
continue;
|
||||
|
||||
if (_toApply.TryGetValue(uid.Value, out var state))
|
||||
_toApply[uid.Value] = (state.EnteringPvs, state.LastApplied, state.curState, es);
|
||||
ref var state = ref CollectionsMarshal.GetValueRefOrAddDefault(_toApply, uid.Value, out var exists);
|
||||
|
||||
if (exists)
|
||||
state = (es.NetEntity, meta, state.EnteringPvs, state.LastApplied, state.curState, es);
|
||||
else
|
||||
_toApply[uid.Value] = (false, GameTick.Zero, null, es);
|
||||
state = (es.NetEntity, meta, false, GameTick.Zero, null, es);
|
||||
}
|
||||
}
|
||||
|
||||
// Check pending states and see if we need to force any entities to re-run component states.
|
||||
foreach (var uid in _pendingReapplyNetStates.Keys)
|
||||
{
|
||||
if (_toApply.ContainsKey(uid))
|
||||
// Original entity referencing the NetEntity may have been deleted.
|
||||
if (!metas.TryGetComponent(uid, out var meta))
|
||||
continue;
|
||||
|
||||
_toApply[uid] = (false, GameTick.Zero, null, null);
|
||||
// State already being re-applied so don't bulldoze it.
|
||||
ref var state = ref CollectionsMarshal.GetValueRefOrAddDefault(_toApply, uid, out var exists);
|
||||
|
||||
if (exists)
|
||||
continue;
|
||||
|
||||
state = (meta.NetEntity, meta, false, GameTick.Zero, null, null);
|
||||
}
|
||||
|
||||
var queuedBroadphaseUpdates = new List<(EntityUid, TransformComponent)>(enteringPvs);
|
||||
@@ -785,7 +792,7 @@ namespace Robust.Client.GameStates
|
||||
{
|
||||
foreach (var (entity, data) in _toApply)
|
||||
{
|
||||
HandleEntityState(entity, _entities.EventBus, data.curState,
|
||||
HandleEntityState(entity, data.NetEntity, data.Meta, _entities.EventBus, data.curState,
|
||||
data.nextState, data.LastApplied, curState.ToSequence, data.EnteringPvs);
|
||||
|
||||
if (!data.EnteringPvs)
|
||||
@@ -1125,18 +1132,16 @@ namespace Robust.Client.GameStates
|
||||
#endif
|
||||
}
|
||||
|
||||
private void HandleEntityState(EntityUid uid, IEventBus bus, EntityState? curState,
|
||||
private void HandleEntityState(EntityUid uid, NetEntity netEntity, MetaDataComponent meta, IEventBus bus, EntityState? curState,
|
||||
EntityState? nextState, GameTick lastApplied, GameTick toTick, bool enteringPvs)
|
||||
{
|
||||
_compStateWork.Clear();
|
||||
var meta = _entityManager.GetComponent<MetaDataComponent>(uid);
|
||||
var netEntity = meta.NetEntity;
|
||||
|
||||
// First remove any deleted components
|
||||
if (curState?.NetComponents != null)
|
||||
{
|
||||
RemQueue<Component> toRemove = new();
|
||||
foreach (var (id, comp) in _entities.GetNetComponents(uid))
|
||||
foreach (var (id, comp) in meta.NetComponents)
|
||||
{
|
||||
if (comp.NetSyncEnabled && !curState.NetComponents.Contains(id))
|
||||
toRemove.Add(comp);
|
||||
@@ -1144,7 +1149,7 @@ namespace Robust.Client.GameStates
|
||||
|
||||
foreach (var comp in toRemove)
|
||||
{
|
||||
_entities.RemoveComponent(uid, comp);
|
||||
_entities.RemoveComponent(uid, comp, meta);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1157,12 +1162,11 @@ namespace Robust.Client.GameStates
|
||||
// the entity. most notably, all entities will have been ejected from their containers.
|
||||
foreach (var (id, state) in _processor.GetLastServerStates(netEntity))
|
||||
{
|
||||
if (!_entityManager.TryGetComponent(uid, id, out var comp))
|
||||
if (!meta.NetComponents.TryGetValue(id, out var comp))
|
||||
{
|
||||
comp = _compFactory.GetComponent(id);
|
||||
var newComp = (Component)comp;
|
||||
newComp.Owner = uid;
|
||||
_entityManager.AddComponent(uid, newComp, true);
|
||||
comp = (Component) _compFactory.GetComponent(id);
|
||||
comp.Owner = uid;
|
||||
_entityManager.AddComponent(uid, comp, true, metadata: meta);
|
||||
}
|
||||
|
||||
_compStateWork[id] = (comp, state, null);
|
||||
@@ -1172,12 +1176,11 @@ namespace Robust.Client.GameStates
|
||||
{
|
||||
foreach (var compChange in curState.ComponentChanges.Span)
|
||||
{
|
||||
if (!_entityManager.TryGetComponent(uid, compChange.NetID, out var comp))
|
||||
if (!meta.NetComponents.TryGetValue(compChange.NetID, out var comp))
|
||||
{
|
||||
comp = _compFactory.GetComponent(compChange.NetID);
|
||||
var newComp = (Component)comp;
|
||||
newComp.Owner = uid;
|
||||
_entityManager.AddComponent(uid, newComp, true);
|
||||
comp = (Component) _compFactory.GetComponent(compChange.NetID);
|
||||
comp.Owner = uid;
|
||||
_entityManager.AddComponent(uid, comp, true, metadata:meta);
|
||||
}
|
||||
else if (compChange.LastModifiedTick <= lastApplied && lastApplied != GameTick.Zero)
|
||||
continue;
|
||||
@@ -1193,17 +1196,20 @@ namespace Robust.Client.GameStates
|
||||
if (compState.LastModifiedTick != toTick + 1)
|
||||
continue;
|
||||
|
||||
if (!_entityManager.TryGetComponent(uid, compState.NetID, out var comp))
|
||||
if (!meta.NetComponents.TryGetValue(compState.NetID, out var comp))
|
||||
{
|
||||
// The component can be null here due to interp, because the NEXT state will have a new
|
||||
// component, but the component does not yet exist.
|
||||
continue;
|
||||
}
|
||||
|
||||
if (_compStateWork.TryGetValue(compState.NetID, out var state))
|
||||
_compStateWork[compState.NetID] = (comp, state.curState, compState.State);
|
||||
ref var state =
|
||||
ref CollectionsMarshal.GetValueRefOrAddDefault(_compStateWork, compState.NetID, out var exists);
|
||||
|
||||
if (exists)
|
||||
state = (comp, state.curState, compState.State);
|
||||
else
|
||||
_compStateWork[compState.NetID] = (comp, null, compState.State);
|
||||
state = (comp, null, compState.State);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1220,14 +1226,19 @@ namespace Robust.Client.GameStates
|
||||
if (netId == null)
|
||||
continue;
|
||||
|
||||
if (_compStateWork.ContainsKey(netId.Value) ||
|
||||
!_entityManager.TryGetComponent(uid, type, out var comp) ||
|
||||
if (!meta.NetComponents.TryGetValue(netId.Value, out var comp) ||
|
||||
!lastState.TryGetValue(netId.Value, out var lastCompState))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
_compStateWork[netId.Value] = (comp, lastCompState, null);
|
||||
ref var compState =
|
||||
ref CollectionsMarshal.GetValueRefOrAddDefault(_compStateWork, netId.Value, out var exists);
|
||||
|
||||
if (exists)
|
||||
continue;
|
||||
|
||||
compState = (comp, lastCompState, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1241,10 +1252,10 @@ namespace Robust.Client.GameStates
|
||||
catch (Exception e)
|
||||
{
|
||||
#if EXCEPTION_TOLERANCE
|
||||
_sawmill.Error($"Failed to apply comp state: entity={comp.Owner}, comp={comp.GetType()}");
|
||||
_runtimeLog.LogException(e, $"{nameof(ClientGameStateManager)}.{nameof(HandleEntityState)}");
|
||||
_sawmill.Error($"Failed to apply comp state: entity={_entities.ToPrettyString(uid)}, comp={comp.GetType()}");
|
||||
_runtimeLog.LogException(e, $"{nameof(ClientGameStateManager)}.{nameof(HandleEntityState)}");
|
||||
#else
|
||||
_sawmill.Error($"Failed to apply comp state: entity={uid}, comp={comp.GetType()}");
|
||||
_sawmill.Error($"Failed to apply comp state: entity={_entities.ToPrettyString(uid)}, comp={comp.GetType()}");
|
||||
throw;
|
||||
#endif
|
||||
}
|
||||
@@ -1392,12 +1403,11 @@ namespace Robust.Client.GameStates
|
||||
|
||||
foreach (var (id, state) in lastState)
|
||||
{
|
||||
if (!_entityManager.TryGetComponent(uid, id, out var comp))
|
||||
if (!meta.NetComponents.TryGetValue(id, out var comp))
|
||||
{
|
||||
comp = _compFactory.GetComponent(id);
|
||||
var newComp = (Component)comp;
|
||||
newComp.Owner = uid;
|
||||
_entityManager.AddComponent(uid, newComp, true);
|
||||
comp = (Component) _compFactory.GetComponent(id);
|
||||
comp.Owner = uid;
|
||||
_entityManager.AddComponent(uid, comp, true, meta);
|
||||
}
|
||||
|
||||
var handleState = new ComponentHandleState(state, null);
|
||||
@@ -1406,7 +1416,7 @@ namespace Robust.Client.GameStates
|
||||
|
||||
// ensure we don't have any extra components
|
||||
RemQueue<Component> toRemove = new();
|
||||
foreach (var (id, comp) in _entities.GetNetComponents(uid))
|
||||
foreach (var (id, comp) in meta.NetComponents)
|
||||
{
|
||||
if (comp.NetSyncEnabled && !lastState.ContainsKey(id))
|
||||
toRemove.Add(comp);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.InteropServices;
|
||||
using Robust.Client.Timing;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameStates;
|
||||
@@ -361,9 +362,11 @@ namespace Robust.Client.GameStates
|
||||
|
||||
foreach (var (netId, implicitCompState) in implicitEntState)
|
||||
{
|
||||
if (!fullRep.TryGetValue(netId, out var serverState))
|
||||
ref var serverState = ref CollectionsMarshal.GetValueRefOrAddDefault(fullRep, netId, out var exists);
|
||||
|
||||
if (!exists)
|
||||
{
|
||||
fullRep.Add(netId, implicitCompState);
|
||||
serverState = implicitCompState;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -379,7 +382,7 @@ namespace Robust.Client.GameStates
|
||||
}
|
||||
|
||||
serverDelta.ApplyToFullState(implicitCompState);
|
||||
fullRep[netId] = implicitCompState;
|
||||
serverState = implicitCompState;
|
||||
DebugTools.Assert(implicitCompState is IComponentDeltaState d && d.FullState);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ using System.Numerics;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Map;
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
namespace Robust.Client.Graphics
|
||||
using Robust.Shared.Graphics;
|
||||
|
||||
namespace Robust.Client.Graphics
|
||||
{
|
||||
/// <summary>
|
||||
/// A fixed eye is an eye which is fixed to one point, its position.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Numerics;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using OpenToolkit.Graphics.OpenGL4;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Map;
|
||||
|
||||
@@ -9,6 +9,7 @@ using Robust.Client.ResourceManagement;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Shared;
|
||||
using Robust.Shared.Enums;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Profiling;
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using OpenToolkit.Graphics.OpenGL4;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Utility;
|
||||
using ES20 = OpenToolkit.Graphics.ES20;
|
||||
|
||||
@@ -16,8 +16,10 @@ using OGLTextureWrapMode = OpenToolkit.Graphics.OpenGL.TextureWrapMode;
|
||||
using TKStencilOp = OpenToolkit.Graphics.OpenGL4.StencilOp;
|
||||
using Robust.Shared.Physics;
|
||||
using Robust.Client.ComponentTrees;
|
||||
using Robust.Shared.Graphics;
|
||||
using static Robust.Shared.GameObjects.OccluderComponent;
|
||||
using Robust.Shared.Utility;
|
||||
using TextureWrapMode = Robust.Shared.Graphics.TextureWrapMode;
|
||||
using Vector4 = Robust.Shared.Maths.Vector4;
|
||||
|
||||
namespace Robust.Client.Graphics.Clyde
|
||||
|
||||
@@ -5,6 +5,7 @@ using Robust.Client.GameObjects;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Maths;
|
||||
using OpenToolkit.Graphics.OpenGL4;
|
||||
using Robust.Shared.Graphics;
|
||||
|
||||
namespace Robust.Client.Graphics.Clyde
|
||||
{
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using OpenToolkit.Graphics.OpenGL4;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
@@ -7,6 +7,7 @@ using System.Runtime.InteropServices;
|
||||
using OpenToolkit.Graphics.OpenGL4;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Utility;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Utility;
|
||||
using TKStencilOp = OpenToolkit.Graphics.OpenGL4.StencilOp;
|
||||
|
||||
@@ -6,6 +6,7 @@ using System.Numerics;
|
||||
using System.Text;
|
||||
using OpenToolkit.Graphics.OpenGL4;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Utility;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
@@ -14,6 +14,7 @@ using System.Runtime.CompilerServices;
|
||||
using System.Runtime.Intrinsics;
|
||||
using System.Runtime.Intrinsics.X86;
|
||||
using System.Threading.Tasks;
|
||||
using Robust.Shared.Graphics;
|
||||
|
||||
namespace Robust.Client.Graphics.Clyde;
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@ using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using OpenToolkit.Graphics.OpenGL4;
|
||||
using Robust.Client.Utility;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Utility;
|
||||
using SixLabors.ImageSharp;
|
||||
@@ -17,6 +19,7 @@ using OGLTextureWrapMode = OpenToolkit.Graphics.OpenGL.TextureWrapMode;
|
||||
using PIF = OpenToolkit.Graphics.OpenGL4.PixelInternalFormat;
|
||||
using PF = OpenToolkit.Graphics.OpenGL4.PixelFormat;
|
||||
using PT = OpenToolkit.Graphics.OpenGL4.PixelType;
|
||||
using TextureWrapMode = Robust.Shared.Graphics.TextureWrapMode;
|
||||
|
||||
namespace Robust.Client.Graphics.Clyde
|
||||
{
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Shared.Enums;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ using Robust.Client.UserInterface;
|
||||
using Robust.Shared;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Log;
|
||||
@@ -21,6 +22,7 @@ using Robust.Shared.Timing;
|
||||
using SixLabors.ImageSharp;
|
||||
using Color = Robust.Shared.Maths.Color;
|
||||
using DependencyAttribute = Robust.Shared.IoC.DependencyAttribute;
|
||||
using TextureWrapMode = Robust.Shared.Graphics.TextureWrapMode;
|
||||
|
||||
namespace Robust.Client.Graphics.Clyde
|
||||
{
|
||||
|
||||
@@ -8,6 +8,7 @@ using Robust.Client.Audio;
|
||||
using Robust.Client.Input;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
namespace Robust.Client.Graphics
|
||||
{
|
||||
internal enum ClydeStockTexture : byte
|
||||
{
|
||||
White,
|
||||
Black,
|
||||
Transparent
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ using System.Diagnostics;
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Maths;
|
||||
|
||||
namespace Robust.Client.Graphics
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Numerics;
|
||||
using System.Text;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Maths;
|
||||
|
||||
namespace Robust.Client.Graphics
|
||||
@@ -154,7 +155,7 @@ namespace Robust.Client.Graphics
|
||||
Vector2 scale,
|
||||
Angle? worldRot,
|
||||
Angle eyeRotation = default,
|
||||
Direction? overrideDirection = null,
|
||||
Shared.Maths.Direction? overrideDirection = null,
|
||||
SpriteComponent? sprite = null,
|
||||
TransformComponent? xform = null,
|
||||
SharedTransformSystem? xformSystem = null);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Numerics;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Maths;
|
||||
|
||||
namespace Robust.Client.Graphics
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Numerics;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.IO;
|
||||
using System.Text;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.Utility;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Utility;
|
||||
using SharpFont;
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Numerics;
|
||||
using System.Threading.Tasks;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Maths;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using Robust.Client.Input;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Numerics;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
|
||||
|
||||
@@ -38,8 +38,7 @@ namespace Robust.Client.Graphics
|
||||
event Action<WindowDestroyedEventArgs> Destroyed;
|
||||
|
||||
/// <summary>
|
||||
/// Raised when the window has been definitively closed.
|
||||
/// This means the window must not be used anymore (it is disposed).
|
||||
/// Raised when the window has been resized.
|
||||
/// </summary>
|
||||
event Action<WindowResizedEventArgs> Resized;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Maths;
|
||||
|
||||
namespace Robust.Client.Graphics
|
||||
{
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Robust.Shared.Graphics;
|
||||
|
||||
namespace Robust.Client.Graphics
|
||||
{
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace Robust.Client.Graphics
|
||||
Vector2 scale,
|
||||
Angle? worldRot,
|
||||
Angle eyeRotation = default,
|
||||
Direction? overrideDirection = null,
|
||||
Shared.Maths.Direction? overrideDirection = null,
|
||||
SpriteComponent? sprite = null,
|
||||
TransformComponent? xform = null,
|
||||
SharedTransformSystem? xformSystem = null);
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
using Robust.Shared.Graphics;
|
||||
|
||||
namespace Robust.Client.Graphics
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
namespace Robust.Client.Graphics
|
||||
using Robust.Shared.Graphics.RSI;
|
||||
|
||||
namespace Robust.Client.Graphics
|
||||
{
|
||||
public interface IRsiStateLike : IDirectionalTextureProvider
|
||||
{
|
||||
RSI.State.DirectionType Directions { get; }
|
||||
RsiDirectionType RsiDirections { get; }
|
||||
bool IsAnimated { get; }
|
||||
int AnimationFrameCount { get; }
|
||||
|
||||
float GetDelay(int frame);
|
||||
Texture GetFrame(RSI.State.Direction dir, int frame);
|
||||
Texture GetFrame(RsiDirection dir, int frame);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using JetBrains.Annotations;
|
||||
using Robust.Shared.Timing;
|
||||
using Robust.Shared.Enums;
|
||||
using System;
|
||||
using Robust.Shared.Graphics;
|
||||
|
||||
namespace Robust.Client.Graphics
|
||||
{
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Robust.Client.Utility;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Graphics.RSI;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
@@ -25,7 +27,7 @@ namespace Robust.Client.Graphics
|
||||
// 2D array for the texture to use for each animation frame at each direction.
|
||||
public readonly Texture[][] Icons;
|
||||
|
||||
internal State(Vector2i size, RSI rsi, StateId stateId, DirectionType direction, float[] delays, Texture[][] icons)
|
||||
internal State(Vector2i size, RSI rsi, StateId stateId, RsiDirectionType rsiDirection, float[] delays, Texture[][] icons)
|
||||
{
|
||||
DebugTools.Assert(size.X > 0);
|
||||
DebugTools.Assert(size.Y > 0);
|
||||
@@ -34,7 +36,7 @@ namespace Robust.Client.Graphics
|
||||
Size = size;
|
||||
RSI = rsi;
|
||||
StateId = stateId;
|
||||
Directions = direction;
|
||||
RsiDirections = rsiDirection;
|
||||
Delays = delays;
|
||||
TotalDelay = delays.Sum();
|
||||
Icons = icons;
|
||||
@@ -63,7 +65,7 @@ namespace Robust.Client.Graphics
|
||||
/// <summary>
|
||||
/// How many directions this state has.
|
||||
/// </summary>
|
||||
public DirectionType Directions { get; }
|
||||
public RsiDirectionType RsiDirections { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The first frame of the "south" direction.
|
||||
@@ -90,14 +92,14 @@ namespace Robust.Client.Graphics
|
||||
|
||||
int IRsiStateLike.AnimationFrameCount => DelayCount;
|
||||
|
||||
public Texture GetFrame(Direction direction, int frame)
|
||||
public Texture GetFrame(RsiDirection rsiDirection, int frame)
|
||||
{
|
||||
return Icons[(int) direction][frame];
|
||||
return Icons[(int) rsiDirection][frame];
|
||||
}
|
||||
|
||||
public Texture[] GetFrames(Direction direction)
|
||||
public Texture[] GetFrames(RsiDirection rsiDirection)
|
||||
{
|
||||
return Icons[(int) direction];
|
||||
return Icons[(int) rsiDirection];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -124,52 +126,12 @@ namespace Robust.Client.Graphics
|
||||
|
||||
Texture IDirectionalTextureProvider.TextureFor(Shared.Maths.Direction dir)
|
||||
{
|
||||
if (Directions == DirectionType.Dir1)
|
||||
if (RsiDirections == RsiDirectionType.Dir1)
|
||||
{
|
||||
return Frame0;
|
||||
}
|
||||
|
||||
return GetFrame(dir.Convert(Directions), 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies which types of directions an RSI state has.
|
||||
/// </summary>
|
||||
public enum DirectionType : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// A single direction, namely South.
|
||||
/// </summary>
|
||||
Dir1,
|
||||
|
||||
/// <summary>
|
||||
/// 4 cardinal directions.
|
||||
/// </summary>
|
||||
Dir4,
|
||||
|
||||
/// <summary>
|
||||
/// 4 cardinal + 4 diagonal directions.
|
||||
/// </summary>
|
||||
Dir8,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies a direction in an RSI state.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Value of the enum here matches the index used to store it in the icons array. If this ever changes, then
|
||||
/// <see cref="GameObjects.SpriteComponent.Layer._rsiDirectionMatrices"/> also needs to be updated.
|
||||
/// </remarks>
|
||||
public enum Direction : byte
|
||||
{
|
||||
South = 0,
|
||||
North = 1,
|
||||
East = 2,
|
||||
West = 3,
|
||||
SouthEast = 4,
|
||||
SouthWest = 5,
|
||||
NorthEast = 6,
|
||||
NorthWest = 7,
|
||||
return GetFrame(dir.Convert(RsiDirections), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Numerics;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
@@ -1,233 +1,112 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Graphics.RSI;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Utility;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
using YamlDotNet.RepresentationModel;
|
||||
using Color = Robust.Shared.Maths.Color;
|
||||
|
||||
namespace Robust.Client.Graphics
|
||||
namespace Robust.Client.Graphics;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a texture used for drawing things.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public abstract class Texture : IRsiStateLike
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains a texture used for drawing things.
|
||||
/// The width of the texture, in pixels.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public abstract class Texture : IRsiStateLike
|
||||
public int Width => Size.X;
|
||||
|
||||
/// <summary>
|
||||
/// The height of the texture, in pixels.
|
||||
/// </summary>
|
||||
public int Height => Size.Y;
|
||||
|
||||
/// <summary>
|
||||
/// The size of the texture, in pixels.
|
||||
/// </summary>
|
||||
public Vector2i Size { get; /*protected set;*/ }
|
||||
|
||||
public Color this[int x, int y] => this.GetPixel(x, y);
|
||||
|
||||
protected Texture(Vector2i size)
|
||||
{
|
||||
/// <summary>
|
||||
/// The width of the texture, in pixels.
|
||||
/// </summary>
|
||||
public int Width => Size.X;
|
||||
Size = size;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The height of the texture, in pixels.
|
||||
/// </summary>
|
||||
public int Height => Size.Y;
|
||||
Texture IDirectionalTextureProvider.Default => this;
|
||||
|
||||
/// <summary>
|
||||
/// The size of the texture, in pixels.
|
||||
/// </summary>
|
||||
public Vector2i Size { get; /*protected set;*/ }
|
||||
Texture IDirectionalTextureProvider.TextureFor(Direction dir)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
public Color this[int x, int y] => this.GetPixel(x, y);
|
||||
RsiDirectionType IRsiStateLike.RsiDirections => RsiDirectionType.Dir1;
|
||||
bool IRsiStateLike.IsAnimated => false;
|
||||
int IRsiStateLike.AnimationFrameCount => 0;
|
||||
|
||||
protected Texture(Vector2i size)
|
||||
{
|
||||
Size = size;
|
||||
}
|
||||
float IRsiStateLike.GetDelay(int frame)
|
||||
{
|
||||
if (frame != 0)
|
||||
throw new IndexOutOfRangeException();
|
||||
|
||||
public static Texture Transparent =>
|
||||
IoCManager.Resolve<IClydeInternal>().GetStockTexture(ClydeStockTexture.Transparent);
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static Texture White =>
|
||||
IoCManager.Resolve<IClydeInternal>().GetStockTexture(ClydeStockTexture.White);
|
||||
Texture IRsiStateLike.GetFrame(RsiDirection dir, int frame)
|
||||
{
|
||||
if (frame != 0)
|
||||
throw new IndexOutOfRangeException();
|
||||
|
||||
public static Texture Black =>
|
||||
IoCManager.Resolve<IClydeInternal>().GetStockTexture(ClydeStockTexture.Black);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads a new texture an existing image.
|
||||
/// </summary>
|
||||
/// <param name="image">The image to load.</param>
|
||||
/// <param name="name">The "name" of this texture. This can be referred to later to aid debugging.</param>
|
||||
/// <param name="loadParameters">
|
||||
/// Parameters that influence the loading of textures.
|
||||
/// Defaults to <see cref="TextureLoadParameters.Default"/> if <c>null</c>.
|
||||
/// </param>
|
||||
/// <typeparam name="T">The type of pixels of the image. At the moment, images must be <see cref="Rgba32"/>.</typeparam>
|
||||
public static Texture LoadFromImage<T>(Image<T> image, string? name = null,
|
||||
TextureLoadParameters? loadParameters = null) where T : unmanaged, IPixel<T>
|
||||
{
|
||||
var manager = IoCManager.Resolve<IClyde>();
|
||||
return manager.LoadTextureFromImage(image, name, loadParameters);
|
||||
}
|
||||
public abstract Color GetPixel(int x, int y);
|
||||
|
||||
/// <summary>
|
||||
/// Loads an image from a stream containing PNG data.
|
||||
/// </summary>
|
||||
/// <param name="stream">The stream to load the image from.</param>
|
||||
/// <param name="name">The "name" of this texture. This can be referred to later to aid debugging.</param>
|
||||
/// <param name="loadParameters">
|
||||
/// Parameters that influence the loading of textures.
|
||||
/// Defaults to <see cref="TextureLoadParameters.Default"/> if <c>null</c>.
|
||||
/// </param>
|
||||
public static Texture LoadFromPNGStream(Stream stream, string? name = null,
|
||||
TextureLoadParameters? loadParameters = null)
|
||||
{
|
||||
var manager = IoCManager.Resolve<IClyde>();
|
||||
return manager.LoadTextureFromPNGStream(stream, name, loadParameters);
|
||||
}
|
||||
public static Texture Transparent =>
|
||||
IoCManager.Resolve<IClydeInternal>().GetStockTexture(ClydeStockTexture.Transparent);
|
||||
|
||||
Texture IDirectionalTextureProvider.Default => this;
|
||||
public static Texture White =>
|
||||
IoCManager.Resolve<IClydeInternal>().GetStockTexture(ClydeStockTexture.White);
|
||||
|
||||
Texture IDirectionalTextureProvider.TextureFor(Direction dir)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
public static Texture Black =>
|
||||
IoCManager.Resolve<IClydeInternal>().GetStockTexture(ClydeStockTexture.Black);
|
||||
|
||||
RSI.State.DirectionType IRsiStateLike.Directions => RSI.State.DirectionType.Dir1;
|
||||
bool IRsiStateLike.IsAnimated => false;
|
||||
int IRsiStateLike.AnimationFrameCount => 0;
|
||||
|
||||
float IRsiStateLike.GetDelay(int frame)
|
||||
{
|
||||
if (frame != 0)
|
||||
throw new IndexOutOfRangeException();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Texture IRsiStateLike.GetFrame(RSI.State.Direction dir, int frame)
|
||||
{
|
||||
if (frame != 0)
|
||||
throw new IndexOutOfRangeException();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public abstract Color GetPixel(int x, int y);
|
||||
/// <summary>
|
||||
/// Loads a new texture an existing image.
|
||||
/// </summary>
|
||||
/// <param name="image">The image to load.</param>
|
||||
/// <param name="name">The "name" of this texture. This can be referred to later to aid debugging.</param>
|
||||
/// <param name="loadParameters">
|
||||
/// Parameters that influence the loading of textures.
|
||||
/// Defaults to <see cref="Robust.Client.Graphics.TextureLoadParameters.Default"/> if <c>null</c>.
|
||||
/// </param>
|
||||
/// <typeparam name="T">The type of pixels of the image. At the moment, images must be <see cref="Rgba32"/>.</typeparam>
|
||||
public static Texture LoadFromImage<T>(Image<T> image, string? name = null,
|
||||
TextureLoadParameters? loadParameters = null) where T : unmanaged, IPixel<T>
|
||||
{
|
||||
var manager = IoCManager.Resolve<IClyde>();
|
||||
return manager.LoadTextureFromImage(image, name, loadParameters);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Flags for loading of textures.
|
||||
/// Loads an image from a stream containing PNG data.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public struct TextureLoadParameters
|
||||
/// <param name="stream">The stream to load the image from.</param>
|
||||
/// <param name="name">The "name" of this texture. This can be referred to later to aid debugging.</param>
|
||||
/// <param name="loadParameters">
|
||||
/// Parameters that influence the loading of textures.
|
||||
/// Defaults to <see cref="Robust.Client.Graphics.TextureLoadParameters.Default"/> if <c>null</c>.
|
||||
/// </param>
|
||||
public static Texture LoadFromPNGStream(Stream stream, string? name = null,
|
||||
TextureLoadParameters? loadParameters = null)
|
||||
{
|
||||
/// <summary>
|
||||
/// The default sampling parameters for the texture.
|
||||
/// </summary>
|
||||
public TextureSampleParameters SampleParameters { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If true, the image data will be treated as sRGB.
|
||||
/// </summary>
|
||||
public bool Srgb { get; set; }
|
||||
|
||||
public static TextureLoadParameters FromYaml(YamlMappingNode yaml)
|
||||
{
|
||||
var loadParams = Default;
|
||||
if (yaml.TryGetNode("sample", out YamlMappingNode? sampleNode))
|
||||
{
|
||||
loadParams.SampleParameters = TextureSampleParameters.FromYaml(sampleNode);
|
||||
}
|
||||
|
||||
if (yaml.TryGetNode("srgb", out var srgb))
|
||||
{
|
||||
loadParams.Srgb = srgb.AsBool();
|
||||
}
|
||||
|
||||
return loadParams;
|
||||
}
|
||||
|
||||
public static readonly TextureLoadParameters Default = new()
|
||||
{
|
||||
SampleParameters = TextureSampleParameters.Default,
|
||||
Srgb = true
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sample flags for textures.
|
||||
/// These are separate from <see cref="TextureLoadParameters"/>,
|
||||
/// because it is possible to create "proxies" to existing textures
|
||||
/// with different sampling parameters than the base texture.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public struct TextureSampleParameters
|
||||
{
|
||||
// NOTE: If somebody is gonna add support for 3D/1D textures, change this doc comment.
|
||||
// See the note on this page for why: https://www.khronos.org/opengl/wiki/Sampler_Object#Filtering
|
||||
/// <summary>
|
||||
/// If true, use bi-linear texture filtering if the texture cannot be rendered 1:1
|
||||
/// </summary>
|
||||
public bool Filter { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Controls how to wrap the texture if texture coordinates outside 0-1 are accessed.
|
||||
/// </summary>
|
||||
public TextureWrapMode WrapMode { get; set; }
|
||||
|
||||
public static TextureSampleParameters FromYaml(YamlMappingNode node)
|
||||
{
|
||||
var wrap = TextureWrapMode.None;
|
||||
var filter = false;
|
||||
|
||||
if (node.TryGetNode("filter", out var filterNode))
|
||||
{
|
||||
filter = filterNode.AsBool();
|
||||
}
|
||||
|
||||
if (node.TryGetNode("wrap", out var wrapNode))
|
||||
{
|
||||
switch (wrapNode.AsString())
|
||||
{
|
||||
case "none":
|
||||
wrap = TextureWrapMode.None;
|
||||
break;
|
||||
case "repeat":
|
||||
wrap = TextureWrapMode.Repeat;
|
||||
break;
|
||||
case "mirrored_repeat":
|
||||
wrap = TextureWrapMode.MirroredRepeat;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException("Not a valid wrap mode.");
|
||||
}
|
||||
}
|
||||
|
||||
return new TextureSampleParameters {Filter = filter, WrapMode = wrap};
|
||||
}
|
||||
|
||||
public static readonly TextureSampleParameters Default = new()
|
||||
{
|
||||
Filter = false,
|
||||
WrapMode = TextureWrapMode.None
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Controls behavior when reading texture coordinates outside 0-1, which usually wraps the texture somehow.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public enum TextureWrapMode : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// Do not wrap, instead clamp to edge.
|
||||
/// </summary>
|
||||
None = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Repeat the texture.
|
||||
/// </summary>
|
||||
Repeat,
|
||||
|
||||
/// <summary>
|
||||
/// Repeat the texture mirrored.
|
||||
/// </summary>
|
||||
MirroredRepeat,
|
||||
var manager = IoCManager.Resolve<IClyde>();
|
||||
return manager.LoadTextureFromPNGStream(stream, name, loadParameters);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ using Robust.Client.ResourceManagement;
|
||||
using Robust.Client.Utility;
|
||||
using Robust.Shared.Console;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Map;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ using Robust.Shared.Enums;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
using Direction = Robust.Shared.Maths.Direction;
|
||||
|
||||
namespace Robust.Client.Map;
|
||||
|
||||
@@ -61,11 +62,16 @@ public sealed class TileEdgeOverlay : Overlay
|
||||
|
||||
var neighborIndices = new Vector2i(tileRef.GridIndices.X + x, tileRef.GridIndices.Y + y);
|
||||
var neighborTile = grid.GetTileRef(neighborIndices);
|
||||
var neighborDef = _tileDefManager[neighborTile.Tile.TypeId];
|
||||
|
||||
// If it's the same tile then no edge to be drawn.
|
||||
if (tileRef.Tile.TypeId == neighborTile.Tile.TypeId)
|
||||
continue;
|
||||
|
||||
// Don't draw if the the neighbor tile edges should draw over us (or if we have the same priority)
|
||||
if (neighborDef.EdgeSprites.Count != 0 && neighborDef.EdgeSpritePriority >= tileDef.EdgeSpritePriority)
|
||||
continue;
|
||||
|
||||
var direction = new Vector2i(x, y).AsDirection();
|
||||
|
||||
// No edge tile
|
||||
|
||||
@@ -28,10 +28,9 @@ public sealed partial class PhysicsSystem
|
||||
|
||||
private void UpdateIsPredicted()
|
||||
{
|
||||
var query = GetEntityQuery<PhysicsComponent>();
|
||||
foreach (var uid in _toUpdate)
|
||||
{
|
||||
if (!query.TryGetComponent(uid, out var physics))
|
||||
if (!PhysicsQuery.TryGetComponent(uid, out var physics))
|
||||
continue;
|
||||
|
||||
var ev = new UpdateIsPredictedEvent(uid);
|
||||
|
||||
@@ -16,7 +16,6 @@ namespace Robust.Client.Physics
|
||||
{
|
||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||
[Dependency] private readonly IPlayerManager _player = default!;
|
||||
[Dependency] private readonly SharedBroadphaseSystem _broadphase = default!;
|
||||
|
||||
public override void Update(float frameTime)
|
||||
|
||||
@@ -8,6 +8,7 @@ using Robust.Client.Player;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Shared.Enums;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Input;
|
||||
using Robust.Shared.Input.Binding;
|
||||
using Robust.Shared.IoC;
|
||||
@@ -20,6 +21,7 @@ using Robust.Shared.Reflection;
|
||||
using Robust.Shared.Timing;
|
||||
using Robust.Shared.Utility;
|
||||
using Robust.Shared.Log;
|
||||
using Direction = Robust.Shared.Maths.Direction;
|
||||
|
||||
namespace Robust.Client.Placement
|
||||
{
|
||||
|
||||
@@ -7,6 +7,7 @@ using Robust.Client.Graphics;
|
||||
using Robust.Client.Input;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Map;
|
||||
|
||||
@@ -73,7 +73,6 @@ namespace Robust.Client.Player
|
||||
ControlledEntity = entity;
|
||||
InternalSession.AttachedEntity = entity;
|
||||
|
||||
|
||||
if (!entMan.TryGetComponent<EyeComponent?>(entity, out var eye))
|
||||
{
|
||||
eye = entMan.AddComponent<EyeComponent>(entity);
|
||||
@@ -84,7 +83,6 @@ namespace Robust.Client.Player
|
||||
}
|
||||
eye.NetSyncEnabled = false;
|
||||
}
|
||||
eye.Current = true;
|
||||
|
||||
EntityAttached?.Invoke(new EntityAttachedEventArgs(entity));
|
||||
|
||||
@@ -101,12 +99,6 @@ namespace Robust.Client.Player
|
||||
{
|
||||
var entMan = IoCManager.Resolve<IEntityManager>();
|
||||
var previous = ControlledEntity;
|
||||
if (entMan.TryGetComponent(previous, out MetaDataComponent? metaData) &&
|
||||
metaData.EntityInitialized &&
|
||||
!metaData.EntityDeleted)
|
||||
{
|
||||
entMan.GetComponent<EyeComponent>(previous.Value).Current = false;
|
||||
}
|
||||
|
||||
ControlledEntity = null;
|
||||
InternalSession.AttachedEntity = null;
|
||||
|
||||
@@ -53,6 +53,8 @@ namespace Robust.Client.Player
|
||||
/// <inheritdoc />
|
||||
public int MaxPlayers => _client.GameInfo?.ServerMaxPlayers ?? 0;
|
||||
|
||||
public ICommonSession? LocalSession => LocalPlayer?.Session;
|
||||
|
||||
/// <inheritdoc />
|
||||
[ViewVariables]
|
||||
public LocalPlayer? LocalPlayer
|
||||
|
||||
@@ -3,6 +3,8 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Utility;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Graphics.RSI;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Resources;
|
||||
@@ -116,9 +118,9 @@ namespace Robust.Client.ResourceManagement
|
||||
|
||||
var dirType = stateObject.DirCount switch
|
||||
{
|
||||
1 => RSI.State.DirectionType.Dir1,
|
||||
4 => RSI.State.DirectionType.Dir4,
|
||||
8 => RSI.State.DirectionType.Dir8,
|
||||
1 => RsiDirectionType.Dir1,
|
||||
4 => RsiDirectionType.Dir4,
|
||||
8 => RsiDirectionType.Dir8,
|
||||
_ => throw new InvalidOperationException()
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Maths;
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="2.1.2" Condition="'$(UseSystemSqlite)' != 'True'" PrivateAssets="compile" />
|
||||
<PackageReference Include="SpaceWizards.NFluidsynth" Version="0.1.1" PrivateAssets="compile" />
|
||||
<PackageReference Include="NVorbis" Version="0.10.1" PrivateAssets="compile" />
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="2.1.3" />
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="2.1.7" />
|
||||
<PackageReference Include="OpenToolkit.Graphics" Version="4.0.0-pre9.1" PrivateAssets="compile" />
|
||||
<PackageReference Include="OpenTK.OpenAL" Version="4.7.5" PrivateAssets="compile" />
|
||||
<PackageReference Include="SpaceWizards.SharpFont" Version="1.0.1" PrivateAssets="compile" />
|
||||
|
||||
@@ -10,6 +10,7 @@ using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Shared.Enums;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Utility;
|
||||
using static Robust.Client.UserInterface.Controls.BaseButton;
|
||||
using static Robust.Client.UserInterface.Controls.LineEdit;
|
||||
@@ -199,7 +200,7 @@ public sealed class EntitySpawningUIController : UIController
|
||||
continue;
|
||||
}
|
||||
|
||||
if (prototype.NoSpawn)
|
||||
if (prototype.HideSpawnMenu)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ using Robust.Client.ResourceManagement;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Shared.Enums;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Map;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Utility;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Graphics.RSI;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Timing;
|
||||
using Robust.Shared.Utility;
|
||||
@@ -21,7 +23,7 @@ namespace Robust.Client.UserInterface.Controls
|
||||
/// </summary>
|
||||
public TextureRect DisplayRect { get; }
|
||||
|
||||
public RSI.State.Direction RsiDirection { get; } = RSI.State.Direction.South;
|
||||
public RsiDirection RsiDirection { get; } = RsiDirection.South;
|
||||
|
||||
public AnimatedTextureRect()
|
||||
{
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Numerics;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Input;
|
||||
using Robust.Shared.Maths;
|
||||
using Timer = Robust.Shared.Timing.Timer;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Maths;
|
||||
|
||||
namespace Robust.Client.UserInterface.Controls
|
||||
|
||||
@@ -98,6 +98,11 @@ namespace Robust.Client.UserInterface.Controls
|
||||
OnTextChanged?.Invoke(new LineEditEventArgs(this, _text));
|
||||
}
|
||||
|
||||
public void ForceSubmitText()
|
||||
{
|
||||
OnTextEntered?.Invoke(new LineEditEventArgs(this, _text));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The text
|
||||
/// </summary>
|
||||
@@ -607,7 +612,7 @@ namespace Robust.Client.UserInterface.Controls
|
||||
{
|
||||
if (Editable)
|
||||
{
|
||||
OnTextEntered?.Invoke(new LineEditEventArgs(this, _text));
|
||||
ForceSubmitText();
|
||||
}
|
||||
|
||||
args.Handle();
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Maths;
|
||||
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Maths;
|
||||
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||
|
||||
|
||||
@@ -50,13 +50,13 @@ namespace Robust.Client.UserInterface.Controls
|
||||
Action<Range> ev = _scrollValueChanged;
|
||||
_hScrollBar = new HScrollBar
|
||||
{
|
||||
Visible = false,
|
||||
Visible = _hScrollEnabled,
|
||||
VerticalAlignment = VAlignment.Bottom,
|
||||
HorizontalAlignment = HAlignment.Stretch
|
||||
};
|
||||
_vScrollBar = new VScrollBar
|
||||
{
|
||||
Visible = false,
|
||||
Visible = _vScrollEnabled,
|
||||
VerticalAlignment = VAlignment.Stretch,
|
||||
HorizontalAlignment = HAlignment.Right
|
||||
};
|
||||
|
||||
@@ -7,6 +7,7 @@ using Robust.Shared.IoC;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Utility;
|
||||
using Robust.Shared.ViewVariables;
|
||||
using Direction = Robust.Shared.Maths.Direction;
|
||||
|
||||
namespace Robust.Client.UserInterface.Controls
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Numerics;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Numerics;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Maths;
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Numerics;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
|
||||
@@ -1,16 +1,32 @@
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Shared.Timing;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Robust.Client.UserInterface.CustomControls
|
||||
{
|
||||
public sealed class Tooltip : PanelContainer
|
||||
{
|
||||
private readonly Label _label;
|
||||
private readonly RichTextLabel _label;
|
||||
|
||||
public string? Text
|
||||
{
|
||||
get => _label.Text;
|
||||
set => _label.Text = value;
|
||||
get => _label.GetMessage();
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
_label.SetMessage(string.Empty);
|
||||
}
|
||||
else
|
||||
{
|
||||
_label.SetMessage(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetMessage(FormattedMessage message)
|
||||
{
|
||||
_label.SetMessage(message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -28,7 +44,7 @@ namespace Robust.Client.UserInterface.CustomControls
|
||||
|
||||
AddChild(vbox);
|
||||
|
||||
vbox.AddChild(_label = new Label());
|
||||
vbox.AddChild(_label = new RichTextLabel());
|
||||
}
|
||||
|
||||
protected override void FrameUpdate(FrameEventArgs args)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Maths;
|
||||
using static Robust.Client.UserInterface.StylesheetHelpers;
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Maths;
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace Robust.Client.UserInterface
|
||||
LayoutContainer.SetPosition(tooltip, new Vector2(screenPosition.X, screenPosition.Y - combinedMinSize.Y));
|
||||
|
||||
var right = tooltip.Position.X + combinedMinSize.X;
|
||||
var top = tooltip.Position.Y - combinedMinSize.Y;
|
||||
var top = tooltip.Position.Y;
|
||||
|
||||
if (right > screenBounds.X)
|
||||
{
|
||||
|
||||
@@ -1,39 +1,40 @@
|
||||
using System;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.Graphics.RSI;
|
||||
using Robust.Shared.Maths;
|
||||
using static Robust.Client.GameObjects.SpriteComponent;
|
||||
using RSIDirection = Robust.Client.Graphics.RSI.State.Direction;
|
||||
using Direction = Robust.Shared.Maths.Direction;
|
||||
|
||||
namespace Robust.Client.Utility
|
||||
{
|
||||
public static class DirExt
|
||||
{
|
||||
public static Direction Convert(this RSIDirection dir)
|
||||
public static Direction Convert(this RsiDirection dir)
|
||||
{
|
||||
switch (dir)
|
||||
{
|
||||
case RSIDirection.South:
|
||||
case RsiDirection.South:
|
||||
return Direction.South;
|
||||
|
||||
case RSIDirection.North:
|
||||
case RsiDirection.North:
|
||||
return Direction.North;
|
||||
|
||||
case RSIDirection.East:
|
||||
case RsiDirection.East:
|
||||
return Direction.East;
|
||||
|
||||
case RSIDirection.West:
|
||||
case RsiDirection.West:
|
||||
return Direction.West;
|
||||
|
||||
case RSIDirection.SouthEast:
|
||||
case RsiDirection.SouthEast:
|
||||
return Direction.SouthEast;
|
||||
|
||||
case RSIDirection.SouthWest:
|
||||
case RsiDirection.SouthWest:
|
||||
return Direction.SouthWest;
|
||||
|
||||
case RSIDirection.NorthEast:
|
||||
case RsiDirection.NorthEast:
|
||||
return Direction.NorthEast;
|
||||
|
||||
case RSIDirection.NorthWest:
|
||||
case RsiDirection.NorthWest:
|
||||
return Direction.NorthWest;
|
||||
}
|
||||
|
||||
@@ -46,54 +47,54 @@ namespace Robust.Client.Utility
|
||||
/// <param name="dir">The direction to round</param>
|
||||
/// <returns><paramref name="dir"/> if it's a cardinal direction, otherwise either north or
|
||||
/// south.</returns>
|
||||
public static RSIDirection RoundToCardinal(this RSIDirection dir)
|
||||
public static RsiDirection RoundToCardinal(this RsiDirection dir)
|
||||
{
|
||||
switch (dir)
|
||||
{
|
||||
case RSIDirection.NorthEast:
|
||||
case RSIDirection.NorthWest:
|
||||
return RSIDirection.North;
|
||||
case RsiDirection.NorthEast:
|
||||
case RsiDirection.NorthWest:
|
||||
return RsiDirection.North;
|
||||
|
||||
case RSIDirection.SouthEast:
|
||||
case RSIDirection.SouthWest:
|
||||
return RSIDirection.South;
|
||||
case RsiDirection.SouthEast:
|
||||
case RsiDirection.SouthWest:
|
||||
return RsiDirection.South;
|
||||
|
||||
default:
|
||||
return dir;
|
||||
}
|
||||
}
|
||||
|
||||
public static RSIDirection Convert(this Direction dir, RSI.State.DirectionType type)
|
||||
public static RsiDirection Convert(this Direction dir, RsiDirectionType type)
|
||||
{
|
||||
if (type == RSI.State.DirectionType.Dir1)
|
||||
return RSIDirection.South;
|
||||
if (type == RsiDirectionType.Dir1)
|
||||
return RsiDirection.South;
|
||||
|
||||
switch (dir)
|
||||
{
|
||||
case Direction.North:
|
||||
return RSIDirection.North;
|
||||
return RsiDirection.North;
|
||||
|
||||
case Direction.South:
|
||||
return RSIDirection.South;
|
||||
return RsiDirection.South;
|
||||
|
||||
case Direction.East:
|
||||
return RSIDirection.East;
|
||||
return RsiDirection.East;
|
||||
|
||||
case Direction.West:
|
||||
return RSIDirection.West;
|
||||
return RsiDirection.West;
|
||||
}
|
||||
|
||||
var rsiDir = dir switch
|
||||
{
|
||||
Direction.SouthEast => RSIDirection.SouthEast,
|
||||
Direction.SouthWest => RSIDirection.SouthWest,
|
||||
Direction.NorthEast => RSIDirection.NorthEast,
|
||||
Direction.NorthWest => RSIDirection.NorthWest,
|
||||
Direction.SouthEast => RsiDirection.SouthEast,
|
||||
Direction.SouthWest => RsiDirection.SouthWest,
|
||||
Direction.NorthEast => RsiDirection.NorthEast,
|
||||
Direction.NorthWest => RsiDirection.NorthWest,
|
||||
_ => throw new ArgumentException($"Unknown dir: {dir}.", nameof(dir))
|
||||
};
|
||||
|
||||
// Round down to a four-way direction if appropriate.
|
||||
if (type == RSI.State.DirectionType.Dir4)
|
||||
if (type == RsiDirectionType.Dir4)
|
||||
{
|
||||
return RoundToCardinal(rsiDir);
|
||||
}
|
||||
@@ -111,18 +112,18 @@ namespace Robust.Client.Utility
|
||||
return (Direction)(((int)dir + 1) % 8);
|
||||
}
|
||||
|
||||
public static RSIDirection ToRsiDirection(this Angle angle, RSI.State.DirectionType type)
|
||||
public static RsiDirection ToRsiDirection(this Angle angle, RsiDirectionType type)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
RSI.State.DirectionType.Dir1 => RSIDirection.South,
|
||||
RSI.State.DirectionType.Dir4 => angle.GetCardinalDir().Convert(type),
|
||||
RSI.State.DirectionType.Dir8 => angle.GetDir().Convert(type),
|
||||
RsiDirectionType.Dir1 => RsiDirection.South,
|
||||
RsiDirectionType.Dir4 => angle.GetCardinalDir().Convert(type),
|
||||
RsiDirectionType.Dir8 => angle.GetDir().Convert(type),
|
||||
_ => throw new ArgumentOutOfRangeException($"Unknown rsi direction type: {type}.", nameof(type))
|
||||
};
|
||||
}
|
||||
|
||||
public static RSIDirection OffsetRsiDir(this RSIDirection dir, DirectionOffset offset)
|
||||
public static RsiDirection OffsetRsiDir(this RsiDirection dir, DirectionOffset offset)
|
||||
{
|
||||
// There is probably a better way to do this.
|
||||
// Eh.
|
||||
@@ -136,32 +137,32 @@ namespace Robust.Client.Utility
|
||||
case DirectionOffset.Clockwise:
|
||||
return dir switch
|
||||
{
|
||||
RSIDirection.North => RSIDirection.East,
|
||||
RSIDirection.East => RSIDirection.South,
|
||||
RSIDirection.South => RSIDirection.West,
|
||||
RSIDirection.West => RSIDirection.North,
|
||||
RsiDirection.North => RsiDirection.East,
|
||||
RsiDirection.East => RsiDirection.South,
|
||||
RsiDirection.South => RsiDirection.West,
|
||||
RsiDirection.West => RsiDirection.North,
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
case DirectionOffset.CounterClockwise:
|
||||
return dir switch
|
||||
{
|
||||
RSIDirection.North => RSIDirection.West,
|
||||
RSIDirection.East => RSIDirection.North,
|
||||
RSIDirection.South => RSIDirection.East,
|
||||
RSIDirection.West => RSIDirection.South,
|
||||
RsiDirection.North => RsiDirection.West,
|
||||
RsiDirection.East => RsiDirection.North,
|
||||
RsiDirection.South => RsiDirection.East,
|
||||
RsiDirection.West => RsiDirection.South,
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
case DirectionOffset.Flip:
|
||||
switch (dir)
|
||||
{
|
||||
case RSIDirection.North:
|
||||
return RSIDirection.South;
|
||||
case RSIDirection.East:
|
||||
return RSIDirection.West;
|
||||
case RSIDirection.South:
|
||||
return RSIDirection.North;
|
||||
case RSIDirection.West:
|
||||
return RSIDirection.East;
|
||||
case RsiDirection.North:
|
||||
return RsiDirection.South;
|
||||
case RsiDirection.East:
|
||||
return RsiDirection.West;
|
||||
case RsiDirection.South:
|
||||
return RsiDirection.North;
|
||||
case RsiDirection.West:
|
||||
return RsiDirection.East;
|
||||
default:
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using Robust.Client.GameObjects;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
@@ -10,6 +10,7 @@ using Robust.Client.ViewVariables.Editors;
|
||||
using Robust.Client.ViewVariables.Instances;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Network;
|
||||
@@ -190,6 +191,11 @@ namespace Robust.Client.ViewVariables
|
||||
return new VVPropEditorEntityUid();
|
||||
}
|
||||
|
||||
if (type == typeof(NetEntity))
|
||||
{
|
||||
return new VVPropEditorNetEntity();
|
||||
}
|
||||
|
||||
if (type == typeof(Color))
|
||||
{
|
||||
return new VVPropEditorColor();
|
||||
@@ -227,7 +233,7 @@ namespace Robust.Client.ViewVariables
|
||||
instance = new ViewVariablesInstanceObject(this, _robustSerializer);
|
||||
}
|
||||
|
||||
var window = new DefaultWindow {Title = "View Variables"};
|
||||
var window = new DefaultWindow {Title = Loc.GetString("view-variables")};
|
||||
instance.Initialize(window, obj);
|
||||
window.OnClose += () => _closeInstance(instance, false);
|
||||
_windows.Add(instance, window);
|
||||
@@ -245,7 +251,7 @@ namespace Robust.Client.ViewVariables
|
||||
{
|
||||
var window = new DefaultWindow
|
||||
{
|
||||
Title = "View Variables",
|
||||
Title = Loc.GetString("view-variables"),
|
||||
SetSize = _defaultWindowSize
|
||||
};
|
||||
var loadingLabel = new Label {Text = "Retrieving remote object data from server..."};
|
||||
|
||||
@@ -4,7 +4,6 @@ using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Shared.Console;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Maths;
|
||||
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||
|
||||
namespace Robust.Client.ViewVariables.Editors
|
||||
@@ -39,7 +38,8 @@ namespace Robust.Client.ViewVariables.Editors
|
||||
|
||||
vvButton.OnPressed += e =>
|
||||
{
|
||||
IoCManager.Resolve<IConsoleHost>().ExecuteCommand($"vv {uid}");
|
||||
var id = IoCManager.Resolve<IEntityManager>().GetNetEntity(uid);
|
||||
IoCManager.Resolve<IConsoleHost>().ExecuteCommand($"vv {id}");
|
||||
};
|
||||
|
||||
hBox.AddChild(lineEdit);
|
||||
|
||||
48
Robust.Client/ViewVariables/Editors/VVPropEditorNetEntity.cs
Normal file
48
Robust.Client/ViewVariables/Editors/VVPropEditorNetEntity.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using System.Numerics;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Shared.Console;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||
|
||||
namespace Robust.Client.ViewVariables.Editors;
|
||||
|
||||
public sealed class VVPropEditorNetEntity : VVPropEditor
|
||||
{
|
||||
protected override Control MakeUI(object? value)
|
||||
{
|
||||
var hBox = new BoxContainer
|
||||
{
|
||||
Orientation = LayoutOrientation.Horizontal,
|
||||
MinSize = new Vector2(200, 0)
|
||||
};
|
||||
|
||||
var nuid = (NetEntity)value!;
|
||||
var lineEdit = new LineEdit
|
||||
{
|
||||
Text = nuid.ToString(),
|
||||
Editable = !ReadOnly,
|
||||
HorizontalExpand = true,
|
||||
};
|
||||
if (!ReadOnly)
|
||||
{
|
||||
lineEdit.OnTextEntered += e =>
|
||||
ValueChanged(NetEntity.Parse(e.Text));
|
||||
}
|
||||
|
||||
var vvButton = new Button()
|
||||
{
|
||||
Text = "View",
|
||||
};
|
||||
|
||||
vvButton.OnPressed += e =>
|
||||
{
|
||||
IoCManager.Resolve<IConsoleHost>().ExecuteCommand($"vv {nuid}");
|
||||
};
|
||||
|
||||
hBox.AddChild(lineEdit);
|
||||
hBox.AddChild(vvButton);
|
||||
return hBox;
|
||||
}
|
||||
}
|
||||
@@ -469,8 +469,7 @@ namespace Robust.Client.ViewVariables.Instances
|
||||
_entitySession = session;
|
||||
|
||||
_membersBlob = await ViewVariablesManager.RequestData<ViewVariablesBlobMembers>(session, new ViewVariablesRequestMembers());
|
||||
|
||||
var uid = (EntityUid) _membersBlob.MemberGroups.SelectMany(p => p.Item2).Single(p => p.Name == "Uid").Value;
|
||||
var uid = (NetEntity) _membersBlob.MemberGroups.SelectMany(p => p.Item2).First(p => p.Value is NetEntity).Value;
|
||||
|
||||
Initialize(window, uid);
|
||||
}
|
||||
|
||||
@@ -209,6 +209,8 @@ using Robust.Shared.Serialization.TypeSerializers.Interfaces;
|
||||
""";
|
||||
|
||||
baseCopy = $$"""
|
||||
/// <seealso cref="ISerializationManager.CopyTo"/>
|
||||
[Obsolete("Use ISerializationManager.CopyTo instead")]
|
||||
public override void Copy(ref {{baseName}} target, ISerializationManager serialization, SerializationHookContext hookCtx, ISerializationContext? context = null)
|
||||
{
|
||||
var cast = ({{definition.GenericTypeName}}) target;
|
||||
@@ -216,6 +218,8 @@ using Robust.Shared.Serialization.TypeSerializers.Interfaces;
|
||||
target = cast!;
|
||||
}
|
||||
|
||||
/// <seealso cref="ISerializationManager.CopyTo"/>
|
||||
[Obsolete("Use ISerializationManager.CopyTo instead")]
|
||||
public override void Copy(ref object target, ISerializationManager serialization, SerializationHookContext hookCtx, ISerializationContext? context = null)
|
||||
{
|
||||
var cast = ({{definition.GenericTypeName}}) target;
|
||||
@@ -227,6 +231,8 @@ using Robust.Shared.Serialization.TypeSerializers.Interfaces;
|
||||
else
|
||||
{
|
||||
baseCopy = $$"""
|
||||
/// <seealso cref="ISerializationManager.CopyTo"/>
|
||||
[Obsolete("Use ISerializationManager.CopyTo instead")]
|
||||
public {{modifiers}} void Copy(ref object target, ISerializationManager serialization, SerializationHookContext hookCtx, ISerializationContext? context = null)
|
||||
{
|
||||
var cast = ({{definition.GenericTypeName}}) target;
|
||||
@@ -237,12 +243,16 @@ using Robust.Shared.Serialization.TypeSerializers.Interfaces;
|
||||
}
|
||||
|
||||
builder.AppendLine($$"""
|
||||
/// <seealso cref="ISerializationManager.CopyTo"/>
|
||||
[Obsolete("Use ISerializationManager.CopyTo instead")]
|
||||
public {{modifiers}} void InternalCopy(ref {{definition.GenericTypeName}} target, ISerializationManager serialization, SerializationHookContext hookCtx, ISerializationContext? context = null)
|
||||
{
|
||||
{{baseCall}}
|
||||
{{CopyDataFields(definition)}}
|
||||
}
|
||||
|
||||
/// <seealso cref="ISerializationManager.CopyTo"/>
|
||||
[Obsolete("Use ISerializationManager.CopyTo instead")]
|
||||
public {{modifiers}} void Copy(ref {{definition.GenericTypeName}} target, ISerializationManager serialization, SerializationHookContext hookCtx, ISerializationContext? context = null)
|
||||
{
|
||||
InternalCopy(ref target, serialization, hookCtx, context);
|
||||
@@ -259,6 +269,8 @@ using Robust.Shared.Serialization.TypeSerializers.Interfaces;
|
||||
var interfaceName = @interface.ToDisplayString();
|
||||
|
||||
builder.AppendLine($$"""
|
||||
/// <seealso cref="ISerializationManager.CopyTo"/>
|
||||
[Obsolete("Use ISerializationManager.CopyTo instead")]
|
||||
public {{interfaceModifiers}} void InternalCopy(ref {{interfaceName}} target, ISerializationManager serialization, SerializationHookContext hookCtx, ISerializationContext? context = null)
|
||||
{
|
||||
var def = ({{definition.GenericTypeName}}) target;
|
||||
@@ -266,6 +278,8 @@ using Robust.Shared.Serialization.TypeSerializers.Interfaces;
|
||||
target = def;
|
||||
}
|
||||
|
||||
/// <seealso cref="ISerializationManager.CopyTo"/>
|
||||
[Obsolete("Use ISerializationManager.CopyTo instead")]
|
||||
public {{interfaceModifiers}} void Copy(ref {{interfaceName}} target, ISerializationManager serialization, SerializationHookContext hookCtx, ISerializationContext? context = null)
|
||||
{
|
||||
InternalCopy(ref target, serialization, hookCtx, context);
|
||||
@@ -290,6 +304,8 @@ using Robust.Shared.Serialization.TypeSerializers.Interfaces;
|
||||
{
|
||||
// TODO make abstract once data definitions are forced to be partial
|
||||
builder.AppendLine($$"""
|
||||
/// <seealso cref="ISerializationManager.CreateCopy"/>
|
||||
[Obsolete("Use ISerializationManager.CreateCopy instead")]
|
||||
public {{modifiers}} {{definition.GenericTypeName}} Instantiate()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
@@ -299,6 +315,8 @@ using Robust.Shared.Serialization.TypeSerializers.Interfaces;
|
||||
else
|
||||
{
|
||||
builder.AppendLine($$"""
|
||||
/// <seealso cref="ISerializationManager.CreateCopy"/>
|
||||
[Obsolete("Use ISerializationManager.CreateCopy instead")]
|
||||
public {{modifiers}} {{definition.GenericTypeName}} Instantiate()
|
||||
{
|
||||
return new {{definition.GenericTypeName}}();
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
using System.Numerics;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Players;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Robust.Server.GameObjects
|
||||
{
|
||||
[RegisterComponent, ComponentReference(typeof(SharedEyeComponent))]
|
||||
public sealed partial class EyeComponent : SharedEyeComponent
|
||||
{
|
||||
public const int DefaultVisibilityMask = 1;
|
||||
|
||||
[DataField("drawFov")]
|
||||
private bool _drawFov = true;
|
||||
[DataField("zoom")]
|
||||
private Vector2 _zoom = Vector2.One;
|
||||
private Vector2 _offset;
|
||||
private Angle _rotation;
|
||||
private uint _visibilityMask = DefaultVisibilityMask;
|
||||
|
||||
public override bool DrawFov
|
||||
{
|
||||
get => _drawFov;
|
||||
set
|
||||
{
|
||||
if (_drawFov == value)
|
||||
return;
|
||||
|
||||
_drawFov = value;
|
||||
Dirty();
|
||||
}
|
||||
}
|
||||
|
||||
public override Vector2 Zoom
|
||||
{
|
||||
get => _zoom;
|
||||
set
|
||||
{
|
||||
if (_zoom.EqualsApprox(value))
|
||||
return;
|
||||
|
||||
_zoom = value;
|
||||
Dirty();
|
||||
}
|
||||
}
|
||||
|
||||
public override Vector2 Offset
|
||||
{
|
||||
get => _offset;
|
||||
set
|
||||
{
|
||||
if (_offset.EqualsApprox(value))
|
||||
return;
|
||||
|
||||
_offset = value;
|
||||
Dirty();
|
||||
}
|
||||
}
|
||||
|
||||
public override Angle Rotation
|
||||
{
|
||||
get => _rotation;
|
||||
set
|
||||
{
|
||||
if(_rotation.EqualsApprox(value))
|
||||
return;
|
||||
|
||||
_rotation = value;
|
||||
Dirty();
|
||||
}
|
||||
}
|
||||
|
||||
public override uint VisibilityMask
|
||||
{
|
||||
get => _visibilityMask;
|
||||
set
|
||||
{
|
||||
if(_visibilityMask == value)
|
||||
return;
|
||||
|
||||
_visibilityMask = value;
|
||||
Dirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
using Robust.Shared.GameObjects;
|
||||
|
||||
namespace Robust.Server.GameObjects
|
||||
{
|
||||
[RegisterComponent]
|
||||
[ComponentReference(typeof(SharedPointLightComponent))]
|
||||
public sealed partial class PointLightComponent : SharedPointLightComponent {}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using Robust.Shared.GameObjects;
|
||||
|
||||
namespace Robust.Server.GameObjects;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class PointLightComponent : SharedPointLightComponent
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Server.Player;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.ViewVariables;
|
||||
using static Robust.Shared.GameObjects.SharedUserInterfaceComponent;
|
||||
|
||||
namespace Robust.Server.GameObjects
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains a collection of entity-bound user interfaces that can be opened per client.
|
||||
/// Bound user interfaces are indexed with an enum or string key identifier.
|
||||
/// </summary>
|
||||
/// <seealso cref="BoundUserInterface"/>
|
||||
[PublicAPI]
|
||||
[RegisterComponent]
|
||||
public sealed partial class ServerUserInterfaceComponent : SharedUserInterfaceComponent
|
||||
{
|
||||
[ViewVariables]
|
||||
public readonly Dictionary<Enum, BoundUserInterface> Interfaces = new();
|
||||
}
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class ActiveUserInterfaceComponent : Component
|
||||
{
|
||||
public HashSet<BoundUserInterface> Interfaces = new();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents an entity-bound interface that can be opened by multiple players at once.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public sealed class BoundUserInterface
|
||||
{
|
||||
public float InteractionRange;
|
||||
|
||||
public float InteractionRangeSqrd => InteractionRange * InteractionRange;
|
||||
|
||||
public Enum UiKey { get; }
|
||||
public EntityUid Owner { get; }
|
||||
|
||||
internal readonly HashSet<IPlayerSession> _subscribedSessions = new();
|
||||
internal BoundUIWrapMessage? LastStateMsg;
|
||||
public bool RequireInputValidation;
|
||||
|
||||
internal bool StateDirty;
|
||||
|
||||
internal readonly Dictionary<IPlayerSession, BoundUIWrapMessage> PlayerStateOverrides =
|
||||
new();
|
||||
|
||||
/// <summary>
|
||||
/// All of the sessions currently subscribed to this UserInterface.
|
||||
/// </summary>
|
||||
public IReadOnlySet<IPlayerSession> SubscribedSessions => _subscribedSessions;
|
||||
|
||||
public BoundUserInterface(PrototypeData data, EntityUid owner)
|
||||
{
|
||||
RequireInputValidation = data.RequireInputValidation;
|
||||
UiKey = data.UiKey;
|
||||
Owner = owner;
|
||||
|
||||
InteractionRange = data.InteractionRange;
|
||||
}
|
||||
}
|
||||
|
||||
[PublicAPI]
|
||||
public sealed class ServerBoundUserInterfaceMessage
|
||||
{
|
||||
public BoundUserInterfaceMessage Message { get; }
|
||||
public IPlayerSession Session { get; }
|
||||
|
||||
public ServerBoundUserInterfaceMessage(BoundUserInterfaceMessage message, IPlayerSession session)
|
||||
{
|
||||
Message = message;
|
||||
Session = session;
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user