Make object sorting position on screen deterministic in case of equal z-order #2627
+71
−49
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fix #2311
This is a quick solution for resolving objects with identical z-order, in which case we'd like to keep their relative sort persistent, and avoid random sorting "swaps".
This is achieved by a combined comparison in sort's "less" function:
Global DrawIndex is allocated for each drawable object in game (except for gui controls that are sorted only among each other).
Static objects are reserved draw indexes at the game init.
Dynamic objects (currently only Overlays) have one assigned for them when they are drawn for the first time.
DrawIndex is ever incrementing counter. When it reaches max value (of uint32_t), it overflows and gets reset to the "base dynamic index", which is set once to the number of all the static game objects.
Also, DrawIndex is reset whenever all dynamic objects are removed; which in current engine happens when all overlays are removed either by command or when a room changes.
DrawIndex replaces use of GUI.ID and Overlay's "creation_id" for this purpose.
Walk-behinds always receive DrawIndex = 0, because
a) they cannot be sorted among themselves due to their nature (as cut-outs from room bg);
b) by classic AGS logic they must draw behind objects and characters when their baselines match walk-behind.
There's a side effect where, in case of equal z-order, objects always have lower position in sort compared to characters, and both objects and characters have lower position than room overlays. Similarly, guis will have lower position compared to screen overlays. I don't know if that matches original AGS behavior; but probably it was random, because neither objects nor chars were ever fixed for this problem.