267 lines
9.0 KiB
C++
267 lines
9.0 KiB
C++
#include "../stdafx.h"
|
|
|
|
#include "cm_hotkeys.hpp"
|
|
#include "cm_settings.hpp"
|
|
|
|
#include "../newgrf_station.h"
|
|
#include "../settings_type.h"
|
|
#include "../sound_func.h"
|
|
#include "../tilehighlight_func.h"
|
|
#include "../viewport_func.h"
|
|
#include "../window_func.h"
|
|
#include "../window_gui.h"
|
|
#include "../window_type.h"
|
|
#include "../widgets/rail_widget.h"
|
|
#include "../widgets/road_widget.h"
|
|
|
|
#include <queue>
|
|
|
|
#include "../safeguards.h"
|
|
|
|
struct RailStationGUISettings {
|
|
Axis orientation; ///< Currently selected rail station orientation
|
|
|
|
bool newstations; ///< Are custom station definitions available?
|
|
StationClassID station_class; ///< Currently selected custom station class (if newstations is \c true )
|
|
byte station_type; ///< %Station type within the currently selected custom station class (if newstations is \c true )
|
|
byte station_count; ///< Number of custom stations (if newstations is \c true )
|
|
};
|
|
extern RailStationGUISettings _railstation; ///< Settings of the station builder GUI
|
|
extern uint32 _realtime_tick;
|
|
|
|
namespace citymania {
|
|
|
|
bool _fn_mod = false;
|
|
bool _remove_mod = false;
|
|
bool _estimate_mod = false;
|
|
|
|
uint32 _effective_actions = 0;
|
|
uint32 _first_effective_tick = 0;
|
|
std::queue<uint32> _last_actions;
|
|
|
|
static void PurgeLastActions() {
|
|
while (!_last_actions.empty() && _last_actions.front() <= _realtime_tick)
|
|
_last_actions.pop();
|
|
}
|
|
|
|
void CountEffectiveAction() {
|
|
if (!_first_effective_tick) _first_effective_tick = _realtime_tick;
|
|
_effective_actions++;
|
|
PurgeLastActions();
|
|
_last_actions.push(_realtime_tick + 60000);
|
|
}
|
|
|
|
void ResetEffectivveActionCounter() {
|
|
_first_effective_tick = 0;
|
|
_effective_actions = 0;
|
|
std::queue<uint32>().swap(_last_actions); // clear the queue
|
|
}
|
|
|
|
std::pair<uint32, uint32> GetEPM() {
|
|
if (!_first_effective_tick || _realtime_tick <= _first_effective_tick) return std::make_pair(0, 0);
|
|
PurgeLastActions();
|
|
return std::make_pair(_effective_actions * 60000 / (_realtime_tick - _first_effective_tick), _last_actions.size());
|
|
}
|
|
|
|
void UpdateModKeys(bool shift_pressed, bool ctrl_pressed, bool alt_pressed) {
|
|
ModKey key = ModKey::NONE;
|
|
if (alt_pressed) key = ModKey::ALT;
|
|
if (ctrl_pressed) key = ModKey::CTRL;
|
|
if (shift_pressed) key = ModKey::SHIFT;
|
|
bool fn_mod_prev = _fn_mod;
|
|
bool remove_mod_prev = _remove_mod;
|
|
_fn_mod = (_settings_client.gui.cm_fn_mod == key);
|
|
_remove_mod = (_settings_client.gui.cm_remove_mod == key);
|
|
_estimate_mod = (_settings_client.gui.cm_estimate_mod == key);
|
|
|
|
Window *w;
|
|
if (fn_mod_prev != _fn_mod) {
|
|
FOR_ALL_WINDOWS_FROM_FRONT(w) {
|
|
if (w->CM_OnFnModStateChange() == ES_HANDLED) break;
|
|
}
|
|
}
|
|
if (remove_mod_prev != _remove_mod) {
|
|
FOR_ALL_WINDOWS_FROM_FRONT(w) {
|
|
if (w->CM_OnRemoveModStateChange() == ES_HANDLED) break;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool HasSeparateRemoveMod() {
|
|
return (_settings_client.gui.cm_fn_mod != _settings_client.gui.cm_remove_mod);
|
|
}
|
|
|
|
ToolRemoveMode RailToolbar_GetRemoveMode(int widget) {
|
|
switch(widget) {
|
|
case WID_RAT_BUILD_NS:
|
|
case WID_RAT_BUILD_X:
|
|
case WID_RAT_BUILD_EW:
|
|
case WID_RAT_BUILD_Y:
|
|
case WID_RAT_AUTORAIL:
|
|
case WID_RAT_POLYRAIL:
|
|
return ToolRemoveMode::MOD;
|
|
|
|
case WID_RAT_BUILD_WAYPOINT:
|
|
case WID_RAT_BUILD_STATION:
|
|
case WID_RAT_BUILD_SIGNALS:
|
|
return HasSeparateRemoveMod() ? ToolRemoveMode::MOD : ToolRemoveMode::BUTTON;
|
|
|
|
default:
|
|
return ToolRemoveMode::NONE;
|
|
}
|
|
}
|
|
|
|
bool RailToolbar_IsRemoveInverted(int widget) {
|
|
return false;
|
|
// return (RailToolbar_GetRemoveMode(widget) != ToolRemoveMode::NONE && citymania::_fn_mod);
|
|
}
|
|
|
|
void RailToolbar_UpdateRemoveWidgetStatus(Window *w, int widget, bool remove_active) {
|
|
if (widget == WID_RAT_REMOVE) return;
|
|
|
|
if (RailToolbar_GetRemoveMode(widget) == citymania::ToolRemoveMode::NONE || !w->IsWidgetLowered(widget)) {
|
|
w->DisableWidget(WID_RAT_REMOVE);
|
|
w->RaiseWidget(WID_RAT_REMOVE);
|
|
} else {
|
|
w->EnableWidget(WID_RAT_REMOVE);
|
|
w->SetWidgetLoweredState(WID_RAT_REMOVE, remove_active);
|
|
SetSelectionRed(remove_active);
|
|
}
|
|
w->SetWidgetDirty(WID_RAT_REMOVE);
|
|
|
|
/* handle station builder */
|
|
if (w->IsWidgetLowered(WID_RAT_BUILD_STATION)) {
|
|
if (remove_active) {
|
|
/* starting drag & drop remove */
|
|
if (!_settings_client.gui.station_dragdrop) {
|
|
SetTileSelectSize(1, 1);
|
|
} else {
|
|
VpSetPlaceSizingLimit(-1);
|
|
}
|
|
} else {
|
|
/* starting station build mode */
|
|
if (!_settings_client.gui.station_dragdrop) {
|
|
int x = _settings_client.gui.station_numtracks;
|
|
int y = _settings_client.gui.station_platlength;
|
|
if (_railstation.orientation == 0) Swap(x, y);
|
|
SetTileSelectSize(x, y);
|
|
} else {
|
|
VpSetPlaceSizingLimit(_settings_game.station.station_spread);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool RailToolbar_RemoveModChanged(Window *w, bool invert_remove, bool remove_active, bool button_clicked) {
|
|
if (w->IsWidgetDisabled(WID_RAT_REMOVE)) return false;
|
|
|
|
DeleteWindowById(WC_SELECT_STATION, 0);
|
|
for (uint i = WID_RAT_BUILD_NS; i < WID_RAT_REMOVE; i++) {
|
|
if (w->IsWidgetLowered(i)) {
|
|
auto old_active = remove_active;
|
|
switch (RailToolbar_GetRemoveMode(i)) {
|
|
case ToolRemoveMode::BUTTON:
|
|
if (button_clicked) remove_active = !w->IsWidgetLowered(WID_RAT_REMOVE);
|
|
break;
|
|
case ToolRemoveMode::MOD:
|
|
if (_remove_mod || !button_clicked) remove_active = (_remove_mod != invert_remove);
|
|
else remove_active = !w->IsWidgetLowered(WID_RAT_REMOVE);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if (old_active != remove_active) {
|
|
if (button_clicked && _settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP);
|
|
RailToolbar_UpdateRemoveWidgetStatus(w, i, remove_active);
|
|
}
|
|
return remove_active;
|
|
}
|
|
}
|
|
return remove_active;
|
|
}
|
|
|
|
ToolRemoveMode RoadToolbar_GetRemoveMode(int widget) {
|
|
switch(widget) {
|
|
case WID_ROT_ROAD_X:
|
|
case WID_ROT_ROAD_Y:
|
|
case WID_ROT_AUTOROAD:
|
|
return ToolRemoveMode::MOD;
|
|
|
|
case WID_ROT_BUS_STATION:
|
|
case WID_ROT_TRUCK_STATION:
|
|
return HasSeparateRemoveMod() ? ToolRemoveMode::MOD : ToolRemoveMode::BUTTON;
|
|
|
|
default:
|
|
return ToolRemoveMode::NONE;
|
|
}
|
|
}
|
|
|
|
void RoadToolbar_UpdateOptionWidgetStatus(Window *w, int widget, bool remove_active, bool is_road) {
|
|
|
|
switch (widget) {
|
|
case WID_ROT_REMOVE:
|
|
case WID_ROT_ONE_WAY:
|
|
return;
|
|
|
|
case WID_ROT_BUS_STATION:
|
|
case WID_ROT_TRUCK_STATION:
|
|
if (is_road) w->DisableWidget(WID_ROT_ONE_WAY);
|
|
break;
|
|
|
|
case WID_ROT_ROAD_X:
|
|
case WID_ROT_ROAD_Y:
|
|
case WID_ROT_AUTOROAD:
|
|
if (is_road) w->SetWidgetDisabledState(WID_ROT_ONE_WAY, !w->IsWidgetLowered(widget));
|
|
break;
|
|
|
|
default:
|
|
if (is_road) {
|
|
w->SetWidgetDisabledState(WID_ROT_ONE_WAY, true);
|
|
w->SetWidgetLoweredState(WID_ROT_ONE_WAY, false);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
|
|
if (RoadToolbar_GetRemoveMode(widget) == citymania::ToolRemoveMode::NONE || !w->IsWidgetLowered(widget)) {
|
|
w->DisableWidget(WID_ROT_REMOVE);
|
|
w->RaiseWidget(WID_ROT_REMOVE);
|
|
} else {
|
|
w->EnableWidget(WID_ROT_REMOVE);
|
|
w->SetWidgetLoweredState(WID_ROT_REMOVE, remove_active);
|
|
SetSelectionRed(remove_active);
|
|
}
|
|
w->SetWidgetDirty(WID_ROT_REMOVE);
|
|
}
|
|
|
|
bool RoadToolbar_RemoveModChanged(Window *w, bool remove_active, bool button_clicked, bool is_road) {
|
|
if (w->IsWidgetDisabled(WID_ROT_REMOVE)) return false;
|
|
DeleteWindowById(WC_SELECT_STATION, 0);
|
|
for (uint i = WID_ROT_ROAD_X; i < WID_ROT_REMOVE; i++) {
|
|
if (w->IsWidgetLowered(i)) {
|
|
auto old_active = remove_active;
|
|
switch (RoadToolbar_GetRemoveMode(i)) {
|
|
case ToolRemoveMode::BUTTON:
|
|
if (button_clicked) remove_active = !w->IsWidgetLowered(WID_ROT_REMOVE);
|
|
break;
|
|
case ToolRemoveMode::MOD:
|
|
if (_remove_mod || !button_clicked) remove_active = _remove_mod;
|
|
else remove_active = !w->IsWidgetLowered(WID_ROT_REMOVE);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if (old_active != remove_active) {
|
|
if (button_clicked && _settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP);
|
|
RoadToolbar_UpdateOptionWidgetStatus(w, i, remove_active, is_road);
|
|
}
|
|
return remove_active;
|
|
}
|
|
}
|
|
return remove_active;
|
|
}
|
|
|
|
|
|
} // namespace citymania
|