ID:2860405
 
Applies to:DM Language
Status: Open

Issue hasn't been assigned a status value.
Collision testing in DM is painful. I've devised a structure that would be highly customizable, use quite a lot of existing behavior, and take a lot of that pain out of working with the engine.

Trace() is a function that works like Move(), but has optional flags, and an optional list argument that you can pass objects that should be ignored when doing collision testing.

This is the flag structure I have outlined:

    TRACE_SLIDE //should trace simulate a slide
TRACE_JUMP // should trace simulate a jump
TRACE_MOVE // should the movement be attempted

//check flags
TRACE_IGNORE_CROSS //do not perform checks on Enter/Cross functions
TRACE_IGNORE_UNCROSS //do not perform checks on Exit/Uncross functions

//result flags (only with TRACE_MOVE)
TRACE_DISABLE_CROSSED // should the movement call Entered()/Crossed() hooks
TRACE_DISABLE_UNCROSSED // should the movement call Exited()/Uncrossed() hooks
TRACE_DISABLE_BUMP //should the movement call the Bump() hook

//return flags
TRACE_RESULTS //return the results in the form of a /trace datum


The first three flags determine how the movement should function. Trace doesn't just check movement, it can also perform the movement. If TRACE_MOVE is on, the Trace() action will actually attempt the movement.

The TRACE_IGNORE flags will disable the checking of objects that we're trying to cross, completely bypassing the calls of Enter()/Cross() or Exit()/Uncross(), or both.

The TRACE_DISABLE flags only function if TRACE_MOVE is set, and will cause a movement to fail to call Entered()/Crossed(), Exited()/Uncrossed() hooks depending on which are set. The TRACE_DISABLE_BUMP flag will not call the Bump() hook when set on a failed trace movement.

The last flag, TRACE_RESULTS will tell this proc what it should return. If it is off, it will return the same return value as Move() would have for the same location arguments. If it is on, however, it will return a trace datum:

trace
coord/old_loc //where the movement started
coord/new_loc //where the movement would have ended
coord/loc //where the movement actually ended
list/crossing //the atoms that we crossed over during the motion
list/uncrossing //the atoms that we stopped crossing during the motion (including pass-throughs)
atom/collider //the atom that caused this movement to fail
finalized = 0 //whether this movement has been attempted (read-only)
result //what a similar Move() would have returned


The trace datum should also contain a function Finalize(), which for any non-finalized trace, will call the appropriate Crossed()/Uncrossed()/Entered()/Exited()/Bump() hooks regardless of what has changed since the trace was constructed.

See my megathread in Design Philosophy:

https://www.byond.com/forum/post/2860395