Skip to content

Commit

Permalink
Fix #410, update MP selector drawing (#417)
Browse files Browse the repository at this point in the history
Due to absence of any discussion around the issue and the approach for the solution, I've decided to just make a PR with one possible solution that I deemed the most straightforward.

The solution uses Vanilla `SelectionDrawer.DrawSelectionBracketFor` while providing the specific material, which will handle the color. The method was likely changed in 1.4 to support custom materials due to the need of custom colors for the selector due to storage groups.

The materials are stored inside of `PlayerInfo` object. The materials are created using `MaterialPool.MatFrom`, so they should be cached by the game (and will be re-used if a player leaves and rejoins).

`MaterialPropertyBlock` could no longer be used here due to the Vanilla method not using it, as it instead opted into using `Material` to override the default one.

As for performance, a slight hit is unavoidable due to the current handling not being fully complete, skipping couple of cases (mentioned in the referenced issue).

This is also compatible with Vehicle Framework, as its prefix to `SelectionDrawer.DrawSelectionBracketFor` will be actually used by MP to draw diagonal selection boxes around vehicles (instead of only rectangular ones, even if vehicle is driving diagonally).
  • Loading branch information
SokyranTheDragon authored Feb 3, 2024
1 parent 257f355 commit 601f3cf
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 17 deletions.
2 changes: 2 additions & 0 deletions Source/Client/Session/PlayerInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public class PlayerInfo : IPlayerInfo
public PlayerType type;
public PlayerStatus status;
public Color color;
public Material selectionBracketMaterial;
public int factionId;

public ulong steamId;
Expand Down Expand Up @@ -83,6 +84,7 @@ public static PlayerInfo Read(ByteReader data)
steamId = steamId,
steamPersonaName = steamName,
color = color,
selectionBracketMaterial = MaterialPool.MatFrom("UI/Overlays/SelectionBracket", ShaderDatabase.MetaOverlay, color * new Color(1, 1, 1, 0.5f)),
ticksBehind = ticksBehind,
simulating = simulating,
factionId = factionId
Expand Down
34 changes: 17 additions & 17 deletions Source/Client/UI/CursorPatches.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,6 @@ static void Postfix()
[StaticConstructorOnStartup]
static class SelectionBoxPatch
{
static Material graySelection = MaterialPool.MatFrom("UI/Overlays/SelectionBracket", ShaderDatabase.MetaOverlay);
static MaterialPropertyBlock propBlock = new MaterialPropertyBlock();
static HashSet<int> drawnThisUpdate = new HashSet<int>();
static Dictionary<object, float> selTimes = new Dictionary<object, float>();

Expand All @@ -76,28 +74,31 @@ static void Postfix()
foreach (var t in Find.Selector.SelectedObjects.OfType<Thing>())
drawnThisUpdate.Add(t.thingIDNumber);

foreach (var player in Multiplayer.session.players)
var tempTimes = SelectionDrawer.selectTimes;
try
{
if (player.factionId != Multiplayer.RealPlayerFaction.loadID) continue;
SelectionDrawer.selectTimes = selTimes;

foreach (var sel in player.selectedThings)
foreach (var player in Multiplayer.session.players)
{
if (!drawnThisUpdate.Add(sel.Key)) continue;
if (!ThingsById.thingsById.TryGetValue(sel.Key, out Thing thing)) continue;
if (thing.Map != Find.CurrentMap) continue;
if (player.factionId != Multiplayer.RealPlayerFaction.loadID) continue;

selTimes[thing] = sel.Value;
SelectionDrawerUtility.CalculateSelectionBracketPositionsWorld(SelectionDrawer.bracketLocs, thing, thing.DrawPos, thing.RotatedSize.ToVector2(), selTimes, Vector2.one, 1f);
selTimes.Clear();

for (int i = 0; i < 4; i++)
foreach (var sel in player.selectedThings)
{
Quaternion rotation = Quaternion.AngleAxis(-i * 90, Vector3.up);
propBlock.SetColor("_Color", player.color * new Color(1, 1, 1, 0.5f));
Graphics.DrawMesh(MeshPool.plane10, SelectionDrawer.bracketLocs[i], rotation, graySelection, 0, null, 0, propBlock);
if (!drawnThisUpdate.Add(sel.Key)) continue;
if (!ThingsById.thingsById.TryGetValue(sel.Key, out Thing thing)) continue;
if (thing.MapHeld != Find.CurrentMap) continue;

selTimes[thing] = sel.Value;
SelectionDrawer.DrawSelectionBracketFor(thing, player.selectionBracketMaterial);
selTimes.Clear();
}
}
}
finally
{
SelectionDrawer.selectTimes = tempTimes;
}

drawnThisUpdate.Clear();
}
Expand Down Expand Up @@ -130,5 +131,4 @@ static void Prefix(ref string str)
str += $"\nSelected by: {players.Join()}";
}
}

}

0 comments on commit 601f3cf

Please sign in to comment.