v0.2.4 - MapEnhancer version detection
Probe for version-specific types at startup to determine which MapEnhancer build is installed, then gray out features unavailable in that build. Three tiers: official v1.5.2 (minimal), v1.6.0 (adds turntable markers), and the community fork (full feature set). Detection uses type probes - TurntableHelper for the v1.6.0+ tier, SwitchResetAuditState for community. Adds HasTurntable and IsCommunity capability flags on MapEnhancerBridge, imMEHasTurntable/imMECommunity atomics on PopoutWindow, and a two-arg RRPOPOUT_SetMapEnhancerCaps export. The renderer reads both flags and wraps community-only menu items in BeginDisabled blocks accordingly. Updates README with version compatibility notes and comparison screenshots.
This commit is contained in:
parent
4391d96e70
commit
c8918851aa
11 changed files with 74 additions and 4 deletions
|
|
@ -2,7 +2,7 @@
|
|||
"Id": "S3",
|
||||
"DisplayName": "S³ - Seton's Special Sauce",
|
||||
"Author": "seton",
|
||||
"Version": "0.2.3",
|
||||
"Version": "0.2.4",
|
||||
"ManagerVersion": "0.27.0",
|
||||
"GameVersionPoint": "0",
|
||||
"AssemblyName": "S3.dll",
|
||||
|
|
|
|||
11
README.md
11
README.md
|
|
@ -74,10 +74,19 @@ Pop the map into a detached native OS window. Drag it to any monitor, resize it
|
|||
|
||||
### MapEnhancer Integration
|
||||
|
||||
If [MapEnhancer](https://github.com/Refizar08/rr-mapenhancer-fix) is installed, the toolbar gear menu expands with follow controls and a settings panel. The **Follow** submenu lets you follow the player camera, the selected locomotive, or any consist picked from a live-updated list. **Jump to Location** is also available. The **Settings** panel gives you live control over all MapEnhancer rendering options without leaving the map: marker visibility toggles, scale sliders for flares, junctions, track lines, and crossings, and bulk switch reset buttons.
|
||||
S³ auto-detects any installed version of MapEnhancer at startup with no configuration required. If MapEnhancer is installed, the toolbar gear menu expands with follow controls and a settings panel. The **Follow** submenu lets you follow the player camera, the selected locomotive, or any consist picked from a live-updated list. **Jump to Location** is also available. The **Settings** panel gives you live control over all MapEnhancer rendering options without leaving the map: marker visibility toggles, scale sliders for flares, junctions, track lines, and crossings, and bulk switch reset buttons.
|
||||
|
||||

|
||||
|
||||
Both the original official builds and the [community fork](https://github.com/Refizar08/rr-mapenhancer-fix) are supported. Features added by the community fork - turntable control, road crossing markers, passenger stop tracking, industry area colors, modded spawn points, and bulk switch reset - are grayed out when an older build is detected. All controls that the installed version supports remain fully functional.
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center"><img src="img/map/map_enhancer_full.png" alt="Community build - all features available"><br><b>Community build</b></td>
|
||||
<td align="center"><img src="img/map/map_enhancer_grayedout.png" alt="Older official build - community features grayed out"><br><b>Older build - community features grayed</b></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
---
|
||||
|
||||
## Physics Optimizer
|
||||
|
|
|
|||
BIN
img/map/map_enhancer_full.png
Normal file
BIN
img/map/map_enhancer_full.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 506 KiB |
BIN
img/map/map_enhancer_grayedout.png
Normal file
BIN
img/map/map_enhancer_grayedout.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 381 KiB |
|
|
@ -667,7 +667,9 @@ static void BuildMapUI(PopoutWindow* win, ImVec2 origin, float w, float h,
|
|||
win->inputQueue.push(ev);
|
||||
};
|
||||
|
||||
bool meOn = win->imMapEnhancerInstalled.load();
|
||||
bool meOn = win->imMapEnhancerInstalled.load();
|
||||
bool meTurntable = win->imMEHasTurntable.load(); // v1.6.0 or community
|
||||
bool meCom = win->imMECommunity.load(); // community only
|
||||
if (meOn) {
|
||||
if (ImGui::BeginMenu("Map Enhancer")) {
|
||||
if (ImGui::MenuItem("Toggle follow mode"))
|
||||
|
|
@ -709,11 +711,16 @@ static void BuildMapUI(PopoutWindow* win, ImVec2 origin, float w, float h,
|
|||
auto meBit = [&](int b) { return (meFlags & (1u << b)) != 0; };
|
||||
|
||||
// -- Markers --
|
||||
// Turntable Markers: available on v1.6.0 and community (ShowTurntableMarkers field).
|
||||
// Everything else in this block is community-only.
|
||||
ImGui::TextDisabled("Markers");
|
||||
ImGui::BeginDisabled(!meTurntable);
|
||||
{
|
||||
bool v = meBit(MB_TurntableMarkers);
|
||||
if (ImGui::MenuItem("Turntable Markers", nullptr, v)) pushMEBool(MB_TurntableMarkers, !v);
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
ImGui::BeginDisabled(!meCom);
|
||||
{
|
||||
bool v = meBit(MB_TurntableControl);
|
||||
if (ImGui::MenuItem("Turntable Control", nullptr, v)) pushMEBool(MB_TurntableControl, !v);
|
||||
|
|
@ -734,15 +741,18 @@ static void BuildMapUI(PopoutWindow* win, ImVec2 origin, float w, float h,
|
|||
bool v = meBit(MB_IndustryAreaColors);
|
||||
if (ImGui::MenuItem("Industry Area Colors", nullptr, v)) pushMEBool(MB_IndustryAreaColors, !v);
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
// -- Behavior --
|
||||
ImGui::TextDisabled("Behavior");
|
||||
ImGui::BeginDisabled(!meCom);
|
||||
{
|
||||
bool v = meBit(MB_ModdedSpawnPoints);
|
||||
if (ImGui::MenuItem("Modded Spawn Points", nullptr, v)) pushMEBool(MB_ModdedSpawnPoints, !v);
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
{
|
||||
bool v = meBit(MB_DoubleClick);
|
||||
if (ImGui::MenuItem("Require Double Click", nullptr, v)) pushMEBool(MB_DoubleClick, !v);
|
||||
|
|
@ -776,6 +786,7 @@ static void BuildMapUI(PopoutWindow* win, ImVec2 origin, float w, float h,
|
|||
if (ImGui::IsItemDeactivatedAfterEdit())
|
||||
pushMEFloat(MF_TrackThickness, win->imMETrackThick.load());
|
||||
}
|
||||
ImGui::BeginDisabled(!meCom);
|
||||
{
|
||||
float v = win->imMECrossingSc.load();
|
||||
ImGui::SetNextItemWidth(110.f);
|
||||
|
|
@ -784,15 +795,18 @@ static void BuildMapUI(PopoutWindow* win, ImVec2 origin, float w, float h,
|
|||
if (ImGui::IsItemDeactivatedAfterEdit())
|
||||
pushMEFloat(MF_CrossingScale, win->imMECrossingSc.load());
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
// -- Switch Reset --
|
||||
// -- Switch Reset (community build only) --
|
||||
ImGui::BeginDisabled(!meCom);
|
||||
ImGui::TextDisabled("Switch Reset");
|
||||
if (ImGui::MenuItem("All Switches - Normal"))
|
||||
pushCmd(UICmd::MEResetSwitchesNormal);
|
||||
if (ImGui::MenuItem("All Switches - Thrown"))
|
||||
pushCmd(UICmd::MEResetSwitchesThrown);
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -209,6 +209,17 @@ void RRPOPOUT_SetMapEnhancerInstalled(int windowHandle, bool installed) {
|
|||
if (win) win->imMapEnhancerInstalled.store(installed);
|
||||
}
|
||||
|
||||
// Set ME capability flags.
|
||||
// hasTurntable — ShowTurntableMarkers field exists (v1.6.0 or community); gates Turntable Markers toggle.
|
||||
// community — full community build (crossing/spawn/switch-reset); gates all other community items.
|
||||
extern "C" __declspec(dllexport)
|
||||
void RRPOPOUT_SetMapEnhancerCaps(int windowHandle, bool hasTurntable, bool community) {
|
||||
PopoutWindow* win = GetPopoutWindow(windowHandle);
|
||||
if (!win) return;
|
||||
win->imMEHasTurntable.store(hasTurntable);
|
||||
win->imMECommunity.store(community);
|
||||
}
|
||||
|
||||
// Tell native whether panning the map should cancel follow mode (for the gear menu checkmark).
|
||||
extern "C" __declspec(dllexport)
|
||||
void RRPOPOUT_SetPanDisablesFollow(int windowHandle, bool active) {
|
||||
|
|
|
|||
|
|
@ -75,6 +75,8 @@ struct PopoutWindow {
|
|||
std::atomic<float> imMapZoom {500.f};
|
||||
std::atomic<bool> imMapSyncPlayer {false};
|
||||
std::atomic<bool> imMapEnhancerInstalled {false};
|
||||
std::atomic<bool> imMEHasTurntable {false}; // true if ShowTurntableMarkers exists (v1.6.0 or community)
|
||||
std::atomic<bool> imMECommunity {false}; // true = community build (has crossing/spawn/switch-reset)
|
||||
std::atomic<bool> imFollowPlayer {false};
|
||||
std::atomic<bool> imAlwaysOnTop {false};
|
||||
std::atomic<bool> imPanDisablesFollow {true};
|
||||
|
|
|
|||
|
|
@ -696,6 +696,7 @@ internal sealed class UiHost : MonoBehaviour
|
|||
_locationsSent = false;
|
||||
_lastStatus = "";
|
||||
Native.RRPOPOUT_SetMapEnhancerInstalled(_overlayHandle, MapEnhancerBridge.IsInstalled);
|
||||
Native.RRPOPOUT_SetMapEnhancerCaps(_overlayHandle, MapEnhancerBridge.HasTurntable, MapEnhancerBridge.IsCommunity);
|
||||
Native.RRPOPOUT_SetMapRotation(_overlayHandle, 0f);
|
||||
Native.RRPOPOUT_SetMapSyncPlayer(_overlayHandle, false);
|
||||
Native.RRPOPOUT_SetFollowPlayer(_overlayHandle, false);
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ namespace S3.Modules.Popout {
|
|||
_mapCamEulerZ = _mapCamera.transform.eulerAngles.z;
|
||||
|
||||
Native.RRPOPOUT_SetMapEnhancerInstalled(_windowHandle, MapEnhancerBridge.IsInstalled);
|
||||
Native.RRPOPOUT_SetMapEnhancerCaps(_windowHandle, MapEnhancerBridge.HasTurntable, MapEnhancerBridge.IsCommunity);
|
||||
Native.RRPOPOUT_SetPanDisablesFollow(_windowHandle, PopoutModule.Settings.panDisablesFollow);
|
||||
Native.RRPOPOUT_SetRightClickRecenter(_windowHandle, PopoutModule.Settings.rightClickRecenter);
|
||||
Native.RRPOPOUT_SetOverlayMapBgAlpha(PopoutModule.Settings.overlayMapBgAlpha);
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ namespace S3.Modules.Popout {
|
|||
internal static class MapEnhancerBridge {
|
||||
|
||||
private static bool? _installed;
|
||||
private static bool? _isCommunity;
|
||||
private static MonoBehaviour? _instance;
|
||||
private static object? _meSettings;
|
||||
|
||||
|
|
@ -53,6 +54,31 @@ namespace S3.Modules.Popout {
|
|||
}
|
||||
}
|
||||
|
||||
// True if ShowTurntableMarkers exists — present in v1.6.0 (lstealth) and community,
|
||||
// but NOT in the original official v1.5.2 (mricher-git). Gates the Turntable Markers toggle.
|
||||
public static bool HasTurntable {
|
||||
get {
|
||||
if (_hasTurntable.HasValue) return _hasTurntable.Value;
|
||||
if (!IsInstalled) { _hasTurntable = false; return false; }
|
||||
_hasTurntable = Type.GetType("MapEnhancer.TurntableHelper, MapEnhancer") != null;
|
||||
return _hasTurntable.Value;
|
||||
}
|
||||
}
|
||||
private static bool? _hasTurntable;
|
||||
|
||||
// True if this is the Refizar08 community build — adds crossing/spawn/switch-reset
|
||||
// features absent from both official builds. Detected by SwitchResetAuditState,
|
||||
// a type that only exists in that fork.
|
||||
public static bool IsCommunity {
|
||||
get {
|
||||
if (_isCommunity.HasValue) return _isCommunity.Value;
|
||||
if (!IsInstalled) { _isCommunity = false; return false; }
|
||||
_isCommunity = Type.GetType("MapEnhancer.SwitchResetAuditState, MapEnhancer") != null;
|
||||
S3.Core.Log.Info($"[S3] MapEnhancer: HasTurntable={HasTurntable} IsCommunity={_isCommunity.Value}");
|
||||
return _isCommunity.Value;
|
||||
}
|
||||
}
|
||||
|
||||
// Current value of the private mapFollowMode field.
|
||||
public static bool FollowMode {
|
||||
get {
|
||||
|
|
|
|||
|
|
@ -123,6 +123,12 @@ namespace S3.Modules.Popout {
|
|||
[DllImport(Dll, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void RRPOPOUT_SetMapEnhancerInstalled(int windowHandle, bool installed);
|
||||
|
||||
// Push ME capability flags to native.
|
||||
// hasTurntable — ShowTurntableMarkers exists (v1.6.0 or community); gates Turntable Markers.
|
||||
// community — full community build (crossing/spawn/switch-reset); gates community items.
|
||||
[DllImport(Dll, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void RRPOPOUT_SetMapEnhancerCaps(int windowHandle, bool hasTurntable, bool community);
|
||||
|
||||
// Update the compass display to reflect the current map rotation (degrees).
|
||||
[DllImport(Dll, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void RRPOPOUT_SetMapRotation(int windowHandle, float degrees);
|
||||
|
|
|
|||
Loading…
Reference in a new issue