diff --git a/DMCompiler/DM/Builders/DMProcBuilder.cs b/DMCompiler/DM/Builders/DMProcBuilder.cs index 615012c4f7..e22b3db87f 100644 --- a/DMCompiler/DM/Builders/DMProcBuilder.cs +++ b/DMCompiler/DM/Builders/DMProcBuilder.cs @@ -193,9 +193,6 @@ public void ProcessStatementSet(DMASTProcStatementSet statementSet) { switch (statementSet.Value) { case DMASTIdentifier {Identifier: "usr"}: _proc.VerbSrc = statementSet.WasInKeyword ? VerbSrc.InUsr : VerbSrc.Usr; - if (statementSet.WasInKeyword) - DMCompiler.UnimplementedWarning(statementSet.Location, - "'set src = usr.contents' is unimplemented"); break; case DMASTDereference {Expression: DMASTIdentifier{Identifier: "usr"}, Operations: var operations}: if (operations is not [DMASTDereference.FieldOperation {Identifier: var deref}]) @@ -203,8 +200,6 @@ public void ProcessStatementSet(DMASTProcStatementSet statementSet) { if (deref == "contents") { _proc.VerbSrc = VerbSrc.InUsr; - DMCompiler.UnimplementedWarning(statementSet.Location, - "'set src = usr.contents' is unimplemented"); } else if (deref == "loc") { _proc.VerbSrc = VerbSrc.UsrLoc; DMCompiler.UnimplementedWarning(statementSet.Location, diff --git a/OpenDreamClient/ClientVerbSystem.cs b/OpenDreamClient/ClientVerbSystem.cs index 3981506827..7b8d16f65d 100644 --- a/OpenDreamClient/ClientVerbSystem.cs +++ b/OpenDreamClient/ClientVerbSystem.cs @@ -3,6 +3,7 @@ using OpenDreamClient.Rendering; using OpenDreamShared.Dream; using OpenDreamShared.Rendering; +using Robust.Client.GameObjects; using Robust.Client.Graphics; using Robust.Client.Player; using Robust.Shared.Asynchronous; @@ -17,6 +18,7 @@ public sealed class ClientVerbSystem : VerbSystem { [Dependency] private readonly ITaskManager _taskManager = default!; [Dependency] private readonly ITimerManager _timerManager = default!; [Dependency] private readonly IOverlayManager _overlayManager = default!; + [Dependency] private readonly TransformSystem _transformSystem = default!; private EntityQuery _spriteQuery; private EntityQuery _sightQuery; @@ -72,12 +74,10 @@ public IEnumerable GetAllVerbs() { /// Whether to ignore "set hidden = TRUE" /// The ID, src, and information of every executable verb public IEnumerable<(int Id, ClientObjectReference Src, VerbInfo VerbInfo)> GetExecutableVerbs(bool ignoreHiddenAttr = false) { - ClientObjectReference? ourMob = null; sbyte? seeInvisibility = null; if (_playerManager.LocalEntity != null) { _sightQuery.TryGetComponent(_playerManager.LocalEntity.Value, out var mobSight); - ourMob = new ClientObjectReference(_entityManager.GetNetEntity(_playerManager.LocalEntity.Value)); seeInvisibility = mobSight?.SeeInvisibility; } @@ -112,7 +112,12 @@ public IEnumerable GetAllVerbs() { // Check the verb's "set src" allows us to execute this switch (verb.Accessibility) { case VerbAccessibility.Usr: - if (!src.Equals(ourMob)) + if (entity != _playerManager.LocalEntity) + continue; + + break; + case VerbAccessibility.InUsr: + if (_transformSystem.GetParentUid(entity) != _playerManager.LocalEntity) continue; break; diff --git a/OpenDreamRuntime/Objects/Types/DreamObjectMovable.cs b/OpenDreamRuntime/Objects/Types/DreamObjectMovable.cs index 0cdd2528fd..36c3ee56ab 100644 --- a/OpenDreamRuntime/Objects/Types/DreamObjectMovable.cs +++ b/OpenDreamRuntime/Objects/Types/DreamObjectMovable.cs @@ -9,6 +9,7 @@ namespace OpenDreamRuntime.Objects.Types; public class DreamObjectMovable : DreamObjectAtom { public EntityUid Entity; public readonly DMISpriteComponent SpriteComponent; + public DreamObjectAtom? Loc; // TODO: Cache this shit. GetWorldPosition is slow. public Vector2i Position => (Vector2i?)TransformSystem?.GetWorldPosition(_transformComponent) ?? (0, 0); @@ -18,7 +19,6 @@ public class DreamObjectMovable : DreamObjectAtom { private readonly TransformComponent _transformComponent; - private DreamObjectAtom? _loc; private string? ScreenLoc { get => _screenLoc; @@ -75,7 +75,7 @@ protected override bool TryGetVar(string varName, out DreamValue value) { value = new(Z); return true; case "loc": - value = new(_loc); + value = new(Loc); return true; case "screen_loc": value = (ScreenLoc != null) ? new(ScreenLoc) : DreamValue.Null; @@ -97,7 +97,7 @@ protected override bool TryGetVar(string varName, out DreamValue value) { case "locs": // Unimplemented; just return a list containing src.loc DreamList locs = ObjectTree.CreateList(); - locs.AddValue(new(_loc)); + locs.AddValue(new(Loc)); value = new DreamValue(locs); return true; @@ -152,7 +152,7 @@ protected override void SetVar(string varName, DreamValue value) { } private void SetLoc(DreamObjectAtom? loc) { - _loc = loc; + Loc = loc; if (TransformSystem == null) return; diff --git a/OpenDreamRuntime/ServerVerbSystem.cs b/OpenDreamRuntime/ServerVerbSystem.cs index c8f20560d1..08c109cc82 100644 --- a/OpenDreamRuntime/ServerVerbSystem.cs +++ b/OpenDreamRuntime/ServerVerbSystem.cs @@ -188,6 +188,11 @@ private bool CanExecute(DreamConnection connection, DreamObject src, DreamProc v switch (verbInfo.Accessibility) { case VerbAccessibility.Usr: return src == connection.Mob; + case VerbAccessibility.InUsr: + if (src is not DreamObjectMovable srcMovable) + return false; + + return srcMovable.Loc == connection.Mob; default: // TODO: All the other kinds return true;