Modular panel and API for displaying information to the players on their HUD

Supported Games
GameServerKingsGameServerKings

About

Magic Panel is a 100% API driven panel display plugin for Rust. Each panel is a separate plugin that will register how that panel will function. Panels dynamically position themselves within a dock based on the dock assigned and the order specified.

Configuration

Config location

The config for MagicPanel and all associated panels can be found in the following path: oxide/config/MagicPanel/MagicPanel.json

Default Configuration

{
  "Chat Command": "mp",
  "Use Image Library": true,
  "Parent UI Layer (Overlay, Hud.Menu, Hud, Under)": "Overlay",
  "Text Outline Settings": {
    "Enable Text Outline": false,
    "Text Outline Color": "#000000FF",
    "Text Outline Distance": "0.5 -0.5"
  },
  "Docks": {
    "lefttop": {
      "Position": {
        "X Position": 0.07,
        "Y Start Position": 0.072,
        "Height": 0.035
      },
      "Enabled": true,
      "Background Color": "#00000000",
      "Panel Alignment (Left, Center, Right)": "Left",
      "Panel Padding": 0.004,
      "Dock Padding": {
        "Left": 0.001,
        "Right": 0.001,
        "Top": 0.0,
        "Bottom": 0.0
      }
    },
    "leftmiddle": {
      "Position": {
        "X Position": 0.07,
        "Y Start Position": 0.036,
        "Height": 0.035
      },
      "Enabled": true,
      "Background Color": "#00000000",
      "Panel Alignment (Left, Center, Right)": "Left",
      "Panel Padding": 0.004,
      "Dock Padding": {
        "Left": 0.001,
        "Right": 0.001,
        "Top": 0.0,
        "Bottom": 0.0
      }
    },
    "leftbottom": {
      "Position": {
        "X Position": 0.07,
        "Y Start Position": 0.0,
        "Height": 0.035
      },
      "Enabled": true,
      "Background Color": "#00000000",
      "Panel Alignment (Left, Center, Right)": "Left",
      "Panel Padding": 0.004,
      "Dock Padding": {
        "Left": 0.001,
        "Right": 0.001,
        "Top": 0.0,
        "Bottom": 0.0
      }
    },
    "image": {
      "Position": {
        "X Position": 0.65,
        "Y Start Position": 0.0,
        "Height": 0.1
      },
      "Enabled": true,
      "Background Color": "#00000000",
      "Panel Alignment (Left, Center, Right)": "Left",
      "Panel Padding": 0.004,
      "Dock Padding": {
        "Left": 0.001,
        "Right": 0.001,
        "Top": 0.0,
        "Bottom": 0.0
      }
    },
    "center": {
      "Position": {
        "X Position": 0.644,
        "Y Start Position": 0.109,
        "Height": 0.035
      },
      "Enabled": true,
      "Background Color": "#00000000",
      "Panel Alignment (Left, Center, Right)": "Right",
      "Panel Padding": 0.004,
      "Dock Padding": {
        "Left": 0.001,
        "Right": 0.001,
        "Top": 0.0,
        "Bottom": 0.0
      }
    },
    "centerupper": {
      "Position": {
        "X Position": 0.4966,
        "Y Start Position": 0.145,
        "Height": 0.035
      },
      "Enabled": true,
      "Background Color": "#00000000",
      "Panel Alignment (Left, Center, Right)": "Center",
      "Panel Padding": 0.004,
      "Dock Padding": {
        "Left": 0.001,
        "Right": 0.001,
        "Top": 0.0,
        "Bottom": 0.0
      }
    },
    "bottom": {
      "Position": {
        "X Position": 0.4966,
        "Y Start Position": 0.0,
        "Height": 0.0235
      },
      "Enabled": true,
      "Background Color": "#00000000",
      "Panel Alignment (Left, Center, Right)": "Center",
      "Panel Padding": 0.004,
      "Dock Padding": {
        "Left": 0.001,
        "Right": 0.001,
        "Top": 0.0,
        "Bottom": 0.0
      }
    },
    "undercompass": {
      "Position": {
        "X Position": 0.4966,
        "Y Start Position": 0.92,
        "Height": 0.035
      },
      "Enabled": true,
      "Background Color": "#00000000",
      "Panel Alignment (Left, Center, Right)": "Center",
      "Panel Padding": 0.004,
      "Dock Padding": {
        "Left": 0.001,
        "Right": 0.001,
        "Top": 0.0,
        "Bottom": 0.0
      }
    }
  }
}

Configuration Options

MagicPanel.json Explanation

Individual Panel Config Explanation

Panel Alignment

  • Left: The x Position will be the left position for the dock
  • Center: The x Position will be the the middle of the dock
  • Right: The x Position will be the right position for the dock
    • The order of the panel will be reversed with the right most panel being the lowest order value

Dock Positioning / Size

Position

The dock postion is controlled by the X Position and Y Start Position fields in the configuration.
The values range between 0 and 1. The bottom left of the screen is X: 0, Y: 0 and the top right is X: 1, Y: 1.
The middle of the screen would be X: 0.5, Y: 0.5
The Y position is the bottom position of the dock.
The X position depends on the panel alignment.
If the panel alignment is left then it will be the left most position.
If the panel alignment is center then it will be the middle of the dock.
If the panel alignment is right then it will be the right most position of the dock.

Size

The size of the panel is control by the hight and number of panels. The height tall the dock will be and the panels will scale to this height.

The width is dynamically calculated based on the number of panels and the dock padding.

Panel Order

Panels are dynamically placed into a dock based on their order specified in each panels configuration.
This order will be left being the lowest value for both left and center.
For right alignment docks the right will be the lowest value.

Chat Commands

  • /mp - shows the magic panel help text
  • /mp off- hides all panels for the player
  • /mp on - shows all panels to the player

Localization

{
  "Chat": "<color=#bebebe>[<color=#de8732>Magic Panel</color>] {0}</color>",
  "On": "on",
  "Off": "off",
  "SettingsChanged": "All your panels are now {0}",
  "Help": "Controls the visibility of the magic panels:\n<color=#de8732>/mp on</color> shows all the magic panels\n<color=#de8732>/mp off</color> hides all the magic panels"
}

Images

Images of all panels avaliable at launch!

Developer API

There are two types of panels for Magic Panel. A global panel which displays the same data to every player and a player panel which displays data only to a specific player

Classes needed for the API

These classes are used when sending information to Magic Panel and should be added to your Panel Plugin

Registration for the API

JSON serialized and sent to Magic Panel. This tells Magic Panel information about the panel itself

private class PanelRegistration
{
    public string Dock { get; set; }
    public float Width { get; set; }
    public int Order { get; set; }
    public string BackgroundColor { get; set; }
}

Panel Class

This contains all the information how to build out the specific panel and contains the image and text information

private class Panel
{
    public PanelImage Image { get; set; }
    public PanelText Text { get; set; }
    
    public Hash<string, object> ToHash()
    {
        return new Hash<string, object>
        {
            [nameof(Image)] = Image.ToHash(),
            [nameof(Text)] = Text.ToHash()
        };
    }
}

Base Panel Class

This contains the basic information for each image and text

private abstract class PanelType
{
    public bool Enabled { get; set; }
    public string Color { get; set; }
    public int Order { get; set; }
    public float Width { get; set; }
    public TypePadding Padding { get; set; }
    
    public virtual Hash<string, object> ToHash()
    {
        return new Hash<string, object>
        {
            [nameof(Enabled)] = Enabled,
            [nameof(Color)] = Color,
            [nameof(Order)] = Order,
            [nameof(Width)] = Width,
            [nameof(Padding)] = Padding.ToHash(),
        };
    }
}

Image Panel Class

Tells Magic Panel how to display the image

private class PanelImage : PanelType
{
    public string Url { get; set; }
    
    public override Hash<string, object> ToHash()
    {
        Hash<string, object> hash = base.ToHash();
        hash[nameof(Url)] = Url;
        return hash;
    }
}

Text Panel Class

Tells magic panel how to display the text

private class PanelText : PanelType
{
    public string Text { get; set; }
    public int FontSize { get; set; }

    [JsonConverter(typeof(StringEnumConverter))]
    public TextAnchor TextAnchor { get; set; }
    
    public override Hash<string, object> ToHash()
    {
        Hash<string, object> hash = base.ToHash();
        hash[nameof(Text)] = Text;
        hash[nameof(FontSize)] = FontSize;
        hash[nameof(TextAnchor)] = TextAnchor;
        return hash;
    }
}

Type Padding

Applies padding to different parts of the panel

private class TypePadding
{
    public float Left { get; set; }
    public float Right { get; set; }
    public float Top { get; set; }
    public float Bottom { get; set; }

    public TypePadding(float left, float right, float top, float bottom)
    {
        Left = left;
        Right = right;
        Top = top;
        Bottom = bottom;
    }
    
    public Hash<string, object> ToHash()
    {
        return new Hash<string, object>
        {
            [nameof(Left)] = Left,
            [nameof(Right)] = Right,
            [nameof(Top)] = Top,
            [nameof(Bottom)] = Bottom
        };
    }
}

Update Enum

Passed into Magic Panel when updating telling it which panels should be updated

enum UpdateEnum { All = 1, Panel = 2, Image = 3, Text = 4 }

Hooks

Register Player Panel

Registers a Player panel in Magic Panel

//plugin - plugin registering the panel
//name - name of the panel (typically he name of the plugin)
//panelData - JSON serialized PanelRegistration class
//getMethodName- The Hook to call in the plugin to get the panel updates
void RegisterPlayerPanel(Plugin plugin, string name, string panelData, string getMethodName)

Register Global Panel

Registers a Global Panel in Magic Panel

//plugin - plugin registering the panel
//name - name of the panel (typically he name of the plugin)
//panelData - JSON serialized PanelRegistration class
//getMethodName- The Hook to call in the plugin to get the panel updates
void RegisterGlobalPanel(Plugin plugin, string name, string panelData, string getMethodName)

Update Global Panel

Tells Magic Panel to update the specified global panel

//panelName - Panel to update
//update - int of the UpdateEnum to update
void UpdatePanel(string panelName, int update)

Update Player Panel

Tells Magic Panel to update the specified global panel

//player - Player to update the panel for
//panelName - Name of the panel to update
//update - int of the UpdateEnum to update
void UpdatePanel(BasePlayer player, string panelName, int update)

Show Panel

Show a hidden global panel

//name - name of the hidden panel to show
void ShowPanel(string name)

Show Panel

Show a hidden player panel

//name - name of the hidden panel to show
//player - player to unhide the panel for)
void ShowPanel(BasePlayer player, string name)

Hide Panel

Hides a global panel

//name - name of the panel to hide
void HidePanel(string name)

Hide Panel

Hides a player panel

//name - name of the panel to hide
//player - layer to hide the panel for
void HidePanel(BasePlayer player , string name)

Testers

I want to thank all the testers who assisted with testing this plugin and associated panels

  • Bull
  • Supreme
  • Trey
MIT License

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.