Drawing of selected objects by other players has a couple of issues
SokyranTheDragon opened this issue · comments
Multiplayer selector drawing issues:
- Doesn't decrease the size when there are multiple things in a single cell (shelves)
- A
Thing
that hasCustomRectForSelector
will only draw the selection on the center, instead of the entire specified rect (like monument marker) - A pawn that is not spawned but on the map will not draw a selection (as we're checking
Thing.Map
instead ofThing.MapHeld
against current map) - If current map check is done against
Thing.MapHeld
, it'll display the selection in an incorrect location since we don't provide any special handling for those situations
Solutions:
- Treat as "works as intended" and leave as-is
- Will likely be the fastest performance-wise (assuming we implement the changes in 'Additional improvements' section), as it doesn't handle all possible cases and does the least work
- Extend the code to handle every single special handling situation
- This will require coming back and extending it every time RimWorld adds special handling for selection drawing
- It won't be compatible with mods that patch the vanilla methods, so they'd need to receive special patches
- Call RimWorld's
DrawSelectionBracketFor
method to let the game handle it, but insert some sort of patch (transpiler) that will apply the color change- It will be a future-proof solution, as changes to vanilla method likely won't require changes on our side
- Compatible with mods that patch the vanilla method (like Vehicle Framework)
- Use Harmony's reverse patching to (basically) copy
DrawSelectionBracketFor
into our own method and apply a transpiler- It will be a future-proof solution, as changes to vanilla method likely won't require changes on our side
- It won't be compatible with mods that patch the vanilla methods, so they'd need to receive special patches
- Instead of doing any patches or re-implementing the method, just call
DrawSelectionBracketFor
but provide theoverrideMat
argument (and create a coloredMaterial
for each player)- It will be a future-proof solution, as changes to vanilla method likely won't require changes on our side
- Compatible with mods that patch the vanilla method (like Vehicle Framework)
- This option was likely not used in the past, as (looking at the old source code) the method did not have the
overrideMat
argument
Additional improvements (assuming still relevant to specific solution):
- Change the color of
MaterialPropertyBlock
using the cached result fromShader.PropertyToID("_Color")
instead of using the string name - Change the color of
MaterialPropertyBlock
of once per player, instead of once per draw call (4 times perThing
due to 4 corners)
Example implementation (using the last proposed solution, also assuming that the player selection Material
is held by PlayerInfo
):
https://gist.github.com/SokyranTheDragon/27313d910055be8b7506ecf111768a5f
Additional notes on compatibility with other mods:
Trying to add custom handling for selection drawing (like Vehicle Framework's 8-way rotation) is currently impossible without fully replacing MP's SelectionBoxPatch
patch. Using the vanilla method as-is should be compatible by default, using a transpiler on vanilla method/using a reverse patch would require minor patches, while re-implementing the vanilla method (the current approach) would require extracting part of it into a separate method for improved compatibility (to allow easier patches to the MP method).
Due to multiple possible solutions to this, I'm not making a PR just yet. I'll be able to do it once we decide on the solution we want to take, assuming we decide to change how this works. @Zetrith is this something you think we should change? Any specific way you'd like this implemented?
The last solution seems like the least amount of work to make (especially since I've already included it as an example implementation earlier), as well to maintain (as we likely won't have to worry about much) - so if I were to make the choice, I'd pick that specific solution.