Skip to content

Commit

Permalink
Flesh out the difference between set src in and set src = some more
Browse files Browse the repository at this point in the history
  • Loading branch information
wixoaGit committed Feb 10, 2024
1 parent bb18bf8 commit c8e10e0
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 22 deletions.
8 changes: 6 additions & 2 deletions DMCompiler/DM/VerbSrc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,17 @@
/// </summary>
public enum VerbSrc {
View,
InView,
OView,
InOView,
Range,
InRange,
ORange,
InORange,
World,
WorldContents,
InWorld,
Usr,
UsrContents,
InUsr,
UsrLoc,
UsrGroup
}
31 changes: 23 additions & 8 deletions DMCompiler/DM/Visitors/DMProcBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -190,14 +190,17 @@ public void ProcessStatementSet(DMASTProcStatementSet statementSet) {
// TODO: Would be much better if the parser was just more strict with the expression
switch (statementSet.Value) {
case DMASTIdentifier {Identifier: "usr"}:
_proc.VerbSrc = statementSet.WasInKeyword ? VerbSrc.UsrContents : VerbSrc.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}])
goto default;

if (deref == "contents") {
_proc.VerbSrc = VerbSrc.UsrContents;
_proc.VerbSrc = VerbSrc.InUsr;
DMCompiler.UnimplementedWarning(statementSet.Location,
"'set src = usr.contents' is unimplemented");
} else if (deref == "loc") {
Expand All @@ -214,24 +217,36 @@ public void ProcessStatementSet(DMASTProcStatementSet statementSet) {

break;
case DMASTIdentifier {Identifier: "world"}:
_proc.VerbSrc = statementSet.WasInKeyword ? VerbSrc.WorldContents : VerbSrc.World;
DMCompiler.UnimplementedWarning(statementSet.Location,
"'set src = world' is unimplemented");
_proc.VerbSrc = statementSet.WasInKeyword ? VerbSrc.InWorld : VerbSrc.World;
if (statementSet.WasInKeyword)
DMCompiler.UnimplementedWarning(statementSet.Location,
"'set src = world.contents' is unimplemented");
else
DMCompiler.UnimplementedWarning(statementSet.Location,
"'set src = world' is unimplemented");
break;
case DMASTDereference {Expression: DMASTIdentifier{Identifier: "world"}, Operations: var operations}:
if (operations is not [DMASTDereference.FieldOperation {Identifier: "contents"}])
goto default;

_proc.VerbSrc = VerbSrc.WorldContents;
_proc.VerbSrc = VerbSrc.InWorld;
DMCompiler.UnimplementedWarning(statementSet.Location,
"'set src = world.contents' is unimplemented");
break;
case DMASTProcCall {Callable: DMASTCallableProcIdentifier {Identifier: { } viewType and ("view" or "oview")}}:
_proc.VerbSrc = viewType == "view" ? VerbSrc.View : VerbSrc.OView; // TODO: Ranges
// TODO: Ranges
if (statementSet.WasInKeyword)
_proc.VerbSrc = viewType == "view" ? VerbSrc.InView : VerbSrc.InOView;
else
_proc.VerbSrc = viewType == "view" ? VerbSrc.View : VerbSrc.OView;
break;
// range() and orange() are undocumented, but they work
case DMASTProcCall {Callable: DMASTCallableProcIdentifier {Identifier: { } viewType and ("range" or "orange")}}:
_proc.VerbSrc = viewType == "range" ? VerbSrc.Range : VerbSrc.ORange; // TODO: Ranges
// TODO: Ranges
if (statementSet.WasInKeyword)
_proc.VerbSrc = viewType == "range" ? VerbSrc.InRange : VerbSrc.InORange;
else
_proc.VerbSrc = viewType == "range" ? VerbSrc.Range : VerbSrc.ORange;
break;
default:
DMCompiler.Emit(WarningCode.BadExpression, statementSet.Value.Location, "Invalid verb src");
Expand Down
10 changes: 9 additions & 1 deletion OpenDreamClient/ClientVerbSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,16 @@ public IEnumerable<VerbInfo> GetAllVerbs() {
public IEnumerable<(int Id, ClientObjectReference Src, VerbInfo VerbInfo)> GetExecutableVerbs(ClientObjectReference target) {
foreach (var verb in GetExecutableVerbs()) {
DreamValueType? targetType = verb.VerbInfo.GetTargetType();
if (targetType == null)
if (targetType == null) {
// Verbs without a target but an "in view()/range()" accessibility will still show
if (verb.Src.Equals(target) &&
verb.VerbInfo.Accessibility
is VerbAccessibility.InRange or VerbAccessibility.InORange
or VerbAccessibility.InView or VerbAccessibility.InOView)
yield return verb;

continue;
}

switch (target.Type) {
case ClientObjectReference.RefType.Entity:
Expand Down
21 changes: 12 additions & 9 deletions OpenDreamRuntime/ServerVerbSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,17 @@ public void RegisterVerb(DreamProc verb) {

VerbAccessibility? verbAccessibility = verb.VerbSrc switch {
VerbSrc.View => VerbAccessibility.View, // TODO: Ranges on the view()/range() types
VerbSrc.InView => VerbAccessibility.InView,
VerbSrc.OView => VerbAccessibility.OView,
VerbSrc.InOView => VerbAccessibility.InOView,
VerbSrc.Range => VerbAccessibility.Range,
VerbSrc.InRange => VerbAccessibility.InRange,
VerbSrc.ORange => VerbAccessibility.ORange,
VerbSrc.World => VerbAccessibility.WorldContents,
VerbSrc.WorldContents => VerbAccessibility.WorldContents,
VerbSrc.Usr or VerbSrc.UsrContents => VerbAccessibility.UsrContents,
VerbSrc.InORange => VerbAccessibility.InORange,
VerbSrc.World => VerbAccessibility.InWorld,
VerbSrc.InWorld => VerbAccessibility.InWorld,
VerbSrc.Usr => VerbAccessibility.Usr,
VerbSrc.InUsr => VerbAccessibility.InUsr,
VerbSrc.UsrLoc => VerbAccessibility.UsrLoc,
VerbSrc.UsrGroup => VerbAccessibility.UsrGroup,
null => null,
Expand All @@ -64,15 +69,13 @@ public void RegisterVerb(DreamProc verb) {
var def = verb.OwningType.ObjectDefinition;

// Assign a default based on the type this verb is defined on
if (def.IsSubtypeOf(_objectTree.Mob) || def.IsSubtypeOf(_objectTree.Client)) {
verbAccessibility = VerbAccessibility.Usr;
} else if (def.IsSubtypeOf(_objectTree.Obj)) {
verbAccessibility = VerbAccessibility.UsrContents;
if (def.IsSubtypeOf(_objectTree.Obj)) {
verbAccessibility = VerbAccessibility.InUsr;
} else if (def.IsSubtypeOf(_objectTree.Turf) || def.IsSubtypeOf(_objectTree.Area)) {
verbAccessibility = VerbAccessibility.View; // TODO: Range of 0
} else {
_sawmill.Error($"Failed to determine the src property of {verb}, could not register it as a verb");
return;
// The default for everything else (/mob especially)
verbAccessibility = VerbAccessibility.Usr;
}
}

Expand Down
8 changes: 6 additions & 2 deletions OpenDreamShared/Dream/VerbSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,16 @@ public struct VerbArg {
[Serializable, NetSerializable]
public enum VerbAccessibility : byte {
View,
InView,
OView,
InOView,
Range,
InRange,
ORange,
WorldContents,
UsrContents,
InORange,
InWorld,
Usr,
InUsr,
UsrLoc,
UsrGroup
}
Expand Down

0 comments on commit c8e10e0

Please sign in to comment.