Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Change the movable contents to special list, and make view include Contents #2050

Merged
merged 5 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 82 additions & 18 deletions OpenDreamRuntime/Objects/Types/DreamList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -976,20 +976,10 @@ private ImmutableAppearance GetAppearance() {
}

// client.screen list
public sealed class ClientScreenList : DreamList {
private readonly DreamObjectTree _objectTree;
private readonly ServerScreenOverlaySystem? _screenOverlaySystem;

private readonly DreamConnection _connection;
public sealed class ClientScreenList(DreamObjectTree objectTree, ServerScreenOverlaySystem? screenOverlaySystem, DreamConnection connection)
: DreamList(objectTree.List.ObjectDefinition, 0) {
private readonly List<DreamValue> _screenObjects = new();

public ClientScreenList(DreamObjectTree objectTree, ServerScreenOverlaySystem? screenOverlaySystem, DreamConnection connection) : base(objectTree.List.ObjectDefinition, 0) {
_objectTree = objectTree;
_screenOverlaySystem = screenOverlaySystem;

_connection = connection;
}

public override bool ContainsValue(DreamValue value) {
return _screenObjects.Contains(value);
}
Expand All @@ -1013,15 +1003,15 @@ public override void AddValue(DreamValue value) {
if (!value.TryGetValueAsDreamObject<DreamObjectMovable>(out var movable))
return;

_screenOverlaySystem?.AddScreenObject(_connection, movable);
screenOverlaySystem?.AddScreenObject(connection, movable);
_screenObjects.Add(value);
}

public override void RemoveValue(DreamValue value) {
if (!value.TryGetValueAsDreamObject<DreamObjectMovable>(out var movable))
return;

_screenOverlaySystem?.RemoveScreenObject(_connection, movable);
screenOverlaySystem?.RemoveScreenObject(connection, movable);
_screenObjects.Remove(value);
}

Expand All @@ -1032,7 +1022,7 @@ public override void Cut(int start = 1, int end = 0) {
if (!_screenObjects[i].TryGetValueAsDreamObject<DreamObjectMovable>(out var movable))
continue;

_screenOverlaySystem?.RemoveScreenObject(_connection, movable);
screenOverlaySystem?.RemoveScreenObject(connection, movable);
}

_screenObjects.RemoveRange(start - 1, end - start);
Expand All @@ -1043,7 +1033,6 @@ public override int GetLength() {
}
}


// client.images list
public sealed class ClientImagesList : DreamList {
private readonly ServerClientImagesSystem? _clientImagesSystem;
Expand Down Expand Up @@ -1170,15 +1159,15 @@ public override void AddValue(DreamValue value) {
if (!value.TryGetValueAsDreamObject<DreamObjectMovable>(out var movable))
throw new Exception($"Cannot add {value} to turf contents");

movable.SetVariable("loc", new(Cell.Turf));
movable.SetLoc(Cell.Turf);
}

public override void Cut(int start = 1, int end = 0) {
int movableCount = Cell.Movables.Count + 1;
if (end == 0 || end > movableCount) end = movableCount;

for (int i = start; i < end; i++) {
Cell.Movables[i - 1].SetVariable("loc", DreamValue.Null);
Cell.Movables[i - 1].SetLoc(null);
}
}

Expand Down Expand Up @@ -1256,6 +1245,81 @@ public override int GetLength() {
}
}

// mob.contents, obj.contents list
public sealed class MovableContentsList(DreamObjectDefinition listDef, DreamObjectMovable owner, TransformComponent transform) : DreamList(listDef, 0) {
public override DreamValue GetValue(DreamValue key) {
Fixed Show fixed Hide fixed
if (!key.TryGetValueAsInteger(out var index))
throw new Exception($"Invalid index into movable contents list: {key}");
if (index < 1 || index > transform.ChildCount)
throw new Exception($"Out of bounds index on movable contents list: {index}");

using var childEnumerator = transform.ChildEnumerator;
while (index >= 1) {
childEnumerator.MoveNext(out EntityUid child);

if (index == 1) {
if (AtomManager.TryGetMovableFromEntity(child, out var childObject))
return new DreamValue(childObject);
else
throw new Exception($"Invalid child in movable contents list: {child}");
}

index--;
}

throw new Exception($"Out of bounds index on movable contents list after iterating: {key}");
}

public override List<DreamValue> GetValues() {
List<DreamValue> values = new List<DreamValue>(transform.ChildCount);
using var childEnumerator = transform.ChildEnumerator;

while (childEnumerator.MoveNext(out EntityUid child)) {
if (!AtomManager.TryGetMovableFromEntity(child, out var childObject))
continue;

values.Add(new DreamValue(childObject));
}

return values;
}

public override void SetValue(DreamValue key, DreamValue value, bool allowGrowth = false) {
throw new Exception("Cannot set an index of movable contents list");
}

public override void AddValue(DreamValue value) {
if (!value.TryGetValueAsDreamObject<DreamObjectMovable>(out var dreamObject))
throw new Exception($"Cannot add {value} to movable contents");

dreamObject.SetLoc(owner);
}

public override void RemoveValue(DreamValue value) {
if (!value.TryGetValueAsDreamObject<DreamObjectMovable>(out var movable))
throw new Exception($"Cannot remove {value} from movable contents");
if (movable.Loc != owner)
return; // This object wasn't in our contents to begin with

movable.SetLoc(null);
}

public override bool ContainsValue(DreamValue value) {
if (!value.TryGetValueAsDreamObject<DreamObjectMovable>(out var dreamObject))
return false;

return dreamObject.Loc == owner;
}

public override void Cut(int start = 1, int end = 0) {
// TODO
}

public override int GetLength() {
return transform.ChildCount;
}
}

// proc args list
internal sealed class ProcArgsList(DreamObjectDefinition listDef, DMProcState state) : DreamList(listDef, 0) {
public override DreamValue GetValue(DreamValue key) {
Expand Down
24 changes: 7 additions & 17 deletions OpenDreamRuntime/Objects/Types/DreamObjectMovable.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using OpenDreamRuntime.Procs;
using OpenDreamRuntime.Procs;
using OpenDreamRuntime.Rendering;
using OpenDreamShared.Dream;
using Robust.Shared.Map;
Expand All @@ -18,20 +18,21 @@ public class DreamObjectMovable : DreamObjectAtom {
public int Z => (int)_transformComponent.MapID;

private readonly TransformComponent _transformComponent;

private readonly MovableContentsList _contents;
private string? _screenLoc;

private string? ScreenLoc {
get => _screenLoc;
set => SetScreenLoc(value);
}

private string? _screenLoc;

public DreamObjectMovable(DreamObjectDefinition objectDefinition) : base(objectDefinition) {
Entity = AtomManager.CreateMovableEntity(this);
SpriteComponent = EntityManager.GetComponent<DMISpriteComponent>(Entity);
AtomManager.SetSpriteAppearance((Entity, SpriteComponent), AtomManager.GetAppearanceFromDefinition(ObjectDefinition));

_transformComponent = EntityManager.GetComponent<TransformComponent>(Entity);
_contents = new MovableContentsList(ObjectTree.List.ObjectDefinition, this, _transformComponent);
}

public override void Initialize(DreamProcArguments args) {
Expand Down Expand Up @@ -80,18 +81,7 @@ protected override bool TryGetVar(string varName, out DreamValue value) {
value = (ScreenLoc != null) ? new(ScreenLoc) : DreamValue.Null;
return true;
case "contents":
DreamList contents = ObjectTree.CreateList();

using (var childEnumerator = _transformComponent.ChildEnumerator) {
while (childEnumerator.MoveNext(out EntityUid child)) {
if (!AtomManager.TryGetMovableFromEntity(child, out var childAtom))
continue;

contents.AddValue(new DreamValue(childAtom));
}
}

value = new(contents);
value = new(_contents);
return true;
case "locs":
// Unimplemented; just return a list containing src.loc
Expand Down Expand Up @@ -150,7 +140,7 @@ protected override void SetVar(string varName, DreamValue value) {
}
}

private void SetLoc(DreamObjectAtom? loc) {
public void SetLoc(DreamObjectAtom? loc) {
Loc = loc;
if (TransformSystem == null)
return;
Expand Down
12 changes: 10 additions & 2 deletions OpenDreamRuntime/Procs/Native/DreamProcNativeRoot.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Buffers;
using System.Buffers;
using OpenDreamRuntime.Objects;
using OpenDreamRuntime.Resources;
using OpenDreamShared.Dream;
Expand Down Expand Up @@ -156,7 +156,7 @@ public static DreamValue NativeProc_animate(NativeProc.Bundle bundle, DreamObjec
return DreamValue.Null;
chainAnim = true;
}

bundle.LastAnimatedObject = new DreamValue(obj);
if(obj.IsSubtypeOf(bundle.ObjectTree.Filter)) {//TODO animate filters
return DreamValue.Null;
Expand Down Expand Up @@ -3024,6 +3024,14 @@ public static DreamValue NativeProc_view(NativeProc.Bundle bundle, DreamObject?
if (center is null)
return new(view);

if (center.TryGetVariable("contents", out var centerContents) && centerContents.TryGetValueAsDreamList(out var centerContentsList)) {
foreach (var item in centerContentsList.GetValues()) {
view.AddValue(item);
}
}

// Center gets included during the walk through the tiles

var eyePos = bundle.AtomManager.GetAtomPosition(center);
var viewData = DreamProcNativeHelpers.CollectViewData(bundle.AtomManager, bundle.MapManager, eyePos, range);

Expand Down
Loading