diff --git a/OpenDreamRuntime/Objects/Types/DreamAssocList.cs b/OpenDreamRuntime/Objects/Types/DreamAssocList.cs index 01843f9130..2c0b6e68f0 100644 --- a/OpenDreamRuntime/Objects/Types/DreamAssocList.cs +++ b/OpenDreamRuntime/Objects/Types/DreamAssocList.cs @@ -148,4 +148,142 @@ public void Swap(int index1, int index2) { public bool ContainsValue(DreamValue value) { return _values.ContainsKey(value); } + + public override DreamValue OperatorAdd(DreamValue b, DMProcState state) { + var listCopy = (DreamAssocList)CreateCopy(); + + if (b.TryGetValueAsIDreamList(out var bList)) { + foreach (var pair in bList.EnumerateAssocValues()) { + if (listCopy.ContainsKey(pair.Key)) { + continue; + } + + listCopy.SetValue(pair.Key, pair.Value); + } + } else { + listCopy.AddValue(b); + } + + return new DreamValue(listCopy); + } + + public override DreamValue OperatorSubtract(DreamValue b, DMProcState state) { + var listCopy = (DreamAssocList)CreateCopy(); + + if (b.TryGetValueAsIDreamList(out var bList)) { + foreach (DreamValue value in bList.EnumerateValues()) { + listCopy.RemoveValue(value); + } + } else { + listCopy.RemoveValue(b); + } + + return new DreamValue(listCopy); + } + + public override DreamValue OperatorOr(DreamValue b, DMProcState state) { + var listCopy = (DreamAssocList)CreateCopy(); + + if (b.TryGetValueAsIDreamList(out var bList)) { + foreach (var pair in bList.EnumerateAssocValues()) { + if (listCopy.ContainsKey(pair.Key)) { + continue; + } + + listCopy.SetValue(pair.Key, pair.Value); + } + } else { + listCopy.AddValue(b); + } + + return new DreamValue(listCopy); + } + + public override DreamValue OperatorCombine(DreamValue b) { + if (b.TryGetValueAsIDreamList(out var bList)) { + foreach (var pair in bList.EnumerateAssocValues()) { + if (ContainsKey(pair.Key)) { + continue; + } + + SetValue(pair.Key, pair.Value); + } + } else { + AddValue(b); + } + + IncRef(); + return new(this); + } + + public override DreamValue OperatorAppend(DreamValue b) { + if (b.TryGetValueAsIDreamList(out var bList)) { + foreach (var pair in bList.EnumerateAssocValues()) { + if (ContainsKey(pair.Key)) { + continue; + } + + SetValue(pair.Key, pair.Value); + } + } else { + AddValue(b); + } + + IncRef(); + return new(this); + } + + public override DreamValue OperatorRemove(DreamValue b) { + if (b.TryGetValueAsIDreamList(out var bList)) { + foreach (var value in bList.EnumerateValues()) { + RemoveValue(value); + } + } else { + RemoveValue(b); + } + + IncRef(); + return new(this); + } + + public override DreamValue OperatorMask(DreamValue b) { + if (b.TryGetValueAsIDreamList(out var bList)) { + foreach (var value in EnumerateValues()) { + if (!bList.ContainsKey(value)) { + RemoveValue(value); + } + } + } else { + foreach (var value in EnumerateValues()) { + if (!value.Equals(b)) { + RemoveValue(value); + } + } + } + + IncRef(); + return new(this); + } + + public override DreamValue OperatorEquivalent(DreamValue b) { + if (!b.TryGetValueAsIDreamList(out var secondList)) + return DreamValue.False; + if (GetLength() != secondList.GetLength()) + return DreamValue.False; + + foreach (var pair in secondList.EnumerateAssocValues()) { + if (!ContainsKey(pair.Key)) { + return DreamValue.False; + } + + using var temp = GetValue(pair.Key); + if (!temp.Equals(pair.Value)) { + return DreamValue.False; + } + } + + return DreamValue.True; + } } + +