ICustomhudManager
On-screen text, prompts, toasts, announcements, countdowns, status chips, progress bars, hit feedback, an event feed and overlays on the Panorama HUD.
Text a plugin puts on a player's screen used to be a point_worldtext parented to the pawn or a center HTML print redrawn every tick. This interface draws it with a custom_hud_layout instead: crisp, positioned by the stylesheet, per player, and gone when its time is up. The layout entities (created on first use, per map) and the per-player state belong to the interface; a plugin calls ShowText() and forgets about it.
Served by the s2t_hud plugin, not the core: it is not filled by SOURCE2MOD_SAVEVARS(). Fetch it once every plugin is loaded:
void MyPlugin::OnAllSource2ModPluginsLoaded() { int ret; GET_SOURCE2MOD_IFACE(g_pCustomhudManager, ICustomhudManager, CUSTOMHUD_MANAGER_INTERFACE_VERSION, ret); }
and treat a null g_pCustomhudManager as "no HUD" (the plugin is not installed, or it is older than this header). The HudMenu below is a menu drawn by the same plugin through the core's menu system (ISource2ModMenus::OpenMenu).
What the client needs: the layouts "s2t_hud" (texts) and "s2t_menu" (menus), compiled into an addon the players have -- see panorama/README.md in Source2Mod repository, which ships the reference layouts and stylesheets. A layout has to follow the id contract below; the stylesheet is free.
Layout contract (panel ids the plugin addresses):
hud_top, hud_topleft, hud_topright, hud_left, hud_right, hud_center, hud_bottom, hud_panel one Panel per HudSlot; the core toggles the class show and one colour class (c-white .. c-grey, see HudColor) and one size class (s-small .. s-huge, HudSize) and the offset classes xm10 .. xp10 and ym10 .. yp10 (HudTextStyle::offsetX/Y) <slot>_text a Label inside it with text="{s:text}" hud_prompt the interaction prompt Panel (show) hud_prompt_key Label text="{s:text}": the key, e.g. "E" hud_prompt_text Label text="{s:text}": what the key does hud_prompt_barwrap Panel shown (show) while a progress is given hud_prompt_bar Panel that gets one of w0 .. w20 (5 % steps) hud_toast_0 .. hud_toast_3 toast cards, newest first (show, t-* of HudToastStyle, in-a / in-b to restart the entrance) hud_toast_N_title, _text Labels text="{s:text}" hud_announce the announcement (show, c-, in-a / in-b) hud_announce_title, _sub Labels text="{s:text}" hud_countdown the countdown (show, c-, pop-a / pop-b per tick) hud_countdown_text Label text="{s:text}" hud_status the chip row (show) hud_status_0 .. hud_status_3 chips (show, c-) hud_status_N_label, _value Labels text="{s:text}" hud_progress the bar (show, c-) hud_progress_label, _value Labels text="{s:text}" hud_progress_bar Panel with w0 .. w20 hud_hitmarker crosshair flash (show, hit-a / hit-b, headshot, kill) hud_damage the number next to it (show, dmg-a / dmg-b, headshot, kill) hud_damage_text Label text="{s:text}" hud_feed the feed (show) hud_feed_0 .. hud_feed_4 rows, newest first (show, t-) hud_feed_N_time, _text Labels text="{s:text}" hud_overlay full-screen tint (show, o- of HudOverlay) hud_overlay_text Label text="{s:text}" hud_timer the big timer (show, c-, tick-a / tick-b per call) hud_timer_tag, _num, _sub Labels text="{s:text}": the pill, the time, the line under it hud_card the corner card (show, c-) hud_card_tag, _title, _sub Labels text="{s:text}"
Everything is per player: what one player sees, nobody else does.
Interface id ICustomhudManager001 (CUSTOMHUD_MANAGER_INTERFACE_VERSION) · Global g_pCustomhudManager (declared by your plugin) · Header public/ICustomhudManager.h in the CustomhudManager_s2t repository
Methods
IsAvailable
virtual bool IsAvailable() = 0;Whether the text layout exists for the running map.
False before the first map, after the entity failed to spawn (logged once), or when the client would draw nothing anyway is not something the server can tell -- a player without the addon simply sees no text.
ShowText
virtual void ShowText(CCSPlayerController* player, HudSlot slot, const char* text, float seconds, HudTextStyle style = {}) = 0;Shows a text in a slot for one player, replacing what was there.
| Parameter | Type | Default | Description |
|---|---|---|---|
player | CCSPlayerController* | Who sees it | |
slot | HudSlot | Where | |
text | const char* | Plain text; "\n" starts a new line, there is no markup | |
seconds | float | How long, 0 or less: until HideText() | |
style | HudTextStyle | {} | Colour, size and the offset from the slot's place |
HideText
virtual void HideText(CCSPlayerController* player, HudSlot slot) = 0;Clears one slot for one player.
| Parameter | Type |
|---|---|
player | CCSPlayerController* |
slot | HudSlot |
ShowPrompt
virtual void ShowPrompt(CCSPlayerController* player, const char* key, const char* text, float progress = -1.0f) = 0;Shows the interaction prompt: a key cap and what it does.
| Parameter | Type | Default | Description |
|---|---|---|---|
player | CCSPlayerController* | Who sees it | |
key | const char* | The key, e.g. "E" | |
text | const char* | e.g. "Steal the weapon" | |
progress | float | -1.0f | 0..1 draws a progress bar; below 0 hides the bar |
HidePrompt
virtual void HidePrompt(CCSPlayerController* player) = 0;| Parameter | Type |
|---|---|
player | CCSPlayerController* |
HideAll
virtual void HideAll(CCSPlayerController* player) = 0;Every slot, the prompt and everything below, for one player.
| Parameter | Type |
|---|---|
player | CCSPlayerController* |
LayoutName
virtual const char* LayoutName() = 0;The layout name the core uses (HudTextLayout in core.json).
ShowToast
virtual void ShowToast(CCSPlayerController* player, HudToastStyle style, const char* title, const char* text, float seconds) = 0;A toast: a card in the stack at the top right, newest first.
Four are kept; a fifth pushes the oldest out. Each goes away after its own time.
| Parameter | Type | Description |
|---|---|---|
player | CCSPlayerController* | Who sees it |
style | HudToastStyle | Its colour and the edge (HudToastStyle) |
title | const char* | One line, bold |
text | const char* | The message under it, may wrap; "" for none |
seconds | float | How long, 0 or less: until ClearToasts() or pushed out |
ClearToasts
virtual void ClearToasts(CCSPlayerController* player) = 0;| Parameter | Type |
|---|---|
player | CCSPlayerController* |
ShowAnnounce
virtual void ShowAnnounce(CCSPlayerController* player, const char* title, const char* subtitle, float seconds, HudColor color = HudColor::White) = 0;The big announcement in the upper centre: a title and a line under it, with an entrance animation each time.
| Parameter | Type | Default | Description |
|---|---|---|---|
player | CCSPlayerController* | ||
title | const char* | ||
subtitle | const char* | ||
seconds | float | How long, 0 or less: until HideAnnounce() | |
color | HudColor | HudColor::White |
HideAnnounce
virtual void HideAnnounce(CCSPlayerController* player) = 0;| Parameter | Type |
|---|---|
player | CCSPlayerController* |
ShowCountdown
virtual void ShowCountdown(CCSPlayerController* player, const char* text, float seconds, HudColor color = HudColor::White) = 0;The giant centre number or word: "3", "2", "1", "GO". Each call pops it again, so a countdown is one call a second.
| Parameter | Type | Default | Description |
|---|---|---|---|
player | CCSPlayerController* | ||
text | const char* | ||
seconds | float | How long this text stays, 0 or less: until HideCountdown() | |
color | HudColor | HudColor::White |
HideCountdown
virtual void HideCountdown(CCSPlayerController* player) = 0;| Parameter | Type |
|---|---|
player | CCSPlayerController* |
ShowStatus
virtual void ShowStatus(CCSPlayerController* player, int chip, const char* label, const char* value, HudColor color = HudColor::White) = 0;A status chip in the row under the round timer: a small label and a value. Stays until hidden.
| Parameter | Type | Default | Description |
|---|---|---|---|
player | CCSPlayerController* | ||
chip | int | 0 .. 3, left to right | |
label | const char* | ||
value | const char* | ||
color | HudColor | HudColor::White |
HideStatus
virtual void HideStatus(CCSPlayerController* player, int chip) = 0;One chip, or every chip with a negative index.
| Parameter | Type |
|---|---|
player | CCSPlayerController* |
chip | int |
ShowProgress
virtual void ShowProgress(CCSPlayerController* player, const char* label, const char* value, float progress, HudColor color = HudColor::White) = 0;A labelled progress bar under the crosshair. Stays until hidden; call again to move the bar.
| Parameter | Type | Default | Description |
|---|---|---|---|
player | CCSPlayerController* | ||
label | const char* | ||
value | const char* | Text at the right end of the label row, e.g. "7 s"; "" for none | |
progress | float | 0..1 | |
color | HudColor | HudColor::White |
HideProgress
virtual void HideProgress(CCSPlayerController* player) = 0;| Parameter | Type |
|---|---|
player | CCSPlayerController* |
ShowHit
virtual void ShowHit(CCSPlayerController* player, int damage, bool headshot, bool kill) = 0;Hit feedback: the crosshair flashes and the damage drifts up next to it, gold on a headshot, red on a kill. Gone by itself.
| Parameter | Type | Description |
|---|---|---|
player | CCSPlayerController* | |
damage | int | 0 or less: the flash alone |
headshot | bool | |
kill | bool |
AddFeed
virtual void AddFeed(CCSPlayerController* player, HudToastStyle style, const char* time, const char* text, float seconds) = 0;A row in the event feed at the top left, newest first. Five are kept; a sixth pushes the oldest out.
| Parameter | Type | Description |
|---|---|---|
player | CCSPlayerController* | |
style | HudToastStyle | |
time | const char* | The short text at the left, e.g. "12:04" or "R3"; "" for none |
text | const char* | |
seconds | float | How long the row stays, 0 or less: until ClearFeed() or pushed out |
ClearFeed
virtual void ClearFeed(CCSPlayerController* player) = 0;| Parameter | Type |
|---|---|
player | CCSPlayerController* |
ShowOverlay
virtual void ShowOverlay(CCSPlayerController* player, HudOverlay overlay, const char* text, float seconds) = 0;A full-screen tint: poison, burn, freeze, heal, a white-out or a fade to black, with an optional centred label.
| Parameter | Type | Description |
|---|---|---|
player | CCSPlayerController* | |
overlay | HudOverlay | |
text | const char* | |
seconds | float | How long, 0 or less: until HideOverlay() |
HideOverlay
virtual void HideOverlay(CCSPlayerController* player) = 0;| Parameter | Type |
|---|---|
player | CCSPlayerController* |
OpenMenu
virtual void OpenMenu(PluginId owner, CCSPlayerController* player, HudMenu* menu) = 0;Opens a HudMenu for a player, on the Panorama HUD.
Goes through the core's menu system (ISource2ModMenus::OpenMenu), so it closes the player's other menu, takes the number keys and the clicks, and is closed for you when owner unloads. Draws nothing for a player without the layout; where that cannot be assumed, a CenterHtmlMenu is the fallback.
| Parameter | Type | Description |
|---|---|---|
owner | PluginId | Plugin the menu belongs to |
player | CCSPlayerController* | Target player |
menu | HudMenu* | The menu; must outlive the time it is open |
ShowTimer
virtual void ShowTimer(CCSPlayerController* player, const char* tag, const char* time, const char* sub, HudColor color) = 0;The big timer: a tag pill, a large time and a line under it, with a halo in the colour; each call pulses the number.
A countdown is one call a second with the new time; the caller keeps the clock. Stays until HideTimer().
| Parameter | Type | Description |
|---|---|---|
player | CCSPlayerController* | Who sees it |
tag | const char* | The pill above the number, e.g. "FREE DAY"; "" for none |
time | const char* | The number, e.g. "2:45" |
sub | const char* | The line under it; "" for none |
color | HudColor | The halo and the number |
HideTimer
virtual void HideTimer(CCSPlayerController* player) = 0;| Parameter | Type |
|---|---|
player | CCSPlayerController* |
ShowCard
virtual void ShowCard(CCSPlayerController* player, const char* tag, const char* title, const char* sub, HudColor color) = 0;The corner card: a tag, a title and a subtitle in a box at the top left -- the day of a jail, the role of a player, the mode.
Stays until HideCard(); a new call replaces the texts in place.
| Parameter | Type | Description |
|---|---|---|
player | CCSPlayerController* | Who sees it |
tag | const char* | Small line above the title, e.g. "DAY 3"; "" for none |
title | const char* | The big line |
sub | const char* | The line under it; "" for none |
color | HudColor | The edge and the tag |
HideCard
virtual void HideCard(CCSPlayerController* player) = 0;| Parameter | Type |
|---|---|
player | CCSPlayerController* |
HudTextStyle
Fields
| Field | Type | Description |
|---|---|---|
color | HudColor | |
size | HudSize | |
offsetX | int | Where the slot sits, relative to the place the stylesheet gives it: steps of 40 px on a 1080p reference, -10..10, positive is right and down. Classes xm10..xp10 / ym10..yp10 on the slot panel; a value outside the range is clamped. |
offsetY | int |
HudMenu
A menu drawn with a custom_hud_layout (ICustomhudManager::OpenMenu).
The same options and handlers as CenterHtmlMenu; only the screen differs. The player clicks the rows or presses 1-6 (the options of the page), 7 (previous page), 8 (next page), 9 (close), so the chat triggers keep working. The navigation texts are the plugin's, which is how they get to be in the player's language.
Needs the menu layout ("s2t_menu"; the reference layout is panorama/layout/custom_game/s2t_menu.xml in Source2Mod repository) in an addon the player has. A player without it sees nothing.
Inherits IBaseMenu
Fields
| Field | Type | Description |
|---|---|---|
PrevText | std::string | |
NextText | std::string | |
CloseText | std::string | |
DimBackground | bool | Dims the screen behind the menu. |
CaptureInput | bool | With input capture the player gets a cursor and can click the rows, but cannot move or aim while the menu is open. Without it the menu is display-only: the number keys (binds, chat triggers) pick the options and the player keeps playing. Per menu, so a plugin can make it the player's choice. |
CaptureWhenDead | bool | A dead player cannot use the slot binds (they do nothing without a pawn), so a menu without CaptureInput takes the mouse for as long as the player is dead and lets go on respawn. The keys and the chat triggers keep working meanwhile; the clicks are added, not swapped in. |
Position | HudMenuPosition | Where the window sits: one of the classes pos-left, pos-center, pos-right goes on menu_root and the stylesheet places it. |
Constructors
explicit HudMenu(std::string title);Enums
HudSlot
enum class HudSlot : intWhere on the screen a text goes. Each is a panel of the layout; the stylesheet decides where that panel is.
| Name | Value | Description |
|---|---|---|
Top | 0 | top centre -- announcements |
TopLeft | ||
TopRight | ||
Left | left of the crosshair | |
Right | right of the crosshair | |
Center | over the crosshair -- countdowns, "START" | |
Bottom | above the weapon HUD | |
Panel | a boxed multi-line panel (quests, info) | |
Count |
HudColor
enum class HudColor : intThe colour classes the stylesheet defines (c-white, c-red, ...).
| Name | Value |
|---|---|
White | 0 |
Red | |
Green | |
Blue | |
Yellow | |
Orange | |
Purple | |
Cyan | |
Grey | |
Count |
HudSize
enum class HudSize : intThe size classes the stylesheet defines (s-small, s-normal, ...).
| Name | Value |
|---|---|
Small | 0 |
Normal | |
Large | |
Huge | |
Count |
HudToastStyle
enum class HudToastStyle : intThe toast and feed styles (t-info, t-success, ...).
| Name | Value |
|---|---|
Info | 0 |
Success | |
Warning | |
Danger | |
Neutral | |
Count |
HudOverlay
enum class HudOverlay : intThe full-screen overlays (o-poison, o-burn, ...).
| Name | Value | Description |
|---|---|---|
Poison | 0 | |
Burn | ||
Freeze | ||
Heal | ||
Blind | white-out | |
Black | fade to black, with an optional label | |
Count |
HudMenuPosition
enum class HudMenuPosition : intWhere on the screen a HudMenu is drawn; a class on the layout's menu_root.
| Name | Value |
|---|---|
Left | 0 |
Center | |
Right |
Macros
| Macro | Expands to |
|---|
HUD Menus, Texts and Prompts
Menus, on-screen text and HUD elements drawn by Panorama through the CustomhudManager_s2t plugin — HudMenu, ICustomhudManager, the reference layouts and the addon that ships them.
Layouts
Creating a custom_hud_layout with CCSCustomHudLayout, global and per-player state, toggling CSS classes, setting dialog variables and capturing the mouse.