Skip to content

Commit

Permalink
Initial release
Browse files Browse the repository at this point in the history
  • Loading branch information
dsperac committed Apr 3, 2023
1 parent 240f232 commit 689acbb
Show file tree
Hide file tree
Showing 7 changed files with 282 additions and 1 deletion.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
media/
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
# tm-auto-hide-records
# Auto-Hide Records

An Openplanet plugin for Trackmania which hides the records UI when moving.

Openplanet plugin url: https://openplanet.dev/plugin/autohiderecords

License: Public Domain
55 changes: 55 additions & 0 deletions src/GameInfo.as
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
class GameInfo {
CTrackMania@ app;

GameInfo() {
@app = cast<CTrackMania@>(GetApp());
}

CTrackManiaNetwork@ Network {
get const {
return cast<CTrackManiaNetwork>(this.app.Network);
}
// set {}
}

CGamePlayground@ CurrentPlayground {
get const {
return cast<CGamePlayground>(this.app.CurrentPlayground);
}
// set {}
}

CGameTerminal@ GameTerminal {
get {
if (this.CurrentPlayground is null
|| this.CurrentPlayground.GameTerminals.Length < 1) {
return null;
}
return this.CurrentPlayground.GameTerminals[0];
}
// set {}
}

NGameLoadProgress_SMgr@ LoadProgress {
get const {
return cast<NGameLoadProgress_SMgr>(this.app.LoadProgress);
}
// set {}
}

MwFastBuffer<CGameUILayer@> UILayers {
get const {
return this.Network.ClientManiaAppPlayground.UILayers;
}
// set {}
}

bool IsPlaying() {
auto network = Network;
auto playground = CurrentPlayground;
return playground !is null &&
network.ClientManiaAppPlayground !is null &&
network.ClientManiaAppPlayground.Playground !is null &&
network.ClientManiaAppPlayground.UILayers.Length > 0;
}
}
82 changes: 82 additions & 0 deletions src/HUDElement.as
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
class HUDElement {
string Name;
string ModuleName;
int ModuleIndex;
string SubModuleName;
bool IsVisible = true;
bool GetVisible() { return this.IsVisible; }
void SetVisible(bool v) { this.IsVisible = v; }

HUDElement(const string &in name, const string &in moduleName, const string &in subModuleName = "") {
this.Name = name;
this.ModuleName = moduleName;
this.ModuleIndex = -1;
this.SubModuleName = subModuleName;
}

void ToggleVisible() {
this.SetVisible(!this.GetVisible());
}

void FindElement(MwFastBuffer<CGameUILayer@> &in uilayers) {
for (uint i = 0; i < uilayers.Length; i++) {
CGameUILayer@ curLayer = uilayers[i];
int start = curLayer.ManialinkPageUtf8.IndexOf("<");
int end = curLayer.ManialinkPageUtf8.IndexOf(">");
if (start != -1 && end != -1) {
auto manialinkname = curLayer.ManialinkPageUtf8.SubStr(start, end);
if (manialinkname.Contains(this.ModuleName)) {
this.ModuleIndex = i;
return; // we don't need to continue further
}
}
}
this.ModuleIndex = -1;
}

bool Exists(CGameUILayer@ curLayer) {
int start = curLayer.ManialinkPageUtf8.IndexOf("<");
int end = curLayer.ManialinkPageUtf8.IndexOf(">");
if (start != -1 && end != -1) {
auto manialinkname = curLayer.ManialinkPageUtf8.SubStr(start, end);
if (manialinkname.Contains(this.ModuleName)) {
return true;
}
}
this.ModuleIndex = -1;
return false;
}

void UpdateVisibilty(CGameUILayer@ layer) {
if (this.Exists(layer)) {
if (this.ModuleName != "" && this.SubModuleName == "") {
if (this.GetVisible() != layer.IsVisible) {
layer.IsVisible = !layer.IsVisible;
}
} else if (this.ModuleName != "" && this.SubModuleName != "") {
CControlFrame@ c = cast<CControlFrame@>(layer.LocalPage.GetFirstChild(this.SubModuleName).Control);
if (c !is null) {
array<CControlFrame@> frames = { c };
while (!frames.IsEmpty()) {
auto children = frames[0].Childs;
for (uint j = 0; j < children.Length; j++) {
if (Reflection::TypeOf(children[j]).Name == "CControlFrame") {
frames.InsertLast(cast<CControlFrame@>(children[j]));
} else {
auto subModule = cast<CControlBase@>(children[j]);
if (this.GetVisible() && !subModule.IsVisible) {
subModule.Show();
} else if (!this.GetVisible() && subModule.IsVisible) {
subModule.Hide();
}
}
}
frames.RemoveAt(0);
}
} else {
error("SubModule could not be found");
}
}
}
}
}
6 changes: 6 additions & 0 deletions src/RecordHUDElement.as
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class RecordHUDElement: HUDElement {
RecordHUDElement() {
super("Records", "UIModule_Race_Record", "");
}
}
RecordHUDElement@ recordHud = RecordHUDElement();
8 changes: 8 additions & 0 deletions src/info.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[meta]
name = "Auto-Hide Records"
author = "Dr Damage"
category = "Overlay"
version = "1.0.0"

[script]
dependencies = [ "VehicleState" ]
123 changes: 123 additions & 0 deletions src/main.as
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// constants
const float SPEED_THRESHOLD = 1.0f;
const int MOUSE_MOVE_HIDE_DELAY = 3500;

// HUDPicker constants
const string HUDPICKER_ID = "HUDPicker";
const string HUDPICKER_RECORD_VISIBLE_VARNAME = "recordVisible";

// global vars
Meta::Plugin@ hudPickerPlugin = Meta::GetPluginFromID(HUDPICKER_ID);
GameInfo@ gameInfo;
float ticker = 0;

// settings definition
[Setting name="Is Enabled" category="General"]
bool AutoHideRecords = true;

// renders the setting in the plugins dropdown menu
void RenderMenu()
{
if (UI::MenuItem(Icons::EyeSlash + " " + "Auto-Hide Records", "", AutoHideRecords)) {
AutoHideRecords = !AutoHideRecords;
}
}

// HUD Picker helpers
Meta::PluginSetting@ findHudPickerRecordsVisibleSetting(array<Meta::PluginSetting@> settings) {
for (int i = 0; i < int(settings.Length); i++) {
if (
settings[i].VarName == HUDPICKER_RECORD_VISIBLE_VARNAME
&& settings[i].Type == Meta::PluginSettingType::Bool
) {
return settings[i];
}
}
return null;
}
bool IsHudPickerRecordsHidden() {
if (
hudPickerPlugin !is null
&& hudPickerPlugin.Enabled
) {
auto settings = hudPickerPlugin.GetSettings();
auto setting = findHudPickerRecordsVisibleSetting(settings);
if (setting !is null) {
bool settingValue = setting.ReadBool();
return !settingValue;
}
}
return false;
}

void UpdateTicker(float dt) {
ticker -= dt;
if (ticker < 0) {
ticker = 0;
}
}

bool ShouldRunPlugin() {
return (
AutoHideRecords // plugin has to be enabled
&& gameInfo.IsPlaying() // should be on a map
&& !IsHudPickerRecordsHidden() // don't do anything if the records element is hidden via HUD Picker
&& gameInfo.LoadProgress.State != NGameLoadProgress_SMgr::EState::Displayed // wait until playground finishes loading
);
}

void OnMouseMove(int x, int y) {
#if TMNEXT
if (!ShouldRunPlugin()) {
return;
}
ticker = MOUSE_MOVE_HIDE_DELAY;
#endif
}

// init
void Main() {
#if TMNEXT
@gameInfo = GameInfo();
#endif
}

void Update(float dt) {
#if TMNEXT
if (!ShouldRunPlugin()) {
return;
}
// if index not set or out of bounds try to find the record ui element inside the UI layers collection and store the index
if (recordHud.ModuleIndex == -1 || recordHud.ModuleIndex >= int(gameInfo.UILayers.Length)) {
recordHud.FindElement(gameInfo.UILayers);
// if not found return
if (recordHud.ModuleIndex == -1) {
return;
}
}
auto gameTerminal = gameInfo.GameTerminal;
auto uiLayer = gameInfo.UILayers[recordHud.ModuleIndex];
auto vehicleState = VehicleState::ViewingPlayerState();
float speed = 0;

if (vehicleState !is null) {
speed = vehicleState.FrontSpeed;
}


bool shouldShowHud = (
ticker > 0 // if mouse was moved
|| (
gameTerminal !is null
&& gameTerminal.UISequence_Current != CGamePlaygroundUIConfig::EUISequence::Playing // if the current game state isn't Playing
) || speed < SPEED_THRESHOLD // if the speed is less than the threshold set
);

recordHud.SetVisible(shouldShowHud);
recordHud.UpdateVisibilty(uiLayer);

if (ticker > 0) {
UpdateTicker(dt);
}
#endif
}

0 comments on commit 689acbb

Please sign in to comment.