Skip to content

Feature Request: Toggle (multi-)class position reporting #112

Description

@andrewmackrodt

When driving in a multi-class event, the position shown is the overall position / total count. It would be useful to have a checkbox in the settings which changes the reporting to show the class position / class total count.

It seems that SimHub does not export this metric explicitly but some dashboards like Lovely Dashboard are able to display this. It may be being pulled from ATSRHubMain, or something like this may be possible (AI generated):

/// <summary>
/// Calculates the player's current position within their car class 
/// and the total count of opponents sharing that same class.
/// </summary>
/// <param name="pluginManager">The active SimHub PluginManager instance.</param>
/// <returns>A tuple containing (ClassPosition, TotalInClass)</returns>
public (int classPosition, int totalInClass) GetPlayerClassMetrics(PluginManager pluginManager)
{
    // Access the unified GameData object populated by DataCorePlugin
    var gameData = pluginManager.LastKnownAllGameData?.GameData;

    // Ensure valid data and an active opponent/driver roster
    if (gameData?.NewData == null || gameData.Opponents == null || gameData.Opponents.Count == 0)
    {
        return (1, 1); // Fallback to P1 out of 1 when running solo or out of a session
    }

    // 1. Identify the player's specific class identifier string
    string playerClass = gameData.NewData.CarClass;

    // Handle edge cases where the game or SimHub doesn't provide a class name
    if (string.IsNullOrWhiteSpace(playerClass))
    {
        // Fallback: If no class metadata exists, treat the field as a single-class race
        return (gameData.NewData.Position, gameData.Opponents.Count);
    }

    // 2. Filter all track entities matching the player's exact class
    // This includes both the player's car and any other same-class opponents
    var sameClassGrid = gameData.Opponents
        .Where(opp => opp.CarClass == playerClass)
        .OrderBy(opp => opp.Position) // Ordered by overall track placement numerical value
        .ToList();

    // 3. Count total class entrants
    int totalInClass = sameClassGrid.Count;

    // 4. Determine the player's rank relative to that specific filtered set
    // SimHub's gameData.Opponents collection usually embeds the player entity. 
    // We verify by matching the 'IsPlayer' flag.
    int playerClassIndex = sameClassGrid.FindIndex(opp => opp.IsPlayer);

    int classPosition;
    if (playerClassIndex != -1)
    {
        // Convert 0-indexed list pointer to 1-based sport ranking
        classPosition = playerClassIndex + 1;
    }
    else
    {
        // Fallback calculation pattern in case the player object is omitted from the collection:
        // Count how many opponents in the same class have a better overall placement position value.
        classPosition = sameClassGrid.Count(opp => opp.Position < gameData.NewData.Position) + 1;
    }

    return (classPosition, totalInClass);
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions