Index: src/command.cpp =================================================================== --- src/command.cpp (revision 15597) +++ src/command.cpp (working copy) @@ -191,6 +191,8 @@ DEF_COMMAND(CmdChangeTimetable); DEF_COMMAND(CmdSetVehicleOnTime); DEF_COMMAND(CmdAutofillTimetable); + +DEF_COMMAND(CmdResetWaypointStats); #undef DEF_COMMAND /** @@ -335,6 +337,7 @@ {CmdChangeTimetable, 0}, /* CMD_CHANGE_TIMETABLE */ {CmdSetVehicleOnTime, 0}, /* CMD_SET_VEHICLE_ON_TIME */ {CmdAutofillTimetable, 0}, /* CMD_AUTOFILL_TIMETABLE */ + {CmdResetWaypointStats, 0}, /* CMD_RESET_WAYPOINT_STATS */ }; /*! Index: src/command_type.h =================================================================== --- src/command_type.h (revision 15597) +++ src/command_type.h (working copy) @@ -286,6 +286,7 @@ CMD_CHANGE_TIMETABLE, ///< change the timetable for a vehicle CMD_SET_VEHICLE_ON_TIME, ///< set the vehicle on time feature (timetable) CMD_AUTOFILL_TIMETABLE, ///< autofill the timetable + CMD_RESET_WAYPOINT_STATS, ///< reset the "Most in a month" traffic counter of a waypoint }; /** Index: src/date.cpp =================================================================== --- src/date.cpp (revision 15597) +++ src/date.cpp (working copy) @@ -158,6 +158,7 @@ extern void EnginesDailyLoop(); extern void DisasterDailyLoop(); extern void IndustryDailyLoop(); +extern void WaypointsMonthlyLoop(); extern void CompaniesMonthlyLoop(); extern void EnginesMonthlyLoop(); extern void TownsMonthlyLoop(); @@ -251,6 +252,7 @@ } InvalidateWindowClasses(WC_CHEATS); + WaypointsMonthlyLoop(); CompaniesMonthlyLoop(); EnginesMonthlyLoop(); TownsMonthlyLoop(); Index: src/lang/english.txt =================================================================== --- src/lang/english.txt (revision 15597) +++ src/lang/english.txt (working copy) @@ -1187,6 +1187,14 @@ STR_WAYPOINT_RAW :{WAYPOINT} STR_EDIT_WAYPOINT_NAME :{WHITE}Edit waypoint name +STR_WAYPOINT_TRAFFIC :{BLACK}Traffic +STR_WAYPOINT_TRAFFIC_THIS_MONTH :{BLACK}This month: {GOLD}{COMMA} +STR_WAYPOINT_TRAFFIC_LAST_MONTH :{BLACK}Last month: {GOLD}{COMMA} +STR_WAYPOINT_TRAFFIC_MOST :{BLACK}Most in a month: {GOLD}{COMMA} + +STR_RESET_STATS :{BLACK}Reset Stats +STR_RESET_STATS_TIP :{BLACK}Reset the "Most in a month" counter + STR_CANT_CHANGE_WAYPOINT_NAME :{WHITE}Can't change waypoint name... STR_CONVERT_RAIL_TO_WAYPOINT_TIP :{BLACK}Convert rail to waypoint STR_CANT_BUILD_TRAIN_WAYPOINT :{WHITE}Can't build train waypoint here... Index: src/rail_cmd.cpp =================================================================== --- src/rail_cmd.cpp (revision 15597) +++ src/rail_cmd.cpp (working copy) @@ -2456,6 +2456,17 @@ DiagDirection dir; int length; + /* if train passes a waypoint, update the waypoint's statistics */ + if (IsFrontEngine(v) && IsRailWaypoint(tile) && v->tile != tile) { + Waypoint *wp = GetWaypointByTile(tile); + /* do not overflow - the limit of 65535 should not be reached under normal circumstances, but just in case */ + if (wp->traffic_this_month < MAX_UVALUE(uint16)) { + wp->traffic_this_month++; + wp->traffic_highest = max(wp->traffic_highest, wp->traffic_this_month); + InvalidateWindow(WC_WAYPOINT_VIEW, wp->index); + } + } + /* this routine applies only to trains in depot tiles */ if (v->type != VEH_TRAIN || !IsRailDepotTile(tile)) return VETSB_CONTINUE; Index: src/saveload/saveload.cpp =================================================================== --- src/saveload/saveload.cpp (revision 15597) +++ src/saveload/saveload.cpp (working copy) @@ -38,7 +38,7 @@ #include "saveload_internal.h" -extern const uint16 SAVEGAME_VERSION = 113; +extern const uint16 SAVEGAME_VERSION = 114; SavegameType _savegame_type; ///< type of savegame we are loading Index: src/saveload/waypoint_sl.cpp =================================================================== --- src/saveload/waypoint_sl.cpp (revision 15597) +++ src/saveload/waypoint_sl.cpp (working copy) @@ -68,6 +68,10 @@ SLE_CONDVAR(Waypoint, grfid, SLE_UINT32, 17, SL_MAX_VERSION), SLE_CONDVAR(Waypoint, owner, SLE_UINT8, 101, SL_MAX_VERSION), + SLE_CONDVAR(Waypoint, traffic_this_month, SLE_UINT16, 114, SL_MAX_VERSION), + SLE_CONDVAR(Waypoint, traffic_last_month, SLE_UINT16, 114, SL_MAX_VERSION), + SLE_CONDVAR(Waypoint, traffic_highest, SLE_UINT16, 114, SL_MAX_VERSION), + SLE_END() }; Index: src/waypoint.cpp =================================================================== --- src/waypoint.cpp (revision 15597) +++ src/waypoint.cpp (working copy) @@ -264,6 +264,21 @@ } /** + * Monthly loop for waypoints + */ +void WaypointsMonthlyLoop() +{ + Waypoint *wp; + + /* Reset waypoint statistics */ + FOR_ALL_WAYPOINTS(wp) { + wp->traffic_last_month = wp->traffic_this_month; + wp->traffic_this_month = 0; + } + InvalidateWindowClasses(WC_WAYPOINT_VIEW); +} + +/** * Remove a waypoint * @param tile from which to remove waypoint * @param flags type of operation @@ -372,6 +387,29 @@ } /** + * Reset the "Most in a month" counter of a waypoint. + * @param tile unused + * @param flags type of operation + * @param p1 id of waypoint + * @param p2 unused + * @param text unused + * @return cost of operation or error + */ +CommandCost CmdResetWaypointStats(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) +{ + if (!IsValidWaypointID(p1)) return CMD_ERROR; + + Waypoint *wp = GetWaypoint(p1); + if (!CheckOwnership(wp->owner)) return CMD_ERROR; + + if (flags & DC_EXEC) { + wp->traffic_highest = wp->traffic_this_month; + InvalidateWindow(WC_WAYPOINT_VIEW, p1); + } + return CommandCost(); +} + +/** * This hacks together some dummy one-shot Station structure for a waypoint. * @param tile on which to work * @return pointer to a Station Index: src/waypoint.h =================================================================== --- src/waypoint.h (revision 15597) +++ src/waypoint.h (working copy) @@ -17,23 +17,27 @@ DECLARE_OLD_POOL(Waypoint, Waypoint, 3, 8000) struct Waypoint : PoolItem { - TileIndex xy; ///< Tile of waypoint + TileIndex xy; ///< Tile of waypoint - TownID town_index; ///< Town associated with the waypoint - uint16 town_cn; ///< The Nth waypoint for this town (consecutive number) - StringID string; ///< C000-C03F have special meaning in old games - char *name; ///< Custom name. If not set, town + town_cn is used for naming + TownID town_index; ///< Town associated with the waypoint + uint16 town_cn; ///< The Nth waypoint for this town (consecutive number) + StringID string; ///< C000-C03F have special meaning in old games + char *name; ///< Custom name. If not set, town + town_cn is used for naming - ViewportSign sign; ///< Dimensions of sign (not saved) - Date build_date; ///< Date of construction - OwnerByte owner; ///< Whom this waypoint belongs to + ViewportSign sign; ///< Dimensions of sign (not saved) + Date build_date; ///< Date of construction + OwnerByte owner; ///< Whom this waypoint belongs to - byte stat_id; ///< ID of waypoint within the waypoint class (not saved) - uint32 grfid; ///< ID of GRF file - byte localidx; ///< Index of station within GRF file + byte stat_id; ///< ID of waypoint within the waypoint class (not saved) + uint32 grfid; ///< ID of GRF file + byte localidx; ///< Index of station within GRF file - byte deleted; ///< Delete counter. If greater than 0 then it is decremented until it reaches 0; the waypoint is then is deleted. + byte deleted; ///< Delete counter. If greater than 0 then it is decremented until it reaches 0; the waypoint is then is deleted. + uint16 traffic_this_month; ///< Number of trains that passed this waypoint this month + uint16 traffic_last_month; ///< Number of trains that passed this waypoint last month + uint16 traffic_highest; ///< Maximum number of trains that have passed the waypoint during one month + Waypoint(TileIndex tile = INVALID_TILE); ~Waypoint(); Index: src/waypoint_gui.cpp =================================================================== --- src/waypoint_gui.cpp (revision 15597) +++ src/waypoint_gui.cpp (working copy) @@ -28,10 +28,25 @@ WAYPVW_VIEWPORTPANEL, WAYPVW_SPACER, WAYPVW_CENTERVIEW, + WAYPVW_RESET_STATS, WAYPVW_RENAME, WAYPVW_SHOW_TRAINS, }; + void DrawStats() + { + DrawString(2, 105, STR_WAYPOINT_TRAFFIC, TC_FROMSTRING); + + SetDParam(0, this->wp->traffic_this_month); + DrawString(2, 115, STR_WAYPOINT_TRAFFIC_THIS_MONTH, TC_FROMSTRING); + + SetDParam(0, this->wp->traffic_last_month); + DrawString(2, 125, STR_WAYPOINT_TRAFFIC_LAST_MONTH, TC_FROMSTRING); + + SetDParam(0, this->wp->traffic_highest); + DrawString(2, 135, STR_WAYPOINT_TRAFFIC_MOST, TC_FROMSTRING); + } + public: WaypointWindow(const WindowDesc *desc, WindowNumber window_number) : Window(desc, window_number) { @@ -52,6 +67,7 @@ virtual void OnPaint() { /* You can only change your own waypoints */ + this->SetWidgetDisabledState(WAYPVW_RESET_STATS, this->wp->owner != _local_company); this->SetWidgetDisabledState(WAYPVW_RENAME, this->wp->owner != _local_company); /* Disable the widget for waypoints with no owner (after company bankrupt) */ this->SetWidgetDisabledState(WAYPVW_SHOW_TRAINS, this->wp->owner == OWNER_NONE); @@ -60,6 +76,8 @@ this->DrawWidgets(); this->DrawViewport(); + + this->DrawStats(); } virtual void OnClick(Point pt, int widget) @@ -73,6 +91,10 @@ } break; + case WAYPVW_RESET_STATS: /* reset stats */ + DoCommandP(0, this->window_number, 0, CMD_RESET_WAYPOINT_STATS); + break; + case WAYPVW_RENAME: /* rename */ SetDParam(0, this->wp->index); ShowQueryString(STR_WAYPOINT_RAW, STR_EDIT_WAYPOINT_NAME, MAX_LENGTH_WAYPOINT_NAME_BYTES, MAX_LENGTH_WAYPOINT_NAME_PIXELS, this, CS_ALPHANUMERAL, QSF_ENABLE_DEFAULT); @@ -104,16 +126,17 @@ { WWT_CLOSEBOX, RESIZE_NONE, COLOUR_GREY, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, // WAYPVW_CLOSEBOX { WWT_CAPTION, RESIZE_NONE, COLOUR_GREY, 11, 247, 0, 13, STR_WAYPOINT_VIEWPORT, STR_018C_WINDOW_TITLE_DRAG_THIS}, // WAYPVW_CAPTION { WWT_STICKYBOX, RESIZE_NONE, COLOUR_GREY, 248, 259, 0, 13, 0x0, STR_STICKY_BUTTON}, // WAYPVW_STICKY -{ WWT_PANEL, RESIZE_NONE, COLOUR_GREY, 0, 259, 14, 105, 0x0, STR_NULL}, // WAYPVW_VIEWPORTPANEL +{ WWT_PANEL, RESIZE_NONE, COLOUR_GREY, 0, 259, 14, 145, 0x0, STR_NULL}, // WAYPVW_VIEWPORTPANEL { WWT_INSET, RESIZE_NONE, COLOUR_GREY, 2, 257, 16, 103, 0x0, STR_NULL}, // WAYPVW_SPACER -{ WWT_PUSHTXTBTN, RESIZE_NONE, COLOUR_GREY, 0, 121, 106, 117, STR_00E4_LOCATION, STR_3053_CENTER_MAIN_VIEW_ON_STATION}, // WAYPVW_CENTERVIEW -{ WWT_PUSHTXTBTN, RESIZE_NONE, COLOUR_GREY, 122, 244, 106, 117, STR_0130_RENAME, STR_CHANGE_WAYPOINT_NAME}, // WAYPVW_RENAME -{ WWT_PUSHTXTBTN, RESIZE_NONE, COLOUR_GREY, 245, 259, 106, 117, STR_TRAIN, STR_SCHEDULED_TRAINS_TIP }, // WAYPVW_SHOW_TRAINS +{ WWT_PUSHTXTBTN, RESIZE_NONE, COLOUR_GREY, 0, 81, 146, 157, STR_00E4_LOCATION, STR_3053_CENTER_MAIN_VIEW_ON_STATION}, // WAYPVW_CENTERVIEW +{ WWT_PUSHTXTBTN, RESIZE_NONE, COLOUR_GREY, 82, 163, 146, 157, STR_RESET_STATS, STR_RESET_STATS_TIP}, // WAYPVW_RESET_STATS +{ WWT_PUSHTXTBTN, RESIZE_NONE, COLOUR_GREY, 164, 245, 146, 157, STR_0130_RENAME, STR_CHANGE_WAYPOINT_NAME}, // WAYPVW_RENAME +{ WWT_PUSHTXTBTN, RESIZE_NONE, COLOUR_GREY, 246, 259, 146, 157, STR_TRAIN, STR_SCHEDULED_TRAINS_TIP }, // WAYPVW_SHOW_TRAINS { WIDGETS_END}, }; static const WindowDesc _waypoint_view_desc = { - WDP_AUTO, WDP_AUTO, 260, 118, 260, 118, + WDP_AUTO, WDP_AUTO, 260, 158, 260, 158, WC_WAYPOINT_VIEW, WC_NONE, WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON, _waypoint_view_widgets,