The International Simutrans Forum

Development => Patches & Projects => Incorporated Patches and Solved Bug Reports => Topic started by: makie on July 16, 2026, 10:54:57 AM

Title: deselecting undergrund view
Post by: makie on July 16, 2026, 10:54:57 AM
If in the display settings "Re-selecting a tool de-selects it" is set
then deselecting the with the tool "underground view" in the "options menu"  is not possible.

If "Re-selecting a tool de-selects it" is not set the switch with tool "underground view" works as intended, forth and back.   

 ;D
Title: Re: deselecting undergrund view
Post by: victor_18993 on July 16, 2026, 11:32:47 AM
Confirmed. The fix is one line: the underground-view tool was missing its
exit() implementation.
Cause
tool_selector_t takes a different path when a tool reports itself as selected:
if (env_t::reselect_closes_tool && tool && tool->is_selected()) {
    if (tool->exit(welt->get_active_player())) {
        // Reset to query tool.
    }
}
else {
    welt->set_tool(tool, welt->get_active_player());
    // This path calls init().
}

The important detail is that
is_selected() has two related but different meanings in the tool system.
The base implementation of
tool_t::is_selected() checks whether the tool is the player's currently selected tool:
welt->get_tool(...) == this

However,
tool_show_underground_t overrides it to report a global display state:
grund_t::underground_mode == ugm_all

The sequence was therefore:
Fix
Tools that override
is_selected() to represent a global toggle state normally implement
exit() by invoking
init() again.
The neighbouring tools in the same file already follow that pattern:
class tool_show_grid_t : public tool_t {
    bool is_selected() const OVERRIDE { return grund_t::show_grid; }
    bool exit(player_t *s) OVERRIDE { return init(s); }
};

class tool_day_night_toggle_t : public tool_t {
    bool exit(player_t *s) OVERRIDE { return init(s); }
};

The same pattern is used by the display toggles in
simtool.h,
tool_toggle_control_t, and the tools in
simtool-dialogs.h.
tool_show_underground_t was the exception.
The complete fix is therefore:
bool exit(player_t *s) OVERRIDE { return init(s); }

This also fixes sliced underground mode, configured with
K. Its
is_selected() reports
ugm_level, and its
init() already changes
ugm_level back to
ugm_none.
Why this does not disable underground view when another tool is selected
Adding
exit() might initially suggest that selecting another construction tool would now leave underground mode. That does not happen.
karte_t::local_set_tool() only calls
exit() on the outgoing selected tool, and a tool is recorded as selected only when its
init() returns true:
bool init_result = tool_in->init(player);

if (player && init_result && !tool_in->is_scripted()) {
    sp_tool->exit(player);
    selected_tool[player->get_player_nr()] = tool_in;
}

tool_show_underground_t::init() returns
needs_click.
For the underground-view modes configured by pak64 and pak128,
needs_click is false. Their menu configurations use:
U
K
I
D

The tool therefore changes the display mode but never becomes the player's persistent selected tool. As a result, selecting a road, query or construction tool does not call its
exit() and does not leave underground view.
I also inspected the
C mode. It is the only mode that would return true, but neither pak64 nor pak128 configures it. The class also has no specialised
work() implementation, so this mode appears unused or vestigial.
The new
exit() is therefore reached through the toolbar's reselect and right-click paths, matching the behaviour already used by tools such as
tool_show_grid_t.
Scope
No other behaviour or data is modified:
is_init_keeps_game_state() already returns true, so this tool continues to be handled locally and is not queued as a network command.
Right-click behaviour
There is one intentional behaviour change worth documenting.
Previously, right-clicking the underground-view button while underground mode was active reset the active tool to the query tool but left underground view enabled.
With the new
exit(), right-clicking the button also disables underground view.
This matches the existing right-click behaviour of the dialog tools and
tool_toggle_control_t, so the underground-view tool now behaves consistently with comparable toggle tools.
If preserving the previous right-click behaviour is preferred, the fix would need to be placed specifically in the left-click reselect path instead. That would be a more specialised change than adding the missing standard
exit() implementation.
Testing
Tested in pak128 on a map containing an actual tunnel.
Pak128 contains two buttons using icon 44:
With
Re-selecting a tool de-selects it enabled:
The patch is a single-line addition to
tool_show_underground_t.
Title: Re: deselecting undergrund view
Post by: makie on July 16, 2026, 11:41:29 AM
The answer looks like it is from ai.
Title: Re: deselecting undergrund view
Post by: victor_18993 on July 16, 2026, 11:58:09 AM
Fair observation — I used AI-assisted tooling to help organise the explanation, and it ended up much longer and more formal than necessary.
The diagnosis and patch were verified against the source and tested in pak128. The actual change is only:
bool exit(player_t *s) OVERRIDE { return init(s); }

tool_show_underground_t::is_selected() reports the underground display state, so when
reselect_closes_tool is enabled, the second click calls
exit() rather than
init(). The class was missing the same
exit() pattern already used by the neighbouring toggle tools.
I will keep future reports shorter.
Title: Re: deselecting undergrund view
Post by: prissi on July 18, 2026, 06:03:06 AM
The answer is not so easy, as there are more than one underground mode, needed some more renovation. Fixed in r12088.
Title: Re: deselecting undergrund view
Post by: makie on July 18, 2026, 07:34:10 AM
Thanks very much.  :thumbsup:  :thumbsup: