Thinkers are always part of a level if they are linked and active, so this reference needs to be kept so that a thinker can unlink itself on destruction.
It may be a bit tricky to separate per-session and per-level actions here - for now only the sound resuming has been moved because that cannot be done per level.
The serializer will require special treatment because it needs the level to index the map geometry.
However, since this only gets called from inside the level itself, the solution is relatively simple: At the start of level serialization it sets the level pointer and at the end clears it again.
- It was calling the fallback aiming in the wrong place when it should have been outside the speed check.
- Credit to _mental_ for the base code, but no gotos involved.
This time there was one important exported script function: Actor.Spawn.
Since this will require a level pointer in the new scheme of things the old version had to be deprecated, because it is static with no argument that allows retrieving the level. However, since this is probably one of the most widely used functions I added a workaround to let it continue to work if used from inside an actor class, which should constitute >95% of all uses. This required a little bit of hackery in the compiler backend to swap out the function if appropriate.
Aside from that there were 5 places in the internal ZScript that needed handling, which mostly consisted of making a formerly static internal function non-static.
There are several places where a temporary change of light mode is needed, all these made this change in the global level struct. Now the change is only local to the active draw info.
If we ever want to refactor the global level data these must not reference the 'level' variable.
The main parts of the map loader cannot use this information, because it can only be created after running the node builder, so it got its own set of index functions instead.
Visual C++ will never statically initialize a class instance where a member field has a default value set, so the DEFINE_ACTION_FUNCTION variants without a direct native call need to be handled differently. The easiest way to do this is to leave out the nullptr default and omit the value in the initializer list. For trailing fields this will always get them nulled.