diff --git a/projects/openttd_vs90.vcproj b/projects/openttd_vs90.vcproj
index 666760ce78..38bf0cccbd 100644
--- a/projects/openttd_vs90.vcproj
+++ b/projects/openttd_vs90.vcproj
@@ -1,7 +1,7 @@
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
@@ -447,6 +445,10 @@
RelativePath=".\..\src\autoreplace.cpp"
>
+
+
@@ -507,6 +509,10 @@
RelativePath=".\..\src\dedicated.cpp"
>
+
+
@@ -543,6 +549,10 @@
RelativePath=".\..\src\fios.cpp"
>
+
+
@@ -551,10 +561,6 @@
RelativePath=".\..\src\fontdetection.cpp"
>
-
-
@@ -568,11 +574,11 @@
>
-
-
-
-
@@ -627,18 +625,14 @@
RelativePath=".\..\src\linkgraph\linkgraphschedule.cpp"
>
-
-
-
-
+
+
@@ -703,6 +697,10 @@
RelativePath=".\..\src\rail.cpp"
>
+
+
@@ -751,6 +749,10 @@
RelativePath=".\..\src\station.cpp"
>
+
+
@@ -767,10 +769,6 @@
RelativePath=".\..\src\strings.cpp"
>
-
-
@@ -867,6 +865,10 @@
RelativePath=".\..\src\autoslope.h"
>
+
+
@@ -887,6 +889,10 @@
RelativePath=".\..\src\bridge.h"
>
+
+
@@ -999,6 +1005,10 @@
RelativePath=".\..\src\video\dedicated_v.h"
>
+
+
@@ -1091,6 +1101,10 @@
RelativePath=".\..\src\fios.h"
>
+
+
@@ -1099,10 +1113,6 @@
RelativePath=".\..\src\fontdetection.h"
>
-
-
@@ -1199,6 +1209,10 @@
RelativePath=".\..\src\ini_type.h"
>
+
+
@@ -1211,18 +1225,6 @@
RelativePath=".\..\src\language.h"
>
-
-
-
-
-
-
@@ -1251,14 +1253,6 @@
RelativePath=".\..\src\linkgraph\linkgraphschedule.h"
>
-
-
-
-
@@ -1271,6 +1265,10 @@
RelativePath=".\..\src\map_type.h"
>
+
+
@@ -1519,6 +1517,10 @@
RelativePath=".\..\src\rail_type.h"
>
+
+
@@ -1859,6 +1861,10 @@
RelativePath=".\..\src\viewport_type.h"
>
+
+
@@ -1903,6 +1909,10 @@
RelativePath=".\..\src\window_type.h"
>
+
+
@@ -2055,10 +2065,18 @@
RelativePath=".\..\src\build_vehicle_gui.cpp"
>
+
+
+
+
@@ -2255,20 +2273,28 @@
RelativePath=".\..\src\viewport_gui.cpp"
>
+
+
+
+
+
+
@@ -2599,6 +2629,10 @@
RelativePath=".\..\src\waypoint_cmd.cpp"
>
+
+
-
-
-
-
@@ -3863,6 +3889,14 @@
RelativePath=".\..\src\blitter\32bpp_sse4.hpp"
>
+
+
+
+
diff --git a/source.list b/source.list
index 3b66ab9fca..e062c1b22c 100644
--- a/source.list
+++ b/source.list
@@ -143,6 +143,7 @@ base_media_func.h
base_station_base.h
bmp.h
bridge.h
+cargo_table_gui.h
cargo_type.h
cargoaction.h
cargomonitor.h
@@ -386,6 +387,7 @@ vehiclelist.h
viewport_func.h
viewport_sprite_sorter.h
viewport_type.h
+watch_gui.h
water.h
waypoint_base.h
waypoint_func.h
@@ -397,6 +399,7 @@ video/win32_v.h
window_func.h
window_gui.h
window_type.h
+zoning.h
zoom_func.h
zoom_type.h
#if WIN32
@@ -452,7 +455,9 @@ autoreplace_gui.cpp
bootstrap_gui.cpp
bridge_gui.cpp
build_vehicle_gui.cpp
+cargo_table_gui.cpp
cheat_gui.cpp
+commands_gui.cpp
company_gui.cpp
console_gui.cpp
date_gui.cpp
@@ -501,8 +506,10 @@ train_gui.cpp
transparency_gui.cpp
tree_gui.cpp
vehicle_gui.cpp
+watch_gui.cpp
viewport_gui.cpp
waypoint_gui.cpp
+zoning_gui.cpp
# Widgets
widgets/airport_widget.h
@@ -511,6 +518,7 @@ widgets/autoreplace_widget.h
widgets/bootstrap_widget.h
widgets/bridge_widget.h
widgets/build_vehicle_widget.h
+widgets/cargo_table_widget.h
widgets/cheat_widget.h
widgets/company_widget.h
widgets/console_widget.h
@@ -590,6 +598,7 @@ vehicle_cmd.cpp
void_cmd.cpp
water_cmd.cpp
waypoint_cmd.cpp
+zoning_cmd.cpp
# Save/Load handlers
saveload/afterload.cpp
diff --git a/src/bridge_gui.cpp b/src/bridge_gui.cpp
index 2e9657e322..019768d23c 100644
--- a/src/bridge_gui.cpp
+++ b/src/bridge_gui.cpp
@@ -24,6 +24,7 @@
#include "cmd_helper.h"
#include "tunnelbridge_map.h"
#include "road_gui.h"
+#include "tilehighlight_func.h"
#include "widgets/bridge_widget.h"
@@ -72,6 +73,8 @@ void CcBuildBridge(const CommandCost &result, TileIndex end_tile, uint32 p1, uin
DiagDirection start_direction = ReverseDiagDir(GetTunnelBridgeDirection(p1));
ConnectRoadToStructure(p1, start_direction);
}
+
+ StoreRailPlacementEndpoints(p1, end_tile, (TileX(p1) == TileX(end_tile)) ? TRACK_Y : TRACK_X, false);
}
/** Window class for handling the bridge-build GUI. */
diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp
index 715c87e99e..49d16f8750 100644
--- a/src/build_vehicle_gui.cpp
+++ b/src/build_vehicle_gui.cpp
@@ -34,7 +34,7 @@
#include "autoreplace_func.h"
#include "widgets/build_vehicle_widget.h"
-
+#include "hotkeys.h"
#include "table/strings.h"
#include "safeguards.h"
@@ -1481,13 +1481,28 @@ struct BuildVehicleWindow : Window {
{
this->vscroll->SetCapacityFromWidget(this, WID_BV_LIST);
}
+
+ virtual EventState OnHotkey(int hotkey)
+ {
+ if (this->owner != _local_company) return ES_NOT_HANDLED;
+ return Window::OnHotkey(hotkey);
+ }
+
+ static HotkeyList hotkeys;
};
+static Hotkey build_vehicle_hotkeys[] = {
+ Hotkey('R', "build_vehicle", WID_BV_BUILD),
+ HOTKEY_LIST_END
+};
+HotkeyList BuildVehicleWindow::hotkeys("build_vehicle", build_vehicle_hotkeys);
+
static WindowDesc _build_vehicle_desc(
WDP_AUTO, "build_vehicle", 240, 268,
WC_BUILD_VEHICLE, WC_NONE,
WDF_CONSTRUCTION,
- _nested_build_vehicle_widgets, lengthof(_nested_build_vehicle_widgets)
+ _nested_build_vehicle_widgets, lengthof(_nested_build_vehicle_widgets),
+ &BuildVehicleWindow::hotkeys
);
void ShowBuildVehicleWindow(TileIndex tile, VehicleType type)
diff --git a/src/command.cpp b/src/command.cpp
index 2830144f89..8d5e1e9a41 100644
--- a/src/command.cpp
+++ b/src/command.cpp
@@ -26,6 +26,10 @@
#include "signal_func.h"
#include "core/backup_type.hpp"
#include "object_base.h"
+#include "window_func.h"
+#include "watch_gui.h"
+#include "network/network_base.h"
+#include "window_func.h"
#include "table/strings.h"
@@ -547,14 +551,19 @@ bool DoCommandP(const CommandContainer *container, bool my_cmd)
bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const char *text, bool my_cmd)
{
/* Cost estimation is generally only done when the
- * local user presses shift while doing somthing.
- * However, in case of incoming network commands,
- * map generation or the pause button we do want
- * to execute. */
- bool estimate_only = _shift_pressed && IsLocalCompany() &&
- !_generating_world &&
- !(cmd & CMD_NETWORK_COMMAND) &&
- (cmd & CMD_ID_MASK) != CMD_PAUSE;
+ * local user presses shift while constructing somthing.
+ * However, in case of incoming network commands or
+ * map generation we do want to execute. */
+ bool estimate_only = false;
+ switch (_command_proc_table[cmd & CMD_ID_MASK].type) {
+ case CMDT_LANDSCAPE_CONSTRUCTION:
+ case CMDT_VEHICLE_CONSTRUCTION:
+ estimate_only = _shift_pressed && IsLocalCompany() &&
+ !_generating_world && !(cmd & CMD_NETWORK_COMMAND);
+ break;
+ default:
+ break; // just to silence warnings
+ }
/* We're only sending the command, so don't do
* fancy things for 'success'. */
@@ -756,6 +765,23 @@ CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd,
if (c != NULL) c->last_build_coordinate = tile;
}
+ /* Send Tile Number to Watching Company Windows */
+ WatchCompany *wc;
+ for(int watching_window = 0; ; watching_window++){
+ wc = dynamic_cast(FindWindowById(WC_WATCH_COMPANY, watching_window));
+ if(wc != NULL) wc->OnDoCommand(_current_company, tile);
+ else break;
+ }
+
+ NetworkClientInfo *ci;
+ FOR_ALL_CLIENT_INFOS(ci) {
+ if (ci->client_playas == _current_company) {
+ wc = dynamic_cast(FindWindowById(WC_WATCH_COMPANYA, ci->client_id));
+ if (wc != NULL) wc->OnDoCommand(_current_company, tile);
+ break;
+ }
+ }
+
SubtractMoneyFromCompany(res2);
/* update signals if needed */
diff --git a/src/company_base.h b/src/company_base.h
index b220669c8c..9835f5f50e 100644
--- a/src/company_base.h
+++ b/src/company_base.h
@@ -17,6 +17,7 @@
#include "autoreplace_type.h"
#include "tile_type.h"
#include "settings_type.h"
+#include "cargo_type.h"
#include "group.h"
/** Statistics about the economy. */
@@ -26,6 +27,7 @@ struct CompanyEconomyEntry {
CargoArray delivered_cargo; ///< The amount of delivered cargo.
int32 performance_history; ///< Company score (scale 0-1000)
Money company_value; ///< The value of the company.
+ Money cargo_income[NUM_CARGO]; ///< Cargo income from each cargo type
};
struct CompanyInfrastructure {
@@ -124,6 +126,12 @@ struct Company : CompanyPool::PoolItem<&_company_pool>, CompanyProperties {
CompanyInfrastructure infrastructure; ///< NOSAVE: Counts of company owned infrastructure.
+ uint32 cargo_units[NUM_CARGO]; ///< Total amount of transported cargo for each cargo ID
+ Money cargo_income[NUM_CARGO]; ///< Total income from transported cargo for each cargo ID
+
+ uint32 cargo_units_period[2][NUM_CARGO]; ///< Monthly amount of transported cargo for each cargo ID
+ Money cargo_income_period[2][NUM_CARGO]; ///< Monthly income from transported cargo for each cargo ID
+
/**
* Is this company a valid company, controlled by the computer (a NoAI program)?
* @param index Index in the pool.
diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp
index 3a94078582..538c11c22f 100644
--- a/src/company_cmd.cpp
+++ b/src/company_cmd.cpp
@@ -38,6 +38,7 @@
#include "story_base.h"
#include "table/strings.h"
+#include "cargo_type.h"
#include "safeguards.h"
@@ -69,6 +70,8 @@ Company::Company(uint16 name_1, bool is_ai)
for (uint j = 0; j < 4; j++) this->share_owners[j] = COMPANY_SPECTATOR;
InvalidateWindowData(WC_PERFORMANCE_DETAIL, 0, INVALID_COMPANY);
+ InvalidateWindowClassesData(WC_WATCH_COMPANY, 0);
+ InvalidateWindowClassesData(WC_WATCH_COMPANYA, 1);
}
/** Destructor. */
@@ -91,6 +94,8 @@ void Company::PostDestructor(size_t index)
InvalidateWindowData(WC_LINKGRAPH_LEGEND, 0);
/* If the currently shown error message has this company in it, then close it. */
InvalidateWindowData(WC_ERRMSG, 0);
+ InvalidateWindowClassesData(WC_WATCH_COMPANY, 0);
+ InvalidateWindowClassesData(WC_WATCH_COMPANYA, 1);
}
/**
@@ -576,9 +581,23 @@ Company *DoStartupNewCompany(bool is_ai, CompanyID company = INVALID_COMPANY)
AI::BroadcastNewEvent(new ScriptEventCompanyNew(c->index), c->index);
Game::NewEvent(new ScriptEventCompanyNew(c->index));
+ if (!is_ai) UpdateAllTownVirtCoords(); //coloured rating
+
+ for (uint j = 0; j < NUM_CARGO; j++) {
+ c->cargo_income[j] = 0;
+ c->cargo_units[j] = 0;
+ }
+ CargoResetPeriods(c);
+
return c;
}
+void CargoResetPeriods(Company *c){
+ memmove(&c->cargo_income_period[1], &c->cargo_income_period[0], sizeof(c->cargo_income_period[0]));
+ memset(&c->cargo_income_period, 0, sizeof(c->cargo_income_period[0]));
+ memmove(&c->cargo_units_period[1], &c->cargo_units_period[0], sizeof(c->cargo_units_period[0]));
+ memset(&c->cargo_units_period, 0, sizeof(c->cargo_units_period[0]));
+}
/** Start the next competitor now. */
void StartupCompanies()
{
@@ -1081,6 +1100,7 @@ CommandCost CmdRenameCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
free(c->name);
c->name = reset ? NULL : stredup(text);
MarkWholeScreenDirty();
+ InvalidateWindowClassesData(WC_WATCH_COMPANY, 0);
CompanyAdminUpdate(c);
}
diff --git a/src/company_func.h b/src/company_func.h
index b5d9361673..2af836a4fd 100644
--- a/src/company_func.h
+++ b/src/company_func.h
@@ -31,6 +31,7 @@ void SubtractMoneyFromCompany(CommandCost cost);
void SubtractMoneyFromCompanyFract(CompanyID company, CommandCost cost);
CommandCost CheckOwnership(Owner owner, TileIndex tile = 0);
CommandCost CheckTileOwnership(TileIndex tile);
+void CargoResetPeriods(Company *c);
extern CompanyByte _local_company;
extern CompanyByte _current_company;
diff --git a/src/company_gui.cpp b/src/company_gui.cpp
index 1f3b06355d..cba418f128 100644
--- a/src/company_gui.cpp
+++ b/src/company_gui.cpp
@@ -1917,6 +1917,9 @@ static const NWidgetPart _nested_company_widgets[] = {
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_C_RELOCATE_HQ), SetFill(1, 0), SetDataTip(STR_COMPANY_VIEW_RELOCATE_HQ, STR_COMPANY_VIEW_RELOCATE_COMPANY_HEADQUARTERS),
NWidget(NWID_SPACER), SetMinimalSize(90, 0),
EndContainer(),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, CW_WIDGET_COMPANY_RESET), SetFill(1, 0), SetDataTip(STR_XI_RESET2, STR_XI_RESET),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, CW_WIDGET_COMPANY_SUSPEND), SetFill(1, 0), SetDataTip(STR_XI_SUSPEND2, STR_XI_SUSPEND),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, CW_WIDGET_COMPANY_RESUME), SetFill(1, 0), SetDataTip(STR_XI_RESUME2, STR_XI_RESUME),
NWidget(NWID_SPACER), SetFill(0, 1),
EndContainer(),
EndContainer(),
@@ -1950,6 +1953,7 @@ static const NWidgetPart _nested_company_widgets[] = {
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_C_COMPANY_PASSWORD), SetFill(1, 0), SetDataTip(STR_COMPANY_VIEW_PASSWORD, STR_COMPANY_VIEW_PASSWORD_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_C_COMPANY_JOIN), SetFill(1, 0), SetDataTip(STR_COMPANY_VIEW_JOIN, STR_COMPANY_VIEW_JOIN_TOOLTIP),
EndContainer(),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, CW_WIDGET_COMPANY_JOIN2), SetFill(1, 0), SetDataTip(STR_COMPANY_VIEW_JOIN, STR_COMPANY_VIEW_JOIN_TOOLTIP),
EndContainer(),
EndContainer(),
EndContainer(),
@@ -1987,6 +1991,16 @@ static const StringID _company_view_vehicle_count_strings[] = {
/**
* Window with general information about a company
*/
+static void ResetCallback(Window *w, bool confirmed)
+{
+ if (confirmed) {
+ CompanyID company2 = (CompanyID)w->window_number;
+ char msg[128];
+ seprintf(msg, lastof(msg), "!reset %i", company2 + 1);
+ NetworkClientSendChatToServer(msg);
+ }
+}
+
struct CompanyWindow : Window
{
CompanyWidgets query_widget;
@@ -2083,6 +2097,13 @@ struct CompanyWindow : Window
}
}
+ if(!_networking){
+ this->SetWidgetDisabledState(CW_WIDGET_COMPANY_RESUME, true);
+ this->SetWidgetDisabledState(CW_WIDGET_COMPANY_SUSPEND, true);
+ this->SetWidgetDisabledState(CW_WIDGET_COMPANY_RESET, true);
+ this->SetWidgetDisabledState(CW_WIDGET_COMPANY_JOIN2, true);
+ }
+
this->DrawWidgets();
}
@@ -2139,6 +2160,15 @@ struct CompanyWindow : Window
break;
}
+ case CW_WIDGET_COMPANY_RESUME:
+ case CW_WIDGET_COMPANY_SUSPEND:
+ case CW_WIDGET_COMPANY_RESET:
+ case CW_WIDGET_COMPANY_JOIN2:
+ if(!_networking || !_novarole){
+ size->width = 0;
+ size->height = 0;
+ }
+ break;
#ifdef ENABLE_NETWORK
case WID_C_HAS_PASSWORD:
*size = maxdim(*size, GetSpriteSize(SPR_LOCK));
@@ -2365,6 +2395,44 @@ struct CompanyWindow : Window
/* just send the join command */
NetworkClientRequestMove(company);
}
+ MarkWholeScreenDirty();
+ break;
+ }
+
+ case CW_WIDGET_COMPANY_JOIN2:{
+ CompanyID company2 = (CompanyID)this->window_number;
+ this->query_widget = CW_WIDGET_COMPANY_JOIN2;
+ char msg[128];
+ seprintf(msg, lastof(msg), "!move %i", company2 + 1);
+ NetworkClientSendChatToServer(msg);
+ MarkWholeScreenDirty();
+ break;
+ }
+ case CW_WIDGET_COMPANY_RESET:{
+ if (!_networking) return;
+ this->query_widget = CW_WIDGET_COMPANY_RESET;
+ ShowQuery(STR_XI_RESET_CAPTION, STR_XI_REALY_RESET, this, ResetCallback);
+ MarkWholeScreenDirty();
+ break;
+ }
+ case CW_WIDGET_COMPANY_SUSPEND:{
+ if (!_networking) return;
+ this->query_widget = CW_WIDGET_COMPANY_SUSPEND;
+ CompanyID company2 = (CompanyID)this->window_number;
+ char msg[128];
+ seprintf(msg, lastof(msg), "!lockp %i", company2 + 1);
+ NetworkClientSendChatToServer(msg);
+ MarkWholeScreenDirty();
+ break;
+ }
+ case CW_WIDGET_COMPANY_RESUME:{
+ if (!_networking) return;
+ this->query_widget = CW_WIDGET_COMPANY_RESUME;
+ CompanyID company2 = (CompanyID)this->window_number;
+ char msg[128];
+ seprintf(msg, lastof(msg), "!lockp %i", company2 + 1);
+ NetworkClientSendChatToServer(msg);
+ MarkWholeScreenDirty();
break;
}
#endif /* ENABLE_NETWORK */
diff --git a/src/crashlog.cpp b/src/crashlog.cpp
index cecbb63120..009405882d 100644
--- a/src/crashlog.cpp
+++ b/src/crashlog.cpp
@@ -87,7 +87,7 @@ char *CrashLog::LogCompiler(char *buffer, const char *last) const
char *CrashLog::LogOpenTTDVersion(char *buffer, const char *last) const
{
return buffer + seprintf(buffer, last,
- "OpenTTD version:\n"
+ "OpenTTD version: Novapolis patched client http://www.novapolis.net\n\n\n"
" Version: %s (%d)\n"
" NewGRF ver: %08x\n"
" Bits: %d\n"
@@ -313,7 +313,7 @@ char *CrashLog::LogGamelog(char *buffer, const char *last) const
char *CrashLog::FillCrashLog(char *buffer, const char *last) const
{
time_t cur_time = time(NULL);
- buffer += seprintf(buffer, last, "*** OpenTTD Crash Report ***\n\n");
+ buffer += seprintf(buffer, last, "*** OpenTTD Crash Report ***\nNovapolis patched client http://www.novapolis.net\nPlease, unless you encounter this bug with unpatched OpenTTD version, report bug to Novapolis team\n\n");
buffer += seprintf(buffer, last, "Crash at: %s", asctime(gmtime(&cur_time)));
YearMonthDay ymd;
diff --git a/src/depot_gui.cpp b/src/depot_gui.cpp
index bddfc7c2d7..cad8eed13f 100644
--- a/src/depot_gui.cpp
+++ b/src/depot_gui.cpp
@@ -28,7 +28,7 @@
#include "vehiclelist.h"
#include "order_backup.h"
#include "zoom_func.h"
-
+#include "hotkeys.h"
#include "widgets/depot_widget.h"
#include "table/strings.h"
@@ -81,34 +81,6 @@ static const NWidgetPart _nested_train_depot_widgets[] = {
EndContainer(),
};
-static WindowDesc _train_depot_desc(
- WDP_AUTO, "depot_train", 362, 123,
- WC_VEHICLE_DEPOT, WC_NONE,
- 0,
- _nested_train_depot_widgets, lengthof(_nested_train_depot_widgets)
-);
-
-static WindowDesc _road_depot_desc(
- WDP_AUTO, "depot_roadveh", 316, 97,
- WC_VEHICLE_DEPOT, WC_NONE,
- 0,
- _nested_train_depot_widgets, lengthof(_nested_train_depot_widgets)
-);
-
-static WindowDesc _ship_depot_desc(
- WDP_AUTO, "depot_ship", 306, 99,
- WC_VEHICLE_DEPOT, WC_NONE,
- 0,
- _nested_train_depot_widgets, lengthof(_nested_train_depot_widgets)
-);
-
-static WindowDesc _aircraft_depot_desc(
- WDP_AUTO, "depot_aircraft", 332, 99,
- WC_VEHICLE_DEPOT, WC_NONE,
- 0,
- _nested_train_depot_widgets, lengthof(_nested_train_depot_widgets)
-);
-
extern void DepotSortList(VehicleList *list);
/**
@@ -295,9 +267,16 @@ struct DepotWindow : Window {
this->sel, EIT_IN_DEPOT, free_wagon ? 0 : this->hscroll->GetPosition(), this->vehicle_over);
/* Length of consist in tiles with 1 fractional digit (rounded up) */
- SetDParam(0, CeilDiv(u->gcache.cached_total_length * 10, TILE_SIZE));
- SetDParam(1, 1);
- DrawString(rtl ? left + WD_FRAMERECT_LEFT : right - this->count_width, rtl ? left + this->count_width : right - WD_FRAMERECT_RIGHT, y + (this->resize.step_height - FONT_HEIGHT_SMALL) / 2, STR_TINY_BLACK_DECIMAL, TC_FROMSTRING, SA_RIGHT); // Draw the counter
+ if (_settings_client.gui.old_depot_train_length_calc) {
+ SetDParam(0, CeilDiv(u->gcache.cached_total_length, 8));
+ SetDParam(1, 1);
+ DrawString(rtl ? left + WD_FRAMERECT_LEFT : right - this->count_width, rtl ? left + this->count_width : right - WD_FRAMERECT_RIGHT, y + (this->resize.step_height - FONT_HEIGHT_SMALL) / 2, STR_TINY_BLACK_COMA, TC_FROMSTRING, SA_RIGHT); // Draw the counter
+ }
+ else {
+ SetDParam(0, CeilDiv(u->gcache.cached_total_length * 10, TILE_SIZE));
+ SetDParam(1, 1);
+ DrawString(rtl ? left + WD_FRAMERECT_LEFT : right - this->count_width, rtl ? left + this->count_width : right - WD_FRAMERECT_RIGHT, y + (this->resize.step_height - FONT_HEIGHT_SMALL) / 2, STR_TINY_BLACK_DECIMAL, TC_FROMSTRING, SA_RIGHT); // Draw the counter
+ }
break;
}
@@ -995,8 +974,24 @@ struct DepotWindow : Window {
return ES_NOT_HANDLED;
}
+
+ virtual EventState OnHotkey(int hotkey)
+ {
+ if (this->owner != _local_company) return ES_NOT_HANDLED;
+ return Window::OnHotkey(hotkey);
+ }
+
+ static HotkeyList hotkeys;
};
+static Hotkey depot_hotkeys[] = {
+ Hotkey(WKC_CTRL | 'F', "depot_go_all", WID_D_START_ALL),
+ Hotkey('R', "depot_build_vehicle", WID_D_BUILD),
+ Hotkey(WKC_NONE, "depot_clone_vehicle", WID_D_CLONE),
+ HOTKEY_LIST_END
+};
+HotkeyList DepotWindow::hotkeys("depot_gui", depot_hotkeys);
+
static void DepotSellAllConfirmationCallback(Window *win, bool confirmed)
{
if (confirmed) {
@@ -1007,6 +1002,38 @@ static void DepotSellAllConfirmationCallback(Window *win, bool confirmed)
}
}
+static WindowDesc _train_depot_desc(
+ WDP_AUTO, "depot_train", 362, 123,
+ WC_VEHICLE_DEPOT, WC_NONE,
+ 0,
+ _nested_train_depot_widgets, lengthof(_nested_train_depot_widgets),
+ &DepotWindow::hotkeys
+);
+
+static WindowDesc _road_depot_desc(
+ WDP_AUTO, "depot_roadveh", 316, 97,
+ WC_VEHICLE_DEPOT, WC_NONE,
+ 0,
+ _nested_train_depot_widgets, lengthof(_nested_train_depot_widgets),
+ &DepotWindow::hotkeys
+);
+
+static WindowDesc _ship_depot_desc(
+ WDP_AUTO, "depot_ship", 306, 99,
+ WC_VEHICLE_DEPOT, WC_NONE,
+ 0,
+ _nested_train_depot_widgets, lengthof(_nested_train_depot_widgets),
+ &DepotWindow::hotkeys
+);
+
+static WindowDesc _aircraft_depot_desc(
+ WDP_AUTO, "depot_aircraft", 332, 99,
+ WC_VEHICLE_DEPOT, WC_NONE,
+ 0,
+ _nested_train_depot_widgets, lengthof(_nested_train_depot_widgets),
+ &DepotWindow::hotkeys
+);
+
/**
* Opens a depot window
* @param tile The tile where the depot/hangar is located
diff --git a/src/economy.cpp b/src/economy.cpp
index ea9d610226..c4d1f3ed9e 100644
--- a/src/economy.cpp
+++ b/src/economy.cpp
@@ -53,6 +53,7 @@
#include "table/strings.h"
#include "table/pricebase.h"
+#include "cargo_table_gui.h"
#include "safeguards.h"
@@ -386,6 +387,7 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner)
/* Reset the ratings for the old owner */
t->ratings[old_owner] = RATING_INITIAL;
ClrBit(t->have_ratings, old_owner);
+ ClrBit(t->fund_regularly, old_owner);
/* Transfer exclusive rights */
if (t->exclusive_counter > 0 && t->exclusivity == old_owner) {
@@ -1081,6 +1083,14 @@ static Money DeliverGoods(int num_pieces, CargoID cargo_type, StationID dest, Ti
const CargoSpec *cs = CargoSpec::Get(cargo_type);
st->town->received[cs->town_effect].new_act += accepted;
+ /* Increase town's counter for all goods types only if delivered near town*/
+ if(CB_Enabled()){
+ if (_settings_client.gui.cb_distance_check == 0 || (DistanceManhattan(st->town->xy, st->xy) <= _settings_client.gui.cb_distance_check)) {
+ st->town->new_act_cargo[cargo_type] += accepted;
+ InvalidateWindowData(WC_CB_TOWN, st->town->index);
+ }
+ }
+
/* Determine profit */
Money profit = GetTransportedGoodsIncome(accepted, DistanceManhattan(source_tile, st->xy), days_in_transit, cargo_type);
@@ -1097,6 +1107,16 @@ static Money DeliverGoods(int num_pieces, CargoID cargo_type, StationID dest, Ti
}
}
+ company->cargo_income[cargo_type] += profit;
+ company->cargo_units[cargo_type] += num_pieces;
+
+ company->cargo_income_period[0][cargo_type] += profit;
+ company->cargo_units_period[0][cargo_type] += num_pieces;
+
+ company->cur_economy.cargo_income[cargo_type] += profit;
+
+ InvalidateCargosWindows(company->index);
+
return profit;
}
@@ -1923,6 +1943,11 @@ void CompaniesMonthlyLoop()
}
CompaniesPayInterest();
HandleEconomyFluctuations();
+
+ Company *c;
+ FOR_ALL_COMPANIES(c){
+ CargoResetPeriods(c);
+ }
}
static void DoAcquireCompany(Company *c)
diff --git a/src/gfx.cpp b/src/gfx.cpp
index a8079d839d..4491e60705 100644
--- a/src/gfx.cpp
+++ b/src/gfx.cpp
@@ -33,6 +33,7 @@ bool _fullscreen;
byte _support8bpp;
CursorVars _cursor;
bool _ctrl_pressed; ///< Is Ctrl pressed?
+bool _alt_pressed; ///< Is Alt pressed?
bool _shift_pressed; ///< Is Shift pressed?
byte _fast_forward;
bool _left_button_down; ///< Is left mouse button pressed?
diff --git a/src/gfx_func.h b/src/gfx_func.h
index 155da59924..13f469c02c 100644
--- a/src/gfx_func.h
+++ b/src/gfx_func.h
@@ -55,6 +55,7 @@ extern bool _fullscreen;
extern byte _support8bpp;
extern CursorVars _cursor;
extern bool _ctrl_pressed; ///< Is Ctrl pressed?
+extern bool _alt_pressed; ///< Is Alt pressed?
extern bool _shift_pressed; ///< Is Shift pressed?
extern byte _fast_forward;
diff --git a/src/gfx_type.h b/src/gfx_type.h
index b209d6e2db..c5ffa80f3b 100644
--- a/src/gfx_type.h
+++ b/src/gfx_type.h
@@ -104,6 +104,16 @@ enum WindowKeyCodes {
WKC_COMMA = 151, ///< , Comma
WKC_PERIOD = 152, ///< . Period
WKC_MINUS = 153, ///< - Minus
+
+ WKC_L_BRACE = 154, ///< { Left brace
+ WKC_R_BRACE = 155, ///< } Right brace
+
+ WKC_L_PAREN = 157, ///< ( Left parentheses
+ WKC_R_PAREN = 158, ///< ) Right parentheses
+ WKC_PLUS = 159, ///< + Plus
+ WKC_EXCLAIM = 160, ///< ! Exclamation mark
+ WKC_ASTERISK = 161, ///< * Asterisk
+ WKC_DOLLAR = 162, ///< $ Dollar sign
};
/** A single sprite of a list of animated cursors */
diff --git a/src/gfxinit.cpp b/src/gfxinit.cpp
index e50327c5e4..88d4b03f6d 100644
--- a/src/gfxinit.cpp
+++ b/src/gfxinit.cpp
@@ -192,6 +192,7 @@ static void LoadSpriteTables()
i++
);
}
+ LoadGrfFile("innerhighlight.grf", SPR_INNER_HIGHLIGHT_BASE, i++);
/* Initialize the unicode to sprite mapping table */
InitializeUnicodeGlyphMap();
diff --git a/src/goal_gui.cpp b/src/goal_gui.cpp
index 5ec929e72d..3bd408f48a 100644
--- a/src/goal_gui.cpp
+++ b/src/goal_gui.cpp
@@ -184,7 +184,15 @@ struct GoalListWindow : public Window {
resize->height = d.height;
- d.height *= 5;
+ uint num = 0;
+ const Goal *s;
+ FOR_ALL_GOALS(s) {
+ if (s->company == INVALID_COMPANY || s->company == this->window_number) {
+ num++;
+ }
+ }
+
+ d.height *= (5 + num);
d.width += padding.width + WD_FRAMERECT_RIGHT + WD_FRAMERECT_LEFT;
d.height += padding.height + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
*size = maxdim(*size, d);
diff --git a/src/graph_gui.cpp b/src/graph_gui.cpp
index c8b2298e16..e9e0f7549f 100644
--- a/src/graph_gui.cpp
+++ b/src/graph_gui.cpp
@@ -103,6 +103,23 @@ struct GraphLegendWindow : Window {
}
};
+
+/** Construct the row containing the digit keys. */
+static NWidgetBase *MakeCargoButtons(int *biggest_index)
+{
+ NWidgetVertical *ver = new NWidgetVertical;
+
+ for (int i = 0; i < _sorted_standard_cargo_specs_size; i++) {
+ NWidgetBackground *leaf = new NWidgetBackground(WWT_PANEL, COLOUR_ORANGE, WID_CPR_CARGO_FIRST + i, NULL);
+ leaf->tool_tip = STR_GRAPH_CARGO_PAYMENT_TOGGLE_CARGO;
+ leaf->SetFill(1, 0);
+ leaf->SetLowered(true);
+ ver->Add(leaf);
+ }
+ *biggest_index = WID_CPR_CARGO_FIRST + _sorted_standard_cargo_specs_size - 1;
+ return ver;
+}
+
/**
* Construct a vertical list of buttons, one for each company.
* @param biggest_index Storage for collecting the biggest index used in the returned tree.
@@ -533,10 +550,64 @@ public:
return INVALID_DATAPOINT;
}
+ void UpdateExcludedData()
+ {
+ this->excluded_data = 0;
+
+ int i = 0;
+ const CargoSpec *cs;
+ FOR_ALL_SORTED_STANDARD_CARGOSPECS(cs) {
+ if (HasBit(_legend_excluded_cargo, cs->Index())) SetBit(this->excluded_data, i);
+ i++;
+ }
+ }
+
+ void UpdateLoweredWidgets()
+ {
+ for (int i = 0; i < _sorted_standard_cargo_specs_size; i++) {
+ this->SetWidgetLoweredState(WID_CPR_CARGO_FIRST + i, !HasBit(this->excluded_data, i));
+ }
+ }
+
virtual void OnClick(Point pt, int widget, int click_count)
{
+ switch (widget) {
/* Clicked on legend? */
- if (widget == WID_CV_KEY_BUTTON) ShowGraphLegend();
+ case WID_CV_KEY_BUTTON:
+ ShowGraphLegend();
+ break;
+ case WID_CPR_ENABLE_CARGOES:
+ /* Remove all cargoes from the excluded lists. */
+ _legend_excluded_cargo = 0;
+ this->excluded_data = 0;
+ this->UpdateLoweredWidgets();
+ this->SetDirty();
+ break;
+
+ case WID_CPR_DISABLE_CARGOES: {
+ /* Add all cargoes to the excluded lists. */
+ int i = 0;
+ const CargoSpec *cs;
+ FOR_ALL_SORTED_STANDARD_CARGOSPECS(cs) {
+ SetBit(_legend_excluded_cargo, cs->Index());
+ SetBit(this->excluded_data, i);
+ i++;
+ }
+ this->UpdateLoweredWidgets();
+ this->SetDirty();
+ break;
+ }
+
+ default:
+ if (widget >= WID_CPR_CARGO_FIRST) {
+ int i = widget - WID_CPR_CARGO_FIRST;
+ ToggleBit(_legend_excluded_cargo, _sorted_cargo_specs[i]->Index());
+ this->ToggleWidgetLoweredState(widget);
+ this->UpdateExcludedData();
+ this->SetDirty();
+ }
+ break;
+ }
}
virtual void OnTick()
@@ -674,8 +745,60 @@ struct IncomeGraphWindow : BaseGraphWindow {
virtual OverflowSafeInt64 GetGraphData(const Company *c, int j)
{
+ if(_legend_excluded_cargo == 0){
return c->old_economy[j].income;
}
+ uint total_income = 0;
+ const CargoSpec *cs;
+ FOR_ALL_SORTED_STANDARD_CARGOSPECS(cs) {
+ if (!HasBit(_legend_excluded_cargo, cs->Index())){
+ total_income += c->old_economy[j].cargo_income[cs->Index()];
+ }
+ }
+ return total_income;
+ }
+
+ virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
+ {
+ if (widget < WID_CPR_CARGO_FIRST) {
+ BaseGraphWindow::UpdateWidgetSize(widget, size, padding, fill, resize);
+ return;
+ }
+
+ const CargoSpec *cs = _sorted_cargo_specs[widget - WID_CPR_CARGO_FIRST];
+ SetDParam(0, cs->name);
+ Dimension d = GetStringBoundingBox(STR_GRAPH_CARGO_PAYMENT_CARGO);
+ d.width += 14; // colour field
+ d.width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
+ d.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
+ *size = maxdim(d, *size);
+ }
+
+ virtual void DrawWidget(const Rect &r, int widget) const
+ {
+ if (widget < WID_CPR_CARGO_FIRST) {
+ BaseGraphWindow::DrawWidget(r, widget);
+ return;
+ }
+
+ const CargoSpec *cs = _sorted_cargo_specs[widget - WID_CPR_CARGO_FIRST];
+ bool rtl = _current_text_dir == TD_RTL;
+
+ /* Since the buttons have no text, no images,
+ * both the text and the coloured box have to be manually painted.
+ * clk_dif will move one pixel down and one pixel to the right
+ * when the button is clicked */
+ byte clk_dif = this->IsWidgetLowered(widget) ? 1 : 0;
+ int x = r.left + WD_FRAMERECT_LEFT;
+ int y = r.top;
+
+ int rect_x = clk_dif + (rtl ? r.right - 12 : r.left + WD_FRAMERECT_LEFT);
+
+ GfxFillRect(rect_x, y + clk_dif, rect_x + 8, y + 5 + clk_dif, PC_BLACK);
+ GfxFillRect(rect_x + 1, y + 1 + clk_dif, rect_x + 7, y + 4 + clk_dif, cs->legend_colour);
+ SetDParam(0, cs->name);
+ DrawString(rtl ? r.left : x + 14 + clk_dif, (rtl ? r.right - 14 + clk_dif : r.right), y + clk_dif, STR_GRAPH_CARGO_PAYMENT_CARGO);
+ }
};
static const NWidgetPart _nested_income_graph_widgets[] = {
@@ -690,6 +813,14 @@ static const NWidgetPart _nested_income_graph_widgets[] = {
NWidget(WWT_PANEL, COLOUR_GREY, WID_CV_BACKGROUND),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CV_GRAPH), SetMinimalSize(576, 128), SetFill(1, 1), SetResize(1, 1),
+ NWidget(NWID_VERTICAL),//add
+ NWidget(NWID_SPACER), SetMinimalSize(0, 24), SetFill(0, 0), SetResize(0, 1),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_CPR_ENABLE_CARGOES), SetDataTip(STR_GRAPH_CARGO_ENABLE_ALL, STR_GRAPH_CARGO_TOOLTIP_ENABLE_ALL), SetFill(1, 0),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_CPR_DISABLE_CARGOES), SetDataTip(STR_GRAPH_CARGO_DISABLE_ALL, STR_GRAPH_CARGO_TOOLTIP_DISABLE_ALL), SetFill(1, 0),
+ NWidget(NWID_SPACER), SetMinimalSize(0, 4),
+ NWidgetFunction(MakeCargoButtons),
+ NWidget(NWID_SPACER), SetMinimalSize(0, 24), SetFill(0, 1), SetResize(0, 1),
+ EndContainer(),//add
NWidget(NWID_VERTICAL),
NWidget(NWID_SPACER), SetFill(0, 1), SetResize(0, 1),
NWidget(WWT_RESIZEBOX, COLOUR_GREY, WID_CV_RESIZE),
@@ -723,8 +854,60 @@ struct DeliveredCargoGraphWindow : BaseGraphWindow {
virtual OverflowSafeInt64 GetGraphData(const Company *c, int j)
{
+ if(_legend_excluded_cargo == 0){
return c->old_economy[j].delivered_cargo.GetSum();
}
+ uint total_delivered = 0;
+ const CargoSpec *cs;
+ FOR_ALL_SORTED_STANDARD_CARGOSPECS(cs) {
+ if (!HasBit(_legend_excluded_cargo, cs->Index())){
+ total_delivered += c->old_economy[j].delivered_cargo[cs->Index()];
+ }
+ }
+ return total_delivered;
+ }
+
+ virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
+ {
+ if (widget < WID_CPR_CARGO_FIRST) {
+ BaseGraphWindow::UpdateWidgetSize(widget, size, padding, fill, resize);
+ return;
+ }
+
+ const CargoSpec *cs = _sorted_cargo_specs[widget - WID_CPR_CARGO_FIRST];
+ SetDParam(0, cs->name);
+ Dimension d = GetStringBoundingBox(STR_GRAPH_CARGO_PAYMENT_CARGO);
+ d.width += 14; // colour field
+ d.width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
+ d.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
+ *size = maxdim(d, *size);
+ }
+
+ virtual void DrawWidget(const Rect &r, int widget) const
+ {
+ if (widget < WID_CPR_CARGO_FIRST) {
+ BaseGraphWindow::DrawWidget(r, widget);
+ return;
+ }
+
+ const CargoSpec *cs = _sorted_cargo_specs[widget - WID_CPR_CARGO_FIRST];
+ bool rtl = _current_text_dir == TD_RTL;
+
+ /* Since the buttons have no text, no images,
+ * both the text and the coloured box have to be manually painted.
+ * clk_dif will move one pixel down and one pixel to the right
+ * when the button is clicked */
+ byte clk_dif = this->IsWidgetLowered(widget) ? 1 : 0;
+ int x = r.left + WD_FRAMERECT_LEFT;
+ int y = r.top;
+
+ int rect_x = clk_dif + (rtl ? r.right - 12 : r.left + WD_FRAMERECT_LEFT);
+
+ GfxFillRect(rect_x, y + clk_dif, rect_x + 8, y + 5 + clk_dif, PC_BLACK);
+ GfxFillRect(rect_x + 1, y + 1 + clk_dif, rect_x + 7, y + 4 + clk_dif, cs->legend_colour);
+ SetDParam(0, cs->name);
+ DrawString(rtl ? r.left : x + 14 + clk_dif, (rtl ? r.right - 14 + clk_dif : r.right), y + clk_dif, STR_GRAPH_CARGO_PAYMENT_CARGO);
+ }
};
static const NWidgetPart _nested_delivered_cargo_graph_widgets[] = {
@@ -739,6 +922,15 @@ static const NWidgetPart _nested_delivered_cargo_graph_widgets[] = {
NWidget(WWT_PANEL, COLOUR_GREY, WID_CV_BACKGROUND),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CV_GRAPH), SetMinimalSize(576, 128), SetFill(1, 1), SetResize(1, 1),
+ NWidget(NWID_VERTICAL),//add
+ NWidget(NWID_SPACER), SetMinimalSize(0, 24), SetFill(0, 0), SetResize(0, 1),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_CPR_ENABLE_CARGOES), SetDataTip(STR_GRAPH_CARGO_ENABLE_ALL, STR_GRAPH_CARGO_TOOLTIP_ENABLE_ALL), SetFill(1, 0),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_CPR_DISABLE_CARGOES), SetDataTip(STR_GRAPH_CARGO_DISABLE_ALL, STR_GRAPH_CARGO_TOOLTIP_DISABLE_ALL), SetFill(1, 0),
+ NWidget(NWID_SPACER), SetMinimalSize(0, 4),
+ NWidgetFunction(MakeCargoButtons),
+ NWidget(NWID_SPACER), SetMinimalSize(0, 24), SetFill(0, 1), SetResize(0, 1),
+ EndContainer(),//add
+ NWidget(NWID_SPACER), SetMinimalSize(5, 0), SetFill(0, 1), SetResize(0, 1),
NWidget(NWID_VERTICAL),
NWidget(NWID_SPACER), SetFill(0, 1), SetResize(0, 1),
NWidget(WWT_RESIZEBOX, COLOUR_GREY, WID_CV_RESIZE),
@@ -899,7 +1091,7 @@ struct PaymentRatesGraphWindow : BaseGraphWindow {
}
this->first_init = false;
}
-
+/*
void UpdateExcludedData()
{
this->excluded_data = 0;
@@ -918,7 +1110,7 @@ struct PaymentRatesGraphWindow : BaseGraphWindow {
this->SetWidgetLoweredState(WID_CPR_CARGO_FIRST + i, !HasBit(this->excluded_data, i));
}
}
-
+*/
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
{
if (widget < WID_CPR_CARGO_FIRST) {
@@ -960,12 +1152,12 @@ struct PaymentRatesGraphWindow : BaseGraphWindow {
SetDParam(0, cs->name);
DrawString(rtl ? r.left : x + 14 + clk_dif, (rtl ? r.right - 14 + clk_dif : r.right), y + clk_dif, STR_GRAPH_CARGO_PAYMENT_CARGO);
}
-
+/*
virtual void OnClick(Point pt, int widget, int click_count)
{
switch (widget) {
case WID_CPR_ENABLE_CARGOES:
- /* Remove all cargoes from the excluded lists. */
+ /* Remove all cargoes from the excluded lists. * /
_legend_excluded_cargo = 0;
this->excluded_data = 0;
this->UpdateLoweredWidgets();
@@ -973,7 +1165,7 @@ struct PaymentRatesGraphWindow : BaseGraphWindow {
break;
case WID_CPR_DISABLE_CARGOES: {
- /* Add all cargoes to the excluded lists. */
+ /* Add all cargoes to the excluded lists. * /
int i = 0;
const CargoSpec *cs;
FOR_ALL_SORTED_STANDARD_CARGOSPECS(cs) {
@@ -997,7 +1189,7 @@ struct PaymentRatesGraphWindow : BaseGraphWindow {
break;
}
}
-
+*/
virtual void OnTick()
{
/* Override default OnTick */
@@ -1031,23 +1223,6 @@ struct PaymentRatesGraphWindow : BaseGraphWindow {
}
};
-/** Construct the row containing the digit keys. */
-static NWidgetBase *MakeCargoButtons(int *biggest_index)
-{
- NWidgetVertical *ver = new NWidgetVertical;
-
- for (int i = 0; i < _sorted_standard_cargo_specs_size; i++) {
- NWidgetBackground *leaf = new NWidgetBackground(WWT_PANEL, COLOUR_ORANGE, WID_CPR_CARGO_FIRST + i, NULL);
- leaf->tool_tip = STR_GRAPH_CARGO_PAYMENT_TOGGLE_CARGO;
- leaf->SetFill(1, 0);
- leaf->SetLowered(true);
- ver->Add(leaf);
- }
- *biggest_index = WID_CPR_CARGO_FIRST + _sorted_standard_cargo_specs_size - 1;
- return ver;
-}
-
-
static const NWidgetPart _nested_cargo_payment_rates_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
@@ -1582,3 +1757,4 @@ void ShowPerformanceRatingDetail()
{
AllocateWindowDescFront(&_performance_rating_detail_desc, 0);
}
+
diff --git a/src/gui.h b/src/gui.h
index 61f2e01307..fc0381c9b7 100644
--- a/src/gui.h
+++ b/src/gui.h
@@ -39,6 +39,10 @@ Window *ShowBuildDocksScenToolbar();
/* airport_gui.cpp */
Window *ShowBuildAirToolbar();
+/* commands_gui.cpp */
+void ShowCommandsToolbar();
+void ShowLoginWindow();
+
/* tgp_gui.cpp */
void ShowGenerateLandscape();
void ShowHeightmapLoad();
diff --git a/src/hotkeys.cpp b/src/hotkeys.cpp
index 8933acb840..e21059ad1a 100644
--- a/src/hotkeys.cpp
+++ b/src/hotkeys.cpp
@@ -61,6 +61,22 @@ static const KeycodeNames _keycode_to_name[] = {
{"NUM_MINUS", WKC_NUM_MINUS},
{"=", WKC_EQUALS},
{"-", WKC_MINUS},
+
+ {"BACKSPACE", WKC_BACKSPACE},
+ {"SLASH", WKC_SLASH},
+ {"SEMICOLON", WKC_SEMICOLON},
+ {"L_BRACKET", WKC_L_BRACKET},
+ {"BACKSLASH", WKC_BACKSLASH},
+ {"R_BRACKET", WKC_R_BRACKET},
+ {"SINGLEQUOTE", WKC_SINGLEQUOTE},
+ {"PERIOD", WKC_PERIOD},
+
+ {"L_BRACE", WKC_L_BRACE},
+ {"R_BRACE", WKC_R_BRACE},
+ {"L_PAREN", WKC_L_PAREN},
+ {"R_PAREN", WKC_R_PAREN},
+ {"EXCLAIM", WKC_EXCLAIM},
+ {"ASTERISK", WKC_ASTERISK},
};
/**
diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp
index e287fbd98d..6b83715672 100644
--- a/src/industry_gui.cpp
+++ b/src/industry_gui.cpp
@@ -30,6 +30,7 @@
#include "tilehighlight_func.h"
#include "string_func.h"
#include "sortlist_type.h"
+#include "widgets/dropdown_type.h"
#include "widgets/dropdown_func.h"
#include "company_base.h"
#include "core/geometry_func.hpp"
@@ -41,6 +42,7 @@
#include "widgets/industry_widget.h"
#include "table/strings.h"
+#include "hotkeys.h"
#include "safeguards.h"
@@ -188,14 +190,6 @@ static const NWidgetPart _nested_build_industry_widgets[] = {
EndContainer(),
};
-/** Window definition of the dynamic place industries gui */
-static WindowDesc _build_industry_desc(
- WDP_AUTO, "build_industry", 170, 212,
- WC_BUILD_INDUSTRY, WC_NONE,
- WDF_CONSTRUCTION,
- _nested_build_industry_widgets, lengthof(_nested_build_industry_widgets)
-);
-
/** Build (fund or prospect) a new industry, */
class BuildIndustryWindow : public Window {
int selected_index; ///< index of the element in the matrix
@@ -267,7 +261,7 @@ class BuildIndustryWindow : public Window {
}
public:
- BuildIndustryWindow() : Window(&_build_industry_desc)
+ BuildIndustryWindow(WindowDesc *desc) : Window(desc)
{
this->timer_enabled = _loaded_newgrf_features.has_newindustries;
@@ -625,13 +619,38 @@ public:
if (indsp == NULL) this->enabled[this->selected_index] = _settings_game.difficulty.industry_density != ID_FUND_ONLY;
this->SetButtons();
}
+
+ virtual EventState OnHotkey(int hotkey)
+ {
+ return Window::OnHotkey(hotkey);
+ }
+
+ static HotkeyList hotkeys;
};
+static Hotkey build_industry_hotkeys[] = {
+ Hotkey((uint16)0, "display_chain", WID_DPI_DISPLAY_WIDGET),
+ Hotkey((uint16)0, "build_button", WID_DPI_FUND_WIDGET),
+ HOTKEY_LIST_END
+};
+
+HotkeyList BuildIndustryWindow::hotkeys("industry_fund_gui", build_industry_hotkeys);
+
+/** Window definition of the dynamic place industries gui */
+static WindowDesc _build_industry_desc(
+ WDP_AUTO, "build_industry", 170, 212,
+ WC_BUILD_INDUSTRY, WC_NONE,
+ WDF_CONSTRUCTION,
+ _nested_build_industry_widgets, lengthof(_nested_build_industry_widgets),
+ &BuildIndustryWindow::hotkeys
+);
+
+
void ShowBuildIndustryWindow()
{
if (_game_mode != GM_EDITOR && !Company::IsValidID(_local_company)) return;
if (BringWindowToFrontById(WC_BUILD_INDUSTRY, 0)) return;
- new BuildIndustryWindow();
+ new BuildIndustryWindow(&_build_industry_desc);
}
static void UpdateIndustryProduction(Industry *i);
@@ -1059,6 +1078,7 @@ static const NWidgetPart _nested_industry_directory_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_ID_DROPDOWN_ORDER), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER),
NWidget(WWT_DROPDOWN, COLOUR_BROWN, WID_ID_DROPDOWN_CRITERIA), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_SORT_CRITERIA),
+ NWidget(WWT_DROPDOWN, COLOUR_BROWN, WID_ID_DROPDOWN_FILTER), SetDataTip(STR_BUTTON_FILTER, STR_TOOLTIP_FILTER_CRITERIA),
NWidget(WWT_PANEL, COLOUR_BROWN), SetResize(1, 0), EndContainer(),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_BROWN, WID_ID_INDUSTRY_LIST), SetDataTip(0x0, STR_INDUSTRY_DIRECTORY_LIST_CAPTION), SetResize(1, 1), SetScrollbar(WID_ID_SCROLLBAR), EndContainer(),
@@ -1086,6 +1106,10 @@ protected:
static const StringID sorter_names[];
static GUIIndustryList::SortFunction * const sorter_funcs[];
+ /* type_filter[industry_type] is set to true if player wishes that type to by displayed */
+ static bool type_filter[NUM_INDUSTRYTYPES];
+ static bool initialized;
+
GUIIndustryList industries;
Scrollbar *vscroll;
@@ -1097,7 +1121,9 @@ protected:
const Industry *i;
FOR_ALL_INDUSTRIES(i) {
- *this->industries.Append() = i;
+ if (this->type_filter[i->type]){
+ *this->industries.Append() = i;
+ }
}
this->industries.Compact();
@@ -1229,9 +1255,17 @@ protected:
}
}
+ void initIndustryTypeFilter()
+ {
+ for (IndustryType indt = 0; indt < NUM_INDUSTRYTYPES; ++indt)
+ this->type_filter[indt] = true;
+ IndustryDirectoryWindow::initialized = true;
+ }
+
public:
IndustryDirectoryWindow(WindowDesc *desc, WindowNumber number) : Window(desc)
{
+ if (IndustryDirectoryWindow::initialized == false) this->initIndustryTypeFilter();
this->CreateNestedTree();
this->vscroll = this->GetScrollbar(WID_ID_SCROLLBAR);
@@ -1300,6 +1334,11 @@ public:
break;
}
+ case WID_ID_DROPDOWN_FILTER: {
+ size->width = 65;
+ break;
+ }
+
case WID_ID_INDUSTRY_LIST: {
Dimension d = GetStringBoundingBox(STR_INDUSTRY_DIRECTORY_NONE);
for (uint i = 0; i < this->industries.Length(); i++) {
@@ -1328,6 +1367,22 @@ public:
ShowDropDownMenu(this, IndustryDirectoryWindow::sorter_names, this->industries.SortType(), WID_ID_DROPDOWN_CRITERIA, 0, 0);
break;
+ case WID_ID_DROPDOWN_FILTER: {
+ DropDownList *list = new DropDownList();
+ *list->Append() = new DropDownListStringItem(STR_BUTTON_FILTER_SELECT_ALL, -2, false);
+ *list->Append() = new DropDownListStringItem(STR_BUTTON_FILTER_SELECT_NONE, -1, false);
+ *list->Append() = new DropDownListItem(-3, false);
+
+ for (IndustryType indt = 0; indt < NUM_INDUSTRYTYPES; ++indt) {
+ const IndustrySpec *inds = GetIndustrySpec(indt);
+ if (inds->enabled)
+ *list->Append() = new DropDownListCheckedItem(inds->name, indt, false, IndustryDirectoryWindow::type_filter[indt]);
+ }
+
+ ShowDropDownList(this, list, -2, WID_ID_DROPDOWN_FILTER, 0, true, false);
+ break;
+ }
+
case WID_ID_INDUSTRY_LIST: {
uint p = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_ID_INDUSTRY_LIST, WD_FRAMERECT_TOP);
if (p < this->industries.Length()) {
@@ -1344,10 +1399,27 @@ public:
virtual void OnDropdownSelect(int widget, int index)
{
- if (this->industries.SortType() != index) {
- this->industries.SetSortType(index);
- this->BuildSortIndustriesList();
+ if (widget == WID_ID_DROPDOWN_CRITERIA) {
+ if (this->industries.SortType() != index) {
+ this->industries.SetSortType(index);
+ }
}
+ else if (widget == WID_ID_DROPDOWN_FILTER) {
+ if ( index == -1 ) { // aka SELECT NONE
+ for (IndustryType indt = 0; indt < NUM_INDUSTRYTYPES; ++indt)
+ IndustryDirectoryWindow::type_filter[indt] = false;
+ // must SetDurty to force redraw of the listing widget
+ this->SetDirty();
+ }
+ else if ( index == -2 ) { // aka SELECT ALL
+ for (IndustryType indt = 0; indt < NUM_INDUSTRYTYPES; ++indt)
+ IndustryDirectoryWindow::type_filter[indt] = true;
+ }
+ else
+ IndustryDirectoryWindow::type_filter[index] = IndustryDirectoryWindow::type_filter[index] ? false: true;
+ this->industries.ForceRebuild();
+ }
+ this->BuildSortIndustriesList();
}
virtual void OnResize()
@@ -1385,6 +1457,8 @@ public:
Listing IndustryDirectoryWindow::last_sorting = {false, 0};
const Industry *IndustryDirectoryWindow::last_industry = NULL;
+bool IndustryDirectoryWindow::initialized = false;
+bool IndustryDirectoryWindow::type_filter[NUM_INDUSTRYTYPES];
/* Available station sorting functions. */
GUIIndustryList::SortFunction * const IndustryDirectoryWindow::sorter_funcs[] = {
diff --git a/src/lang/english.txt b/src/lang/english.txt
index db4f8844b8..b4727e9781 100644
--- a/src/lang/english.txt
+++ b/src/lang/english.txt
@@ -232,6 +232,9 @@ STR_TOOLTIP_GROUP_ORDER :{BLACK}Select g
STR_TOOLTIP_SORT_ORDER :{BLACK}Select sorting order (descending/ascending)
STR_TOOLTIP_SORT_CRITERIA :{BLACK}Select sorting criteria
STR_TOOLTIP_FILTER_CRITERIA :{BLACK}Select filtering criteria
+STR_BUTTON_FILTER :{BLACK}Filter
+STR_BUTTON_FILTER_SELECT_ALL :Select All
+STR_BUTTON_FILTER_SELECT_NONE :Select None
STR_BUTTON_SORT_BY :{BLACK}Sort by
STR_BUTTON_LOCATION :{BLACK}Location
STR_BUTTON_RENAME :{BLACK}Rename
@@ -322,9 +325,11 @@ STR_TOOLBAR_TOOLTIP_DISPLAY_TOWN_DIRECTORY :{BLACK}Display
STR_TOOLBAR_TOOLTIP_DISPLAY_SUBSIDIES :{BLACK}Display subsidies
STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_STATIONS :{BLACK}Display list of company's stations
STR_TOOLBAR_TOOLTIP_DISPLAY_COMPANY_FINANCES :{BLACK}Display company finances information
+STR_TOOLBAR_TOOLTIP_DISPLAY_COMPANY_CARGOS :{BLACK}Display company cargos information
STR_TOOLBAR_TOOLTIP_DISPLAY_COMPANY_GENERAL :{BLACK}Display general company information
STR_TOOLBAR_TOOLTIP_DISPLAY_STORY_BOOK :{BLACK}Display story book
STR_TOOLBAR_TOOLTIP_DISPLAY_GOALS_LIST :{BLACK}Display goal list
+STR_TOOLBAR_TOOLTIP_DISPLAY_WATCH :{BLACK}Watch company's actions
STR_TOOLBAR_TOOLTIP_DISPLAY_GRAPHS :{BLACK}Display graphs
STR_TOOLBAR_TOOLTIP_DISPLAY_COMPANY_LEAGUE :{BLACK}Display company league table
STR_TOOLBAR_TOOLTIP_FUND_CONSTRUCTION_OF_NEW :{BLACK}Fund construction of new industry or list all industries
@@ -376,6 +381,7 @@ STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Settings
STR_SETTINGS_MENU_SCRIPT_SETTINGS :AI/Game script settings
STR_SETTINGS_MENU_NEWGRF_SETTINGS :NewGRF settings
STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Transparency options
+STR_SETTINGS_MENU_ZONING :Zoning
STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Town names displayed
STR_SETTINGS_MENU_STATION_NAMES_DISPLAYED :Station names displayed
STR_SETTINGS_MENU_WAYPOINTS_DISPLAYED :Waypoint names displayed
@@ -400,6 +406,7 @@ STR_MAP_MENU_MAP_OF_WORLD :Map of world
STR_MAP_MENU_EXTRA_VIEW_PORT :Extra viewport
STR_MAP_MENU_LINGRAPH_LEGEND :Cargo Flow Legend
STR_MAP_MENU_SIGN_LIST :Sign list
+STR_MAP_MENU_WATCH_COMPANY :Watch Company
############ range for town menu starts
STR_TOWN_MENU_TOWN_DIRECTORY :Town directory
@@ -468,7 +475,7 @@ STR_NEWS_MENU_MESSAGE_HISTORY_MENU :Message history
############ range for about menu starts
STR_ABOUT_MENU_LAND_BLOCK_INFO :Land area information
-STR_ABOUT_MENU_SEPARATOR :
+STR_ABOUT_MENU_SEPARATOR :Novapolis
STR_ABOUT_MENU_TOGGLE_CONSOLE :Toggle console
STR_ABOUT_MENU_AI_DEBUG :AI/Game script debug
STR_ABOUT_MENU_SCREENSHOT :Screenshot
@@ -479,6 +486,7 @@ STR_ABOUT_MENU_ABOUT_OPENTTD :About 'OpenTTD'
STR_ABOUT_MENU_SPRITE_ALIGNER :Sprite aligner
STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Toggle bounding boxes
STR_ABOUT_MENU_TOGGLE_DIRTY_BLOCKS :Toggle colouring of dirty blocks
+STR_ABOUT_MENU_LOGIN_WINDOW :Login Window
############ range ends here
############ range for ordinal numbers used for the place in the highscore window
@@ -1707,6 +1715,26 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Allow trains to
STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Change setting value
+STR_CONFIG_SETTING_VEHICLES_CTRL :{ORANGE}Controls & Orders
+STR_CONFIG_SETTING_ORDER_SHORTCUTS :{ORANGE}Order's Shortcuts
+STR_CONFIG_SETTING_CTRL_ENABLE_CTRLCLICK_STARTSTOP :Allow ctrl+left-click vehicles to start or stop them: {STRING2}
+STR_CONFIG_SETTING_AUTOSET_NOLOAD_ON_TRANSFER :"Transfer" orders are "No Loading" by default: {STRING2}
+STR_CONFIG_SETTING_AUTOSET_NOLOAD_ON_UNLOAD :"Unload all" orders are "No Loading" by default: {STRING2}
+
+STR_CONFIG_SETTING_CTRL_GOTOSHORTCUT_CTRLLCLICK :ctrl+left-click: {STRING2}
+STR_CONFIG_SETTING_CTRL_GOTOSHORTCUT_CTRLSHIFTLCLICK :ctrl+shift+left-click: {STRING2}
+STR_CONFIG_SETTING_CTRL_GOTOSHORTCUT_SHIFTLCLICK :shift+left-click: {STRING2}
+STR_CONFIG_SETTING_CTRL_GOTOSHORTCUT_ALTLCLICK :alt+left-click: {STRING2}
+STR_CONFIG_SETTING_CTRL_GOTOSHORTCUT_ALTSHIFTCLICK :alt+shift+left-click: {STRING2}
+STR_CONFIG_SETTING_CTRL_GOTOSHORTCUT_CTRLALTLCLICK :ctrl+alt+left-click: {STRING2}
+STR_CONFIG_SETTING_CTRL_GOTOSHORTOPTS_NONE :do nothing
+STR_CONFIG_SETTING_CTRL_GOTOSHORTOPTS_FULL_LOAD_ANY :Full load any cargo
+STR_CONFIG_SETTING_CTRL_GOTOSHORTOPTS_TRANSFER_CARGO :Transfer cargo
+STR_CONFIG_SETTING_CTRL_GOTOSHORTOPTS_UNLOAD_ALL :Force unload of all cargo
+STR_CONFIG_SETTING_CTRL_GOTOSHORTOPTS_FEEDERLOAD :Feeder Load (replace first order)
+STR_CONFIG_SETTING_CTRL_GOTOSHORTOPTS_FEEDERDROP :Feeder Unload (replace last order)
+STR_CONFIG_SETTING_CTRL_GOTOSHORTOPTS_NO_LOAD :Do not load any cargo
+
# Config errors
STR_CONFIG_ERROR :{WHITE}Error with the configuration file...
STR_CONFIG_ERROR_ARRAY :{WHITE}... error in array '{RAW_STRING}'
@@ -2316,6 +2344,7 @@ STR_RAIL_TOOLBAR_MAGLEV_CONSTRUCTION_CAPTION :Maglev Construc
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}Build railway track. Ctrl toggles build/remove for railway construction. Shift toggles building/showing cost estimate
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_AUTORAIL :{BLACK}Build railway track using the Autorail mode. Ctrl toggles build/remove for railway construction. Shift toggles building/showing cost estimate
+STR_RAIL_TOOLBAR_TOOLTIP_BUILD_POLYRAIL :{BLACK}Build railway track using the Polyline mode. Ctrl toggles build/remove for railway construction. Shift toggles building/showing cost estimate
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Build train depot (for buying and servicing trains). Shift toggles building/showing cost estimate
STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL_TO_WAYPOINT :{BLACK}Convert rail to waypoint. Ctrl enables joining waypoints. Shift toggles building/showing cost estimate
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_STATION :{BLACK}Build railway station. Ctrl enables joining stations. Shift toggles building/showing cost estimate
@@ -2333,6 +2362,7 @@ STR_RAIL_NAME_MAGLEV :Maglev
# Rail depot construction window
STR_BUILD_DEPOT_TRAIN_ORIENTATION_CAPTION :{WHITE}Train Depot Orientation
STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP :{BLACK}Select railway depot orientation
+STR_BUILD_DEPOT_TRAIN_ORIENTATION_AUTO_TOOLTIP :{BLACK}Automatically select railway depot orientation based on environment
# Rail waypoint construction window
STR_WAYPOINT_CAPTION :{WHITE}Waypoint
@@ -2341,6 +2371,8 @@ STR_WAYPOINT_GRAPHICS_TOOLTIP :{BLACK}Select w
# Rail station construction window
STR_STATION_BUILD_RAIL_CAPTION :{WHITE}Rail Station Selection
STR_STATION_BUILD_ORIENTATION :{BLACK}Orientation
+STR_STATION_BUILD_ORIENTATION_AUTO :{BLACK}Auto
+STR_STATION_BUILD_ORIENTATION_AUTO_TOOLTIP :{BLACK}Automatically select station orientation based on environment
STR_STATION_BUILD_RAILROAD_ORIENTATION_TOOLTIP :{BLACK}Select railway station orientation
STR_STATION_BUILD_NUMBER_OF_TRACKS :{BLACK}Number of tracks
STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP :{BLACK}Select number of platforms for railway station
@@ -2396,6 +2428,7 @@ STR_ROAD_TOOLBAR_TRAM_CONSTRUCTION_CAPTION :{WHITE}Tramway
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_SECTION :{BLACK}Build road section. Ctrl toggles build/remove for road construction. Shift toggles building/showing cost estimate
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_SECTION :{BLACK}Build tramway section. Ctrl toggles build/remove for tramway construction. Shift toggles building/showing cost estimate
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOROAD :{BLACK}Build road section using the Autoroad mode. Ctrl toggles build/remove for road construction. Shift toggles building/showing cost estimate
+STR_ROAD_TOOLBAR_TOOLTIP_BUILD_FULLROAD :{BLACK}Build road section using the Autoroad mode with only full tile roads. Ctrl toggles build/remove for road construction. Shift toggles building/showing cost estimate
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOTRAM :{BLACK}Build tramway section using the Autotram mode. Ctrl toggles build/remove for tramway construction. Shift toggles building/showing cost estimate
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Build road vehicle depot (for buying and servicing vehicles). Shift toggles building/showing cost estimate
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAM_VEHICLE_DEPOT :{BLACK}Build tram vehicle depot (for buying and servicing vehicles). Shift toggles building/showing cost estimate
@@ -2416,6 +2449,7 @@ STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Road Dep
STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}Select road vehicle depot orientation
STR_BUILD_DEPOT_TRAM_ORIENTATION_CAPTION :{WHITE}Tram Depot Orientation
STR_BUILD_DEPOT_TRAM_ORIENTATION_SELECT_TOOLTIP :{BLACK}Select tram vehicle depot orientation
+STR_BUILD_DEPOT_ROAD_ORIENTATION_AUTO_TOOLTIP :{BLACK}Automatically select road depot orientation based on environment
# Road vehicle station construction window
STR_STATION_BUILD_BUS_ORIENTATION :{WHITE}Bus Station Orientation
@@ -4879,10 +4913,18 @@ STR_SAVEGAME_NAME_DEFAULT :{COMPANY}, {STR
STR_SAVEGAME_NAME_SPECTATOR :Spectator, {1:STRING1}
# Viewport strings
+STR_VIEWPORT_TOWN_POP_VERY_POOR_RATING :{WHITE}{TOWN} {RED}({COMMA})
+STR_VIEWPORT_TOWN_POP_MEDIOCRE_RATING :{WHITE}{TOWN} {ORANGE}({COMMA})
+STR_VIEWPORT_TOWN_POP_GOOD_RATING :{WHITE}{TOWN} {YELLOW}({COMMA})
STR_VIEWPORT_TOWN_POP :{WHITE}{TOWN} ({COMMA})
+STR_VIEWPORT_TOWN_POP_EXCELLENT_RATING :{WHITE}{TOWN} {GREEN}({COMMA})
STR_VIEWPORT_TOWN :{WHITE}{TOWN}
STR_VIEWPORT_TOWN_TINY_BLACK :{TINY_FONT}{BLACK}{TOWN}
+STR_VIEWPORT_TOWN_TINY_VERY_POOR_RATING :{TINY_FONT}{RED}{TOWN}
+STR_VIEWPORT_TOWN_TINY_MEDIOCRE_RATING :{TINY_FONT}{ORANGE}{TOWN}
+STR_VIEWPORT_TOWN_TINY_GOOD_RATING :{TINY_FONT}{YELLOW}{TOWN}
STR_VIEWPORT_TOWN_TINY_WHITE :{TINY_FONT}{WHITE}{TOWN}
+STR_VIEWPORT_TOWN_TINY_EXCELLENT_RATING :{TINY_FONT}{GREEN}{TOWN}
STR_VIEWPORT_SIGN_SMALL_BLACK :{TINY_FONT}{BLACK}{SIGN}
STR_VIEWPORT_SIGN_SMALL_WHITE :{TINY_FONT}{WHITE}{SIGN}
@@ -4968,3 +5010,247 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+### PATCH
+STR_TOWN_DIRECTORY_CAPTION_EXTRA :{WHITE}Towns ({YELLOW}{COMMA}{WHITE} / {ORANGE}{COMMA}{WHITE})
+STR_LOCAL_AUTHORITY_COMPANY_RATING_NUM :{YELLOW}{COMPANY} {COMPANY_NUM}: {ORANGE}{STRING} {BLACK}({COMMA})
+STR_TOWN_VIEW_GROWTH :{BLACK}GR: {ORANGE}{COMMA} {BLACK}Next: {ORANGE}{COMMA} {BLACK}RH: {ORANGE}{COMMA} {BLACK}Flag {ORANGE}{NUM} {BLACK}FB: {ORANGE}{NUM} {BLACK}month{P "" s}
+STR_TOWN_VIEW_GROWTH_TILES :{BLACK}HS: {ORANGE}{COMMA}(+{COMMA}) {BLACK}CS: {ORANGE}{COMMA}(+{COMMA}) {BLACK}HR: {ORANGE}{COMMA}(+{COMMA})
+STR_TOWN_VIEW_REALPOP_RATE :{BLACK}Real Population: {YELLOW}{COMMA} {BLACK}Rating: {YELLOW}{COMMA}
+STR_TOWN_VIEW_HOUSE_STATE :{BLACK}Houses: UC {ORANGE}{COMMA} {BLACK}UR: {ORANGE}{COMMA} {BLACK}DTM: {ORANGE}{COMMA}
+STR_CB_DISTANCE_CHECK :CB town acceptance: {STRING2}
+
+###ADMIN
+STR_WATCH_WINDOW_TITLE :{WHITE}Watching {RAW_STRING}.
+STR_WATCH_CLICK_TO_WATCH_COMPANY :{BLACK}Click here to watch company building
+STR_WATCH_CLICK_NEW_WINDOW :{BLACK}Click here to open new watching window
+
+STR_WATCH_WINDOW_TITLE_CLIENT :{WHITE}{RAW_STRING} in {RAW_STRING}({NUM}).
+STR_XI_KICK :{BLACK}Kick
+STR_XI_KICKC :{BLACK}Kick from cp
+STR_XI_BAN :{BLACK}Ban
+STR_XI_BAN1 :{BLACK}Ban (1 day)
+STR_XI_LOCK :{BLACK}Lock
+STR_XI_UNLOCK :{BLACK}UNLock
+STR_XI_JOIN :{BLACK}Join company
+STR_XI_RESET :{BLACK}Reset company
+STR_XI_RESET2 :{BLACK}Reset
+STR_XI_WATCH :Watch
+STR_XI_SUSPEND :{BLACK}Suspend
+STR_XI_SUSPEND2 :{BLACK}Suspend
+STR_XI_RESUME :{BLACK}Resume
+STR_XI_RESUME2 :{BLACK}Resume
+STR_XI_ENABLE :{BLACK}En/Dis
+STR_XI_SIGN_TOOLTIP :{BLACK}Put a sign to attract player
+STR_XI_PLAYERS_TOOLTIP :{BLACK}Show clients
+STR_XI_COMPANYW_TOOLTIP :{BLACK}Open Company window
+STR_XI_COMPANYHQ :{BLACK}HQ
+STR_XI_COMPANYHQ_TOOLTIP :{BLACK}Go to company's HQ
+STR_XI_PRIVATE_PLAYER_MESSAGE :{BLACK}.{GREEN}P{BLACK}.
+STR_XI_PRIVATE_PLAYER_MESSAGE_TOOLTIP :{BLACK}Send a Custom private message to this player
+STR_XI_PRIVATE_COMPANY_MESSAGE :{BLACK}.{GREEN}C{BLACK}.
+STR_XI_PRIVATE_COMPANY_MESSAGE_TOOLTIP :{BLACK}Send a Custom private message to this company
+
+STR_XI_BAN_QUERY :{WHITE}
+STR_XI_BAN_DAYSDEFAULT :1
+STR_XI_REALY_RESET :{WHITE}Are you sure?.
+STR_XI_RESET_CAPTION :{WHITE}Reset
+
+STR_NETWORK_CLIENT_EXTRA :{WHITE} (#{NUM} in c#{NUM})
+
+######## Zoning toolbar
+
+STR_ZONING_TOOLBAR :{WHITE}Zoning toolbar
+STR_ZONING_OUTER :{BLACK}Outer tile borders:
+STR_ZONING_INNER :{BLACK}Inner tile borders:
+STR_ZONING_OUTER_INFO :{BLACK}Select which type of zoning you want on the outer border of a tile.
+STR_ZONING_INNER_INFO :{BLACK}Select which type of zoning you want on the inner border of a tile.
+
+STR_ZONING_NO_ZONING :{BLACK}Nothing
+STR_ZONING_AUTHORITY :{BLACK}Authority
+STR_ZONING_CAN_BUILD :{BLACK}Where I can't build
+STR_ZONING_STA_CATCH :{BLACK}Station catchment
+STR_ZONING_IND_CATCH :{BLACK}Industry catchment
+STR_ZONING_BUL_CATCH :{BLACK}City catchment
+STR_ZONING_BUL_UNSER :{BLACK}Unserved buildings
+STR_ZONING_IND_UNSER :{BLACK}Unserved industries
+STR_ZONING_TOWN_ZONES :{BLACK}Town zones
+STR_ZONING_CB_TOWN_BORDERS :{BLACK}CB town borders
+STR_ZONING_CB_BORDERS :{BLACK}CB borders
+STR_ZONING_ADVERTISEMENT_ZONES :{BLACK}Advertisement
+STR_ZONING_TOWN_GROWTH_TILES :{BLACK}Town growth tiles
+
+# Commands toolbar
+STR_TOOLBAR_COMMANDS_CAPTION :{WHITE}Commands
+STR_TOOLBAR_COMMANDS_GOAL_CAPTION :{BLACK}Goal
+STR_TOOLBAR_COMMANDS_GOAL_TOOLTIP :{BLACK}Send !goal command to server.
+STR_TOOLBAR_COMMANDS_QUEST_CAPTION :{BLACK}Quest list
+STR_TOOLBAR_COMMANDS_QUEST_TOOLTIP :{BLACK}Send !quest command to server.
+STR_TOOLBAR_COMMANDS_SCORE_CAPTION :{BLACK}Score
+STR_TOOLBAR_COMMANDS_SCORE_TOOLTIP :{BLACK}Send !score command to server.
+STR_TOOLBAR_COMMANDS_TOWN_CAPTION :{BLACK}Town
+STR_TOOLBAR_COMMANDS_TOWN_TOOLTIP :{BLACK}Send !town command to server.
+STR_TOOLBAR_COMMANDS_TOWN_ID_CAPTION :{BLACK}Town ID
+STR_TOOLBAR_COMMANDS_TOWN_ID_TOOLTIP :{BLACK}Send !town c-id command to server.
+STR_TOOLBAR_COMMANDS_HINT_CAPTION :{BLACK}CB Hint
+STR_TOOLBAR_COMMANDS_HINT_TOOLTIP :{BLACK}Send !hint command to server(Shows town demand in CB mode).
+STR_TOOLBAR_COMMANDS_LOGIN_CAPTION :{BLACK}Login
+STR_TOOLBAR_COMMANDS_LOGIN_TOOLTIP :{BLACK}Send !login command to server.
+STR_TOOLBAR_COMMANDS_TIMELEFT_CAPTION :{BLACK}Timeleft
+STR_TOOLBAR_COMMANDS_TIMELEFT_TOOLTIP :{BLACK}Send !timeleft command to server.
+STR_TOOLBAR_COMMANDS_NS_CAPTION :{BLACK}NS{NUM}
+STR_TOOLBAR_COMMANDS_NS_TOOLTIP :{BLACK}Join NS{NUM}
+STR_TOOLBAR_COMMANDS_RESETME_CAPTION :{BLACK}ResetMe
+STR_TOOLBAR_COMMANDS_RESETME_TOOLTIP :{BLACK}Send !resetme command to server.
+STR_TOOLBAR_COMMANDS_SAVEME_CAPTION :{BLACK}SaveMe
+STR_TOOLBAR_COMMANDS_SAVEME_TOOLTIP :{BLACK}Send !saveme command to server.
+STR_TOOLBAR_COMMANDS_NAME_CAPTION :{BLACK}New name
+STR_TOOLBAR_COMMANDS_NAME_TOOLTIP :{BLACK}Send !name command to server.
+STR_TOOLBAR_COMMANDS_INFO_CAPTION :{BLACK}Info
+STR_TOOLBAR_COMMANDS_INFO_TOOLTIP :{BLACK}Send !info command to server.
+
+STR_TOOLBAR_COMMANDS_OPTION_CARGO_CAPTION :{BLACK}Both
+STR_TOOLBAR_COMMANDS_OPTION_CARGO_TOOLTIP :{BLACK}Switch cargo buttons to both amount and income
+STR_TOOLBAR_COMMANDS_OPTION_CARGO_I_CAPTION :{BLACK}Income
+STR_TOOLBAR_COMMANDS_OPTION_CARGO_A_CAPTION :{BLACK}Amount
+STR_TOOLBAR_COMMANDS_OPTION_CARGO_A_TOOLTIP :{BLACK}Switch cargo buttons to amount
+STR_TOOLBAR_COMMANDS_OPTION_CARGO_I_TOOLTIP :{BLACK}Switch cargo buttons to income
+
+
+STR_TOOLBAR_COMMANDS_TOWN_QUERY :{WHITE}Company ID:
+STR_TOOLBAR_COMMANDS_LOGIN_NAME_QUERY :{WHITE}
+STR_TOOLBAR_COMMANDS_LOGIN_PASSWORD_QUERY :{WHITE}Password:
+STR_TOOLBAR_COMMANDS_NAME_NEWNAME_QUERY :{WHITE}New name:
+
+STR_TOOLBAR_COMMANDS_TOPICS_CAPTION :{BLACK}Topics
+STR_TOOLBAR_COMMANDS_TOPICS_TOOLTIP :{BLACK}Display help topics
+STR_TOOLBAR_COMMANDS_TOPIC1_CAPTION :{BLACK}HELP Login
+STR_TOOLBAR_COMMANDS_TOPIC1_TOOLTIP :{BLACK}How to use login
+STR_TOOLBAR_COMMANDS_TOPIC2_CAPTION :{BLACK}HELP Coal Accept
+STR_TOOLBAR_COMMANDS_TOPIC2_TOOLTIP :{BLACK}What to do when town does not accept Coal
+STR_TOOLBAR_COMMANDS_TOPIC3_CAPTION :{BLACK}HELP Food accept
+STR_TOOLBAR_COMMANDS_TOPIC3_TOOLTIP :{BLACK}What to do when town does not accept Food
+STR_TOOLBAR_COMMANDS_TOPIC4_CAPTION :{BLACK}HELP energy
+STR_TOOLBAR_COMMANDS_TOPIC4_TOOLTIP :{BLACK}What are tourists, business mail or energy?
+STR_TOOLBAR_COMMANDS_TOPIC5_CAPTION :{BLACK}HELP admin
+STR_TOOLBAR_COMMANDS_TOPIC5_TOOLTIP :{BLACK}How to use admin command?
+STR_TOOLBAR_COMMANDS_TOPIC6_CAPTION :{BLACK}HELP New Comp.
+STR_TOOLBAR_COMMANDS_TOPIC6_TOOLTIP :{BLACK}Why new company can not be starter?
+
+STR_TOOLBAR_COMMANDS_HELP_CAPTION :{BLACK}Help
+STR_TOOLBAR_COMMANDS_HELP_TOOLTIP :{BLACK}Display Help
+STR_TOOLBAR_COMMANDS_RULES_CAPTION :{BLACK}RULES
+STR_TOOLBAR_COMMANDS_RULES_TOOLTIP :{BLACK}Show Rules
+STR_TOOLBAR_COMMANDS_CBHINT_CAPTION :{BLACK}CB Hint
+STR_TOOLBAR_COMMANDS_CBHINT_TOOLTIP :{BLACK}Display help for City builder
+STR_TOOLBAR_COMMANDS_BEST_CAPTION :{BLACK}Best
+STR_TOOLBAR_COMMANDS_BEST_TOOLTIP :{BLACK}Show 5 best games
+STR_TOOLBAR_COMMANDS_RANK_CAPTION :{BLACK}Rank
+STR_TOOLBAR_COMMANDS_RANK_TOOLTIP :{BLACK}Show top 10 players
+STR_TOOLBAR_COMMANDS_ME_CAPTION :{BLACK}My Rank
+STR_TOOLBAR_COMMANDS_ME_TOOLTIP :{BLACK}Show your ranking position
+
+#login window
+STR_LOGINWINDOW_CAPTION :{WHITE}Login Window
+STR_LOGINWINDOW_NOVAPOLIS :{BLACK}Novapolis
+STR_LOGINWINDOW_NICE :{BLACK}N-ice
+STR_LOGINWINDOW_BTPRO :{BLACK}BTPro
+STR_LOGINERROR_NOCONNECT :{WHITE}Failed to connect
+STR_LOGINERROR_BADINPUT :{WHITE}Bad username or password
+STR_LOGIN_USERNAME :{WHITE}Username
+STR_LOGIN_PASSWORD :{WHITE}Password
+STR_LOGIN_SET :{WHITE}Set
+STR_LOGIN_NOTSET :{WHITE}Not Set
+STR_LOGIN_CHANGE_USERNAME :{WHITE}Change username
+STR_LOGIN_CHANGE_PASSWORD :{WHITE}Change password
+STR_LOGIN_SEND_LOGIN_TT :{WHITE}Send Login - you must but on the correct community server
+STR_LOGIN_USERNAME_DISPLAY :{WHITE}{RAW_STRING}
+STR_LOGIN_PASSWORD_DISPLAY :{WHITE}{STRING}
+
+#cargo table
+STR_TOOLBAR_CARGOS_HEADER_CARGO :{BLACK}Cargo Name
+STR_TOOLBAR_CARGOS_HEADER_AMOUNT :{BLACK}Amount
+STR_TOOLBAR_CARGOS_HEADER_INCOME :{BLACK}Income
+STR_TOOLBAR_CARGOS_HEADER_TOTAL :{BLACK}Total
+STR_TOOLBAR_CARGOS_HEADER_TOTAL_MONTH :{BLACK}Total this Month
+
+STR_TOOLBAR_CARGOS_UNITS :{BLACK}{COMMA}
+STR_TOOLBAR_CARGOS_UNITS_TOTAL :{BLACK}{COMMA}
+STR_TOOLBAR_CARGOS_CAPTION :{WHITE}{COMPANY} Cargo Transported {BLACK}{COMPANY_NUM}
+STR_TOOLBAR_CARGOS_NAME :{BLACK}{STRING}
+
+#towns
+STR_TOWN_DIRECTORY_TOWN_COLOUR :{ORANGE}{TOWN}{BLACK} ({COMMA})
+STR_TOWN_DIRECTORY_CITY_COLOUR :{YELLOW}{TOWN}{BLACK} ({COMMA})
+STR_OLD_DEPOT_TRAINT_LENGTH :Old depot length format: {STRING2}
+STR_SMALLMAP_TOWN_LARGE :{TINY_FONT}{YELLOW}{TOWN}
+
+STR_ORDER_DIST :{NUM}, {NUM}
+
+#server list
+STR_NETWORK_SELECT_NOVA :{BLACK}Novapolis
+STR_NETWORK_SELECT_NICE :{BLACK}N-ice
+STR_NETWORK_SELECT_BTPRO :{BLACK}BTPro
+STR_NETWORK_SELECT_REDDIT :{BLACK}reddit
+STR_NETWORK_SELECT_SERVER_TOOLTIP :{BLACK}Filter this one
+
+### Town CB gui
+STR_BUTTON_CB :{STRING}
+STR_BUTTON_CB_YES :{BLACK}CB
+STR_TOWN_VIEW_CB_CAPTION :{WHITE}{TOWN}
+
+STR_CB_LARGE_ADVERTISING_CAMPAIGN :{BLACK}Large Advertising
+STR_CB_NEW_BUILDINGS :{BLACK}Fund Buildings
+STR_CB_FUND_REGULAR :{BLACK}Fund Regularly
+STR_CB_FUND_REGULAR_TT :{BLACK}Every time fund buildings is zero and company has enough money, buildings will be funded automatically
+STR_CB_FUNDED_REGULARLY :{GREEN}Town is funded regularly
+
+STR_TOWN_CB_FUNDING :{ORANGE}Funded for {YELLOW}{COMMA}{ORANGE} month{P "" s}
+STR_TOWN_CB_GROWING :{GREEN}Town is growing!
+STR_TOWN_CB_NOT_GROWING :{WHITE}Town is not growing
+STR_TOWN_CB_GROWING_DETAIL :{ORANGE}1 house in {YELLOW}{COMMA} {ORANGE}days ({YELLOW}{COMMA}%{ORANGE}). Next House in {YELLOW}{COMMA} {ORANGE}days
+
+STR_TOWN_GROWTH_HEADER_CARGO :{BLACK}Cargo
+STR_TOWN_GROWTH_HEADER_AMOUNT :{BLACK}Delivered
+STR_TOWN_GROWTH_HEADER_REQ :{BLACK}Required
+STR_TOWN_GROWTH_HEADER_LAST :{BLACK}Last Month
+STR_TOWN_GROWTH_HEADER_STORE :{BLACK}Stored
+STR_TOWN_GROWTH_HEADER_STORE_PCT :{BLACK}Use%
+STR_TOWN_GROWTH_HEADER_FROM :{BLACK}From
+
+STR_TOWN_CB_CARGO_NAME :{BLACK}{STRING}:
+
+STR_TOWN_CB_CARGO_AMOUNT_GOOD :{GREEN}{COMMA}
+STR_TOWN_CB_CARGO_AMOUNT_BAD :{YELLOW}{COMMA}
+STR_TOWN_CB_CARGO_AMOUNT_NOT :{SILVER}{COMMA}
+
+STR_TOWN_CB_CARGO_REQ_YES :{ORANGE}{COMMA}
+STR_TOWN_CB_CARGO_REQ_NOT :{SILVER}{COMMA}
+
+STR_TOWN_CB_CARGO_STORE_YES :{LTBLUE}{COMMA}
+STR_TOWN_CB_CARGO_STORE_NOT :{SILVER}{COMMA}
+STR_TOWN_CB_CARGO_STORE_DECAY :{BLACK}-
+
+STR_TOWN_CB_CARGO_STORE_PCT_YES :{LTBLUE}{COMMA}%
+STR_TOWN_CB_CARGO_STORE_PCT_NOT :{SILVER}{COMMA}%
+
+STR_TOWN_CB_CARGO_PREVIOUS_YES :{GREEN}{COMMA}
+STR_TOWN_CB_CARGO_PREVIOUS_EDGE :{YELLOW}{COMMA}
+STR_TOWN_CB_CARGO_PREVIOUS_BAD :{RED}{COMMA}
+STR_TOWN_CB_CARGO_PREVIOUS_NOT :{SILVER}{COMMA}
+
+STR_TOWN_CB_CARGO_FROM_YES :{YELLOW}{COMMA}
+STR_TOWN_CB_CARGO_FROM_NOT :{SILVER}{COMMA}
+
+#polyrail double click option
+STR_CONFIG_SETTING_POLYRAIL_DOUBLECLICK_TOOLTIPS :Enable finishing polyrail with mouse double click{STRING2}
+
+#tooltips extra
+STR_CONFIG_SETTING_ENABLE_EXTRA_TOOLTIPS :Enable extra tooltips{STRING2}
+STR_TTE_HOUSE_NAME :{LTBLUE}{STRING}
+STR_TTE_HOUSE :{BLACK}Population: {NUM}
+STR_TTE_INDUSTRY_NAME :{LTBLUE}{INDUSTRY}
+STR_TTE_INDUSTRY :{WHITE}{STRING} {BLACK}{CARGO_SHORT} {YELLOW}{NUM} %
+STR_TTE_STATION_NAME :{LTBLUE}{STATION}
+STR_TTE_STATION :{WHITE}{STRING} {BLACK}{CARGO_SHORT} {YELLOW}{NUM} %
+STR_LAND_AREA_INFORMATION_POP :{BLACK}Population: {LTBLUE}{NUM}
diff --git a/src/main_gui.cpp b/src/main_gui.cpp
index fe26335e94..ce8acfc338 100644
--- a/src/main_gui.cpp
+++ b/src/main_gui.cpp
@@ -107,7 +107,7 @@ bool HandlePlacePushButton(Window *w, int widget, CursorID cursor, HighLightStyl
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP);
w->SetDirty();
- if (w->IsWidgetLowered(widget)) {
+ if (w->IsWidgetLowered(widget) && mode == _thd.place_mode) {
ResetObjectToPlace();
return false;
}
@@ -227,6 +227,7 @@ enum {
GHK_TOGGLE_INVISIBILITY = GHK_TOGGLE_TRANSPARENCY + 9,
GHK_TRANSPARENCY_TOOLBAR = GHK_TOGGLE_INVISIBILITY + 8,
GHK_TRANSPARANCY,
+ GHK_BORROW_ALL,
GHK_CHAT,
GHK_CHAT_ALL,
GHK_CHAT_COMPANY,
@@ -393,6 +394,10 @@ struct MainWindow : Window
ResetRestoreAllTransparency();
break;
+ case GHK_BORROW_ALL:
+ DoCommandP(0, 0, 1, CMD_INCREASE_LOAN | CMD_MSG(STR_ERROR_CAN_T_BORROW_ANY_MORE_MONEY));
+ break;
+
#ifdef ENABLE_NETWORK
case GHK_CHAT: // smart chat; send to team if any, otherwise to all
if (_networking) {
@@ -465,6 +470,11 @@ struct MainWindow : Window
InvalidateWindowData(WC_MAIN_TOOLBAR, 0, data, true);
}
+ virtual void OnMouseOver(Point pt, int widget)
+ {
+ if (_game_mode != GM_MENU && _settings_client.gui.enable_extra_tooltips && pt.x != -1) GuiPrepareTooltipsExtra(this);
+ }
+
static HotkeyList hotkeys;
};
@@ -511,6 +521,7 @@ static Hotkey global_hotkeys[] = {
Hotkey('8' | WKC_CTRL | WKC_SHIFT, "invisibility_catenary", GHK_TOGGLE_INVISIBILITY + 7),
Hotkey('X' | WKC_CTRL, "transparency_toolbar", GHK_TRANSPARENCY_TOOLBAR),
Hotkey('X', "toggle_transparency", GHK_TRANSPARANCY),
+ Hotkey(WKC_NONE, "borrow_all", GHK_BORROW_ALL),
#ifdef ENABLE_NETWORK
Hotkey(_ghk_chat_keys, "chat", GHK_CHAT),
Hotkey(_ghk_chat_all_keys, "chat_all", GHK_CHAT_ALL),
diff --git a/src/misc.cpp b/src/misc.cpp
index f32cd7ad5e..871bf581c4 100644
--- a/src/misc.cpp
+++ b/src/misc.cpp
@@ -110,6 +110,7 @@ void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settin
InitializeEconomy();
ResetObjectToPlace();
+ ClearRailPlacementEndpoints();
GamelogReset();
GamelogStartAction(GLAT_START);
diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp
index 1d596ae3fe..e40d6a22f3 100644
--- a/src/misc_gui.cpp
+++ b/src/misc_gui.cpp
@@ -33,6 +33,14 @@
#include "safeguards.h"
+#include "house.h"
+#include "town_map.h"
+#include "station_base.h"
+#include "viewport_func.h"
+#include "industry.h"
+
+void GuiShowTooltipsExtra(Window *parent, uint param, TooltipCloseCondition close_tooltip);
+
/** Method to open the OSK. */
enum OskActivation {
OSKA_DISABLED, ///< The OSK shall not be activated at all.
@@ -164,6 +172,7 @@ public:
td.airport_tile_name = STR_NULL;
td.rail_speed = 0;
td.road_speed = 0;
+ td.population = 0;
td.grf = NULL;
@@ -293,6 +302,13 @@ public:
line_nr++;
}
+ /* House pop */
+ if (td.population != 0) {
+ SetDParam(0, td.population);
+ GetString(this->landinfo_data[line_nr], STR_LAND_AREA_INFORMATION_POP, lastof(this->landinfo_data[line_nr]));
+ line_nr++;
+ }
+
assert(line_nr < LAND_INFO_CENTERED_LINES);
/* Mark last line empty */
@@ -1208,3 +1224,229 @@ void ShowQuery(StringID caption, StringID message, Window *parent, QueryCallback
new QueryWindow(&_query_desc, caption, message, parent, callback);
}
+
+/** Window for displaying a tooltip. */
+void GuiPrepareTooltipsExtra(Window *parent){
+ const Point p = GetTileBelowCursor();
+ const TileIndex tile = TileVirtXY(p.x, p.y);
+
+ if (tile >= MapSize()) return;
+ uint param = 0;
+ switch (GetTileType(tile)) {
+ /*case MP_HOUSE: {
+ const HouseID house = GetHouseType(tile);
+ param = ((house & 0xFFFF) << 16) | MP_HOUSE;
+ break;
+ }*/
+ case MP_INDUSTRY: {
+ const Industry *ind = Industry::GetByTile(tile);
+ if(ind->produced_cargo[0] == CT_INVALID && ind->produced_cargo[1] == CT_INVALID) return;
+ param = ((ind->index & 0xFFFF) << 16) | MP_INDUSTRY;
+ break;
+ }
+ case MP_STATION: {
+ if (IsRailWaypoint(tile) || HasTileWaterGround(tile)) break;
+ const Station *st = Station::GetByTile(tile);
+ param |= ((st->index & 0xFFFF) << 16) | MP_STATION;
+ break;
+ }
+ default:
+ return;
+ }
+ if(param != 0) GuiShowTooltipsExtra(parent, param, TCC_HOVER);
+}
+
+static const NWidgetPart _nested_tooltips_extra_widgets[] = {
+ NWidget(WWT_PANEL, COLOUR_GREY, WID_TT_BACKGROUND), SetMinimalSize(64, 32), EndContainer(),
+};
+
+static WindowDesc _tool_tips_extra_desc(
+ WDP_MANUAL, NULL, 0, 0,
+ WC_TOOLTIPS_EXTRA, WC_NONE,
+ 0,
+ _nested_tooltips_extra_widgets, lengthof(_nested_tooltips_extra_widgets)
+);
+
+struct TooltipsExtraWindow : public Window
+{
+ TileType tiletype;
+ uint16 objIndex;
+ TooltipCloseCondition close_cond;
+
+ TooltipsExtraWindow(Window *parent, uint param, TooltipCloseCondition close_tooltip) : Window(&_tool_tips_extra_desc)
+ {
+ this->parent = parent;
+ this->tiletype = (TileType)(param & 0xFFFF);
+ this->objIndex = (uint16)((param >> 16) & 0xFFFF);
+ this->close_cond = close_tooltip;
+ this->InitNested();
+ CLRBITS(this->flags, WF_WHITE_BORDER);
+ }
+
+ virtual Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number)
+ {
+ int scr_top = GetMainViewTop() + 2;
+ int scr_bot = GetMainViewBottom() - 2;
+ Point pt;
+ pt.y = Clamp(_cursor.pos.y + _cursor.size.y + _cursor.offs.y + 5, scr_top, scr_bot);
+ if (pt.y + sm_height > scr_bot) pt.y = min(_cursor.pos.y + _cursor.offs.y - 5, scr_bot) - sm_height;
+ pt.x = sm_width >= _screen.width ? 0 : Clamp(_cursor.pos.x - (sm_width >> 1), 0, _screen.width - sm_width);
+ return pt;
+ }
+
+ virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
+ {
+ static const uint LINE_HEIGHT = FONT_HEIGHT_NORMAL + 2;
+ size->width = 200;
+ size->height = LINE_HEIGHT + 4;
+ switch(this->tiletype) {
+ /*case MP_HOUSE: {
+ size->height += LINE_HEIGHT;
+ SetDParam(0, 1000);
+ size->width = GetStringBoundingBox(STR_TTE_HOUSE).width;
+ break;
+ }*/
+ case MP_INDUSTRY: {
+ const Industry *ind = Industry::GetIfValid((IndustryID)this->objIndex);
+ if(ind == NULL) break;
+
+ for (CargoID i = 0; i < lengthof(ind->produced_cargo); i++) {
+ if (ind->produced_cargo[i] == CT_INVALID) continue;
+ const CargoSpec *cs = CargoSpec::Get(ind->produced_cargo[i]);
+ if(cs == NULL) continue;
+ size->height += LINE_HEIGHT;
+ SetDParam(0, cs->name);
+ SetDParam(1, cs->Index());
+ SetDParam(2, ind->last_month_production[i]);
+ SetDParam(3, ToPercent8(ind->last_month_pct_transported[i]));
+ size->width = max(GetStringBoundingBox(STR_TTE_INDUSTRY).width + 50, size->width);
+ }
+ break;
+ }
+ case MP_STATION: {
+ const Station *st = Station::GetIfValid((StationID)this->objIndex);
+ if(st == NULL) break;
+
+ for (int i = 0; i < _sorted_standard_cargo_specs_size; i++) {
+ const CargoSpec *cs = _sorted_cargo_specs[i];
+ if(cs == NULL) continue;
+ int cargoid = cs->Index();
+ if (HasBit(st->goods[cargoid].status, GoodsEntry::GES_RATING)) {
+ size->height += LINE_HEIGHT;
+ SetDParam(0, cs->name);
+ SetDParam(1, cargoid);
+ SetDParam(2, st->goods[cargoid].cargo.TotalCount());
+ SetDParam(3, ToPercent8(st->goods[cargoid].rating));
+ size->width = max(GetStringBoundingBox(STR_TTE_STATION).width + 50, size->width);
+ }
+ }
+ break;
+ }
+ }
+ size->width += 2 + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
+ size->height += 2 + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
+ }
+
+ virtual void DrawWidget(const Rect &r, int widget) const
+ {
+ static const uint LINE_HEIGHT = FONT_HEIGHT_NORMAL + 2;
+ GfxDrawLine(r.left, r.top, r.right, r.top, PC_BLACK);
+ GfxDrawLine(r.left, r.bottom, r.right, r.bottom, PC_BLACK);
+ GfxDrawLine(r.left, r.top, r.left, r.bottom, PC_BLACK);
+ GfxDrawLine(r.right, r.top, r.right, r.bottom, PC_BLACK);
+
+ int y = r.top + WD_FRAMERECT_TOP + 4;
+ int left = r.left + WD_FRAMERECT_LEFT + 4;
+
+ switch(this->tiletype) {
+ /*case MP_HOUSE: {
+ const HouseID house = (HouseID)this->objIndex;
+ const HouseSpec *hs = HouseSpec::Get(house);
+ if(hs == NULL) break;
+
+ SetDParam(0, hs->building_name);
+ DrawString(left, r.right - WD_FRAMERECT_RIGHT, y, STR_TTE_HOUSE_NAME, TC_BLACK, SA_CENTER);
+ y += LINE_HEIGHT;
+ SetDParam(0, hs->population);
+ DrawString(left, r.right - WD_FRAMERECT_RIGHT, y, STR_TTE_HOUSE);
+ break;
+ }*/
+ case MP_INDUSTRY: {
+ const Industry *ind = Industry::GetIfValid((IndustryID)this->objIndex);
+ if(ind == NULL) break;
+
+ SetDParam(0, ind->index);
+ DrawString(left, r.right - WD_FRAMERECT_RIGHT, y, STR_TTE_INDUSTRY_NAME, TC_BLACK, SA_CENTER);
+ y += LINE_HEIGHT;
+
+ for (CargoID i = 0; i < lengthof(ind->produced_cargo); i++) {
+ if (ind->produced_cargo[i] == CT_INVALID) continue;
+ const CargoSpec *cs = CargoSpec::Get(ind->produced_cargo[i]);
+ if(cs == NULL) continue;
+ SetDParam(0, cs->name);
+ SetDParam(1, cs->Index());
+ SetDParam(2, ind->last_month_production[i]);
+ SetDParam(3, ToPercent8(ind->last_month_pct_transported[i]));
+
+ this->DrawSpriteIcons(cs->GetCargoIcon(), left, y);
+ DrawString(left + 40, r.right - WD_FRAMERECT_RIGHT, y, STR_TTE_INDUSTRY);
+ y += LINE_HEIGHT;
+ }
+ break;
+ }
+ case MP_STATION: {
+ uint pars = 0;
+ const Station *st = Station::GetIfValid((StationID)this->objIndex);
+ if(st == NULL) break;
+
+ SetDParam(0, st->index);
+ DrawString(left, r.right - WD_FRAMERECT_RIGHT, y, STR_TTE_STATION_NAME, TC_BLACK, SA_CENTER);
+ y += LINE_HEIGHT;
+
+ for (int i = 0; i < _sorted_standard_cargo_specs_size; i++) {
+ const CargoSpec *cs = _sorted_cargo_specs[i];
+ if(cs == NULL) continue;
+ int cargoid = cs->Index();
+ if (HasBit(st->goods[cargoid].status, GoodsEntry::GES_RATING)) {
+ SetDParam(0, cs->name);
+ SetDParam(1, cargoid);
+ SetDParam(2, st->goods[cargoid].cargo.TotalCount());
+ SetDParam(3, ToPercent8(st->goods[cargoid].rating));
+
+ this->DrawSpriteIcons(cs->GetCargoIcon(), left, y);
+ DrawString(left + 40, r.right - WD_FRAMERECT_RIGHT, y, STR_TTE_STATION);
+ y += LINE_HEIGHT;
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ virtual void OnMouseLoop()
+ {
+ if (!_cursor.in_window) {
+ delete this;
+ return;
+ }
+
+ switch (this->close_cond) {
+ case TCC_RIGHT_CLICK: if (!_right_button_down) delete this; break;
+ case TCC_LEFT_CLICK: if (!_left_button_down) delete this; break;
+ case TCC_HOVER: if (!_mouse_hovering) delete this; break;
+ }
+ }
+
+ void DrawSpriteIcons(SpriteID sprite, int left, int top) const
+ {
+ for(int i = 0; i < 30; i += 10) {
+ DrawSprite(sprite, PAL_NONE, left + i, top);
+ }
+ }
+};
+
+void GuiShowTooltipsExtra(Window *parent, uint param, TooltipCloseCondition close_tooltip)
+{
+ DeleteWindowById(WC_TOOLTIPS_EXTRA, 0);
+ new TooltipsExtraWindow(parent, param, close_tooltip);
+}
diff --git a/src/network/network.cpp b/src/network/network.cpp
index 7c0727e205..e21b89a7ec 100644
--- a/src/network/network.cpp
+++ b/src/network/network.cpp
@@ -83,7 +83,7 @@ bool _network_udp_server; ///< Is the UDP server started?
uint16 _network_udp_broadcast; ///< Timeout for the UDP broadcasts.
uint8 _network_advertise_retries; ///< The number of advertisement retries we did.
CompanyMask _network_company_passworded; ///< Bitmask of the password status of all companies.
-
+bool _novarole = false;
/* Check whether NETWORK_NUM_LANDSCAPES is still in sync with NUM_LANDSCAPE */
assert_compile((int)NETWORK_NUM_LANDSCAPES == (int)NUM_LANDSCAPE);
assert_compile((int)NETWORK_COMPANY_NAME_LENGTH == MAX_LENGTH_COMPANY_NAME_CHARS * MAX_CHAR_LENGTH);
@@ -117,6 +117,7 @@ NetworkClientInfo::~NetworkClientInfo()
{
/* Delete the chat window, if you were chatting with this client. */
InvalidateWindowData(WC_SEND_NETWORK_MSG, DESTTYPE_CLIENT, this->client_id);
+ InvalidateWindowData(WC_WATCH_COMPANYA, this->client_id, 2);
}
/**
diff --git a/src/network/network_client.cpp b/src/network/network_client.cpp
index c800760f3b..cb84af241e 100644
--- a/src/network/network_client.cpp
+++ b/src/network/network_client.cpp
@@ -34,10 +34,13 @@
#include "table/strings.h"
-#include "../safeguards.h"
+#include "../town.h"
+#include "network_func.h"
+#include "../safeguards.h"
/* This file handles all the client-commands */
+void SyncCBClient(byte * msg);
/** Read some packets, and when do use that data as initial load filter. */
struct PacketReader : LoadFilter {
@@ -265,6 +268,11 @@ void ClientNetworkGameSocketHandler::ClientError(NetworkRecvStatus res)
if (_network_first_time) {
_network_first_time = false;
SendAck();
+ extern bool novahost();
+ if(novahost()){
+ NetworkClientSendChatToServer("!check 1444"); //check version
+ CB_SetCB(false);
+ }
}
_sync_frame = 0;
@@ -614,6 +622,10 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CLIENT_INFO(Pac
strecpy(ci->client_name, name, lastof(ci->client_name));
SetWindowDirty(WC_CLIENT_LIST, 0);
+ InvalidateWindowClassesData(WC_WATCH_COMPANY, 0);
+ SetWindowClassesDirty(WC_WATCH_COMPANY);
+ InvalidateWindowData(WC_WATCH_COMPANYA, ci->client_id, 1);
+ SetWindowClassesDirty(WC_WATCH_COMPANYA);
return NETWORK_RECV_STATUS_OKAY;
}
@@ -633,6 +645,10 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CLIENT_INFO(Pac
strecpy(ci->client_name, name, lastof(ci->client_name));
SetWindowDirty(WC_CLIENT_LIST, 0);
+ InvalidateWindowClassesData(WC_WATCH_COMPANY, 0);
+ SetWindowClassesDirty(WC_WATCH_COMPANY);
+ InvalidateWindowData(WC_WATCH_COMPANYA, ci->client_id, 1);
+ SetWindowClassesDirty(WC_WATCH_COMPANYA);
return NETWORK_RECV_STATUS_OKAY;
}
@@ -984,7 +1000,8 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CHAT(Packet *p)
}
if (ci != NULL) {
- NetworkTextMessage(action, GetDrawStringCompanyColour(ci->client_playas), self_send, name, msg, data);
+ if (strncmp(msg, "synccbclient", 12) == 0) SyncCBClient(p->buffer);
+ else NetworkTextMessage(action, GetDrawStringCompanyColour(ci->client_playas), self_send, name, msg, data);
}
return NETWORK_RECV_STATUS_OKAY;
}
@@ -1021,6 +1038,8 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_QUIT(Packet *p)
}
SetWindowDirty(WC_CLIENT_LIST, 0);
+ InvalidateWindowClassesData( WC_WATCH_COMPANYA, 0 );
+ SetWindowClassesDirty( WC_WATCH_COMPANYA );
/* If we come here it means we could not locate the client.. strange :s */
return NETWORK_RECV_STATUS_OKAY;
@@ -1107,6 +1126,8 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_MOVE(Packet *p)
if (client_id == _network_own_client_id) {
SetLocalCompany(company_id);
}
+ InvalidateWindowClassesData( WC_WATCH_COMPANYA, 0 );
+ SetWindowClassesDirty( WC_WATCH_COMPANYA );
return NETWORK_RECV_STATUS_OKAY;
}
@@ -1253,6 +1274,10 @@ void NetworkClientSendChat(NetworkAction action, DestType type, int dest, const
MyClient::SendChat(action, type, dest, msg, data);
}
+void NetworkClientSendChatToServer(const char * msg)
+{
+ NetworkClientSendChat(NETWORK_ACTION_CHAT_CLIENT, DESTTYPE_CLIENT, CLIENT_ID_SERVER, msg);
+}
/**
* Set/Reset company password on the client side.
* @param password Password to be set.
@@ -1298,4 +1323,49 @@ bool NetworkMaxSpectatorsReached()
return NetworkSpectatorCount() >= (_network_server ? _settings_client.network.max_spectators : _network_server_max_spectators);
}
+void SyncCBClient(byte *msg){ //len = 3 + 6 + 12 + 3 + 6*cargo
+ size_t pos = 21;
+ size_t length = pos;
+ byte tmp;
+
+ while(msg[length] != '\0'){ length++; }
+
+ _novarole = msg[pos++] == 'A';
+ if(length == pos) return;
+
+ CB_SetCB(true);
+
+ tmp = msg[pos++];
+ _settings_client.gui.cb_distance_check = (tmp == 0xFF) ? 0 : tmp;
+ tmp = msg[pos++];
+ CB_SetStorage((tmp == 0xFF) ? 0 : (uint)tmp);
+
+ for(int i = 0; i < NUM_CARGO; i++){
+ CB_SetRequirements(i, 0, 0, 0);
+ }
+
+ //IConsolePrintF(CC_INFO, "cb check %i, storage %i", _settings_client.gui.cb_distance_check, tmp);
+ uint8 cargo;
+ uint req, from, decay;
+ while(pos < length){ //CargoID NUM_CARGO
+ cargo = msg[pos++];
+ if(cargo == 0xFF) cargo = 0;
+
+ tmp = msg[pos++];
+ req = (tmp == 0xFF) ? 0 : tmp;
+ tmp = msg[pos++];
+ req += (tmp == 0xFF) ? 0 : (tmp << 8);
+
+ tmp = msg[pos++];
+ from = (tmp == 0xFF) ? 0 : tmp;
+ tmp = msg[pos++];
+ from += (tmp == 0xFF) ? 0 : (tmp << 8);
+
+ tmp = msg[pos++];
+ decay = (tmp == 0xFF) ? 0 : tmp;
+
+ CB_SetRequirements(cargo, req, from, decay);
+ //IConsolePrintF(CC_INFO, "cargo#%i %i/%i/%i", cargo, req, from, decay);
+ }
+}
#endif /* ENABLE_NETWORK */
diff --git a/src/network/network_func.h b/src/network/network_func.h
index b4db6fc0c2..2069c7bf4b 100644
--- a/src/network/network_func.h
+++ b/src/network/network_func.h
@@ -39,7 +39,7 @@ extern uint8 _network_reconnect;
extern StringList _network_bind_list;
extern StringList _network_host_list;
extern StringList _network_ban_list;
-
+extern bool _novarole;
byte NetworkSpectatorCount();
void NetworkUpdateClientName();
bool NetworkCompanyHasClients(CompanyID company);
@@ -58,6 +58,7 @@ void NetworkClientConnectGame(NetworkAddress address, CompanyID join_as, const c
void NetworkClientRequestMove(CompanyID company, const char *pass = "");
void NetworkClientSendRcon(const char *password, const char *command);
void NetworkClientSendChat(NetworkAction action, DestType type, int dest, const char *msg, int64 data = 0);
+void NetworkClientSendChatToServer(const char * msg);
bool NetworkClientPreferTeamChat(const NetworkClientInfo *cio);
bool NetworkCompanyIsPassworded(CompanyID company_id);
bool NetworkMaxCompaniesReached();
diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp
index 8e90b19a26..f7b3a5d821 100644
--- a/src/network/network_gui.cpp
+++ b/src/network/network_gui.cpp
@@ -38,6 +38,7 @@
#include "../table/sprites.h"
#include "../stringfilter_type.h"
+#include "../watch_gui.h"
#include "../safeguards.h"
@@ -234,6 +235,7 @@ protected:
Scrollbar *vscroll; ///< vertical scrollbar of the list of servers
QueryString name_editbox; ///< Client name editbox.
QueryString filter_editbox; ///< Editbox for filter on servers
+ bool UDP_CC_queried;
int lock_offset; ///< Left offset for lock icon.
int blot_offset; ///< Left offset for green/yellow/red compatibility icon.
@@ -474,6 +476,7 @@ public:
this->querystrings[WID_NG_FILTER] = &this->filter_editbox;
this->filter_editbox.cancel_button = QueryString::ACTION_CLEAR;
+ this->UDP_CC_queried = false;
this->SetFocusedWidget(WID_NG_FILTER);
this->last_joined = NetworkGameListAddItem(NetworkAddress(_settings_client.network.last_host, _settings_client.network.last_port));
@@ -782,6 +785,23 @@ public:
case WID_NG_NEWGRF_MISSING: // Find missing content online
if (this->server != NULL) ShowMissingContentWindow(this->server->info.grfconfig);
break;
+ case WID_NG_NICE:
+ case WID_NG_BTPRO:
+ case WID_NG_REDDIT:
+ case WID_NG_NOVA:
+ if(!UDP_CC_queried){
+ NetworkUDPQueryMasterServer();
+ UDP_CC_queried = true;
+ }
+ if(widget == WID_NG_NICE) this->filter_editbox.text.Assign("n-ice");
+ else if(widget == WID_NG_BTPRO) this->filter_editbox.text.Assign("BTPro");
+ else if(widget == WID_NG_NOVA) this->filter_editbox.text.Assign("Novapolis");
+ else if(widget == WID_NG_REDDIT) this->filter_editbox.text.Assign("reddit");
+ this->servers.ForceRebuild();
+ this->BuildGUINetworkGameList();
+ this->ScrollToSelectedServer();
+ this->SetDirty();
+ break;
}
}
@@ -909,7 +929,7 @@ public:
}
};
-Listing NetworkGameWindow::last_sorting = {false, 5};
+Listing NetworkGameWindow::last_sorting = {false, 0};
GUIGameServerList::SortFunction * const NetworkGameWindow::sorter_funcs[] = {
&NGameNameSorter,
&NGameClientSorter,
@@ -946,6 +966,10 @@ static const NWidgetPart _nested_network_game_widgets[] = {
NWidget(WWT_DROPDOWN, COLOUR_LIGHT_BLUE, WID_NG_CONN_BTN),
SetDataTip(STR_BLACK_STRING, STR_NETWORK_SERVER_LIST_ADVERTISED_TOOLTIP),
NWidget(NWID_SPACER), SetFill(1, 0), SetResize(1, 0),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NG_REDDIT), SetFill(1, 0), SetDataTip(STR_NETWORK_SELECT_REDDIT, STR_NETWORK_SELECT_SERVER_TOOLTIP),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NG_NICE), SetFill(1, 0), SetDataTip(STR_NETWORK_SELECT_NICE, STR_NETWORK_SELECT_SERVER_TOOLTIP),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NG_BTPRO), SetFill(1, 0), SetDataTip(STR_NETWORK_SELECT_BTPRO, STR_NETWORK_SELECT_SERVER_TOOLTIP),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NG_NOVA), SetFill(1, 0), SetDataTip(STR_NETWORK_SELECT_NOVA, STR_NETWORK_SELECT_SERVER_TOOLTIP),
EndContainer(),
NWidget(NWID_HORIZONTAL), SetPIP(0, 7, 0),
NWidget(WWT_TEXT, COLOUR_LIGHT_BLUE, WID_NG_FILTER_LABEL), SetDataTip(STR_LIST_FILTER_TITLE, STR_NULL),
@@ -1691,6 +1715,14 @@ static void ClientList_Ban(const NetworkClientInfo *ci)
NetworkServerKickOrBanIP(ci->client_id, true);
}
+static void ClientList_Watch(const NetworkClientInfo *ci)
+{
+ if (ci != NULL){
+ CompanyID cid = (CompanyID)ci->client_id;
+ ShowWatchWindow(cid, 1);
+ }
+}
+
static void ClientList_GiveMoney(const NetworkClientInfo *ci)
{
ShowNetworkGiveMoneyWindow(ci->client_playas);
@@ -1767,6 +1799,9 @@ struct NetworkClientListPopupWindow : Window {
this->AddAction(STR_NETWORK_CLIENTLIST_BAN, &ClientList_Ban);
}
+ if (_network_own_client_id != ci->client_id && ci->client_id != CLIENT_ID_SERVER && _novarole) {
+ this->AddAction(STR_XI_WATCH, &ClientList_Watch);
+ }
this->InitNested(client_id);
CLRBITS(this->flags, WF_WHITE_BORDER);
}
@@ -1908,8 +1943,11 @@ struct NetworkClientListWindow : Window {
FOR_ALL_CLIENT_INFOS(ci) {
width = max(width, GetStringBoundingBox(ci->client_name).width);
}
-
- size->width = WD_FRAMERECT_LEFT + this->server_client_width + this->company_icon_width + width + WD_FRAMERECT_RIGHT;
+ SetDParam(0, 0xFFFF);
+ SetDParam(1, INVALID_COMPANY);
+ uint width2 = GetStringBoundingBox(STR_NETWORK_CLIENT_EXTRA).width;
+ size->width = WD_FRAMERECT_LEFT + this->server_client_width + this->company_icon_width + width + WD_FRAMERECT_RIGHT + width2;
+ //size->width = WD_FRAMERECT_LEFT + this->server_client_width + this->company_icon_width + width + WD_FRAMERECT_RIGHT;
}
virtual void OnPaint()
@@ -1960,6 +1998,11 @@ struct NetworkClientListWindow : Window {
DrawString(name_left, name_right, y, ci->client_name, colour);
+ uint extra = GetStringBoundingBox(ci->client_name).width + 15;
+ SetDParam(0, ci->client_id);
+ SetDParam(1, ci->client_playas == INVALID_COMPANY ? ci->client_playas : ci->client_playas + 1);
+ DrawString(name_left + extra, right, y, STR_NETWORK_CLIENT_EXTRA, TC_FROMSTRING, SA_RIGHT);
+
y += FONT_HEIGHT_NORMAL;
}
}
diff --git a/src/order_gui.cpp b/src/order_gui.cpp
index 9841708586..5b46442065 100644
--- a/src/order_gui.cpp
+++ b/src/order_gui.cpp
@@ -171,6 +171,78 @@ static const StringID _order_conditional_condition[] = {
INVALID_STRING_ID,
};
+struct OrdersFromSettings
+{
+ enum OrderUnloadFlags unload;
+ enum OrderLoadFlags load;
+};
+
+typedef enum {
+ GOFS_NONE = 0,
+ GOFS_FULL,
+ GOFS_XFER,
+ GOFS_UNLOAD,
+ GOFS_FEEDLOAD,
+ GOFS_FEEDUNLOAD,
+ GOFS_NOLOAD
+} GetOrderFromSettingsTypes;
+
+static enum {
+ GOFS_FEEDER_NULL,
+ GOFS_FEEDER_LOAD,
+ GOFS_FEEDER_UNLOAD
+} gofsfeeder_ordermod = GOFS_FEEDER_NULL;
+
+#define GOFSFEEDER_ORDERMOD_RESET gofsfeeder_ordermod = GOFS_FEEDER_NULL
+
+
+/* fetch and compute orders set from settings */
+
+static void GetOrdersFromSettings(const Vehicle *v, uint8 setting, struct OrdersFromSettings *rv)
+{
+ rv->load = (enum OrderLoadFlags)-1;
+ rv->unload = (enum OrderUnloadFlags)-1;
+
+ switch(setting) {
+
+ case GOFS_FEEDLOAD:
+ if (v->GetNumOrders()) gofsfeeder_ordermod = GOFS_FEEDER_LOAD;
+ rv->unload = OUFB_NO_UNLOAD;
+ rv->load = OLF_FULL_LOAD_ANY;
+ break;
+ case GOFS_FULL:
+ rv->load = OLF_FULL_LOAD_ANY;
+ break;
+
+ case GOFS_UNLOAD:
+ rv->unload = OUFB_UNLOAD;
+ if (_settings_client.gui.auto_noload_on_unloadall)
+ rv->load = OLFB_NO_LOAD;
+ break;
+
+ case GOFS_FEEDUNLOAD:
+ if (v->GetNumOrders()) gofsfeeder_ordermod = GOFS_FEEDER_UNLOAD;
+ rv->unload = OUFB_TRANSFER;
+ rv->load = OLFB_NO_LOAD;
+ break;
+
+ case GOFS_XFER:
+ rv->unload = OUFB_TRANSFER;
+ if (_settings_client.gui.auto_noload_on_transfer)
+ rv->load = OLFB_NO_LOAD;
+ break;
+
+ case GOFS_NOLOAD:
+ rv->load = OLFB_NO_LOAD;
+ break;
+
+ case GOFS_NONE:
+ break;
+
+ default: NOT_REACHED();
+ }
+}
+
extern uint ConvertSpeedToDisplaySpeed(uint speed);
extern uint ConvertDisplaySpeedToSpeed(uint speed);
@@ -346,6 +418,19 @@ void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int
}
DrawString(rtl ? left : middle, rtl ? middle : right, y, STR_ORDER_TEXT, colour);
+
+ uint order_dist_sq = 0;
+ uint order_dist_mh = 0;
+ const Order *next2 = order->next != NULL ? order->next : v->GetFirstOrder();
+ TileIndex prev_tile = order->GetLocation(v, true);
+ TileIndex cur_tile = next2->GetLocation(v, true);
+ if (prev_tile != INVALID_TILE && cur_tile != INVALID_TILE){
+ order_dist_sq = IntSqrt(DistanceSquare(prev_tile, cur_tile));
+ order_dist_mh = DistanceManhattan(prev_tile, cur_tile);
+ }
+ SetDParam(0, order_dist_sq);
+ SetDParam(1, order_dist_mh);
+ DrawString(middle, right, y, STR_ORDER_DIST, TC_WHITE, SA_RIGHT);
}
/**
@@ -400,8 +485,34 @@ static Order GetOrderCmdFromTile(const Vehicle *v, TileIndex tile)
(facil = FACIL_BUS_STOP, v->type == VEH_ROAD && RoadVehicle::From(v)->IsBus()) ||
(facil = FACIL_TRUCK_STOP, 1);
if (st->facilities & facil) {
+ uint8 os = 0xff;
order.MakeGoToStation(st_index);
- if (_ctrl_pressed) order.SetLoadType(OLF_FULL_LOAD_ANY);
+ if (_ctrl_pressed) {
+ if (_shift_pressed)
+ os = _settings_client.gui.goto_shortcuts_ctrlshift_lclick;
+ else if (_alt_pressed)
+ os = _settings_client.gui.goto_shortcuts_altctrl_lclick;
+ else
+ os = _settings_client.gui.goto_shortcuts_ctrl_lclick;
+ }
+ else if (_shift_pressed) {
+ if (_alt_pressed)
+ os = _settings_client.gui.goto_shortcuts_altshift_lclick;
+ else
+ os = _settings_client.gui.goto_shortcuts_shift_lclick;
+ }
+ else if (_alt_pressed)
+ os = _settings_client.gui.goto_shortcuts_alt_lclick;
+
+ if (os != 0xff) {
+ struct OrdersFromSettings ofs;
+ GetOrdersFromSettings(v, os, &ofs);
+ if (ofs.load != (enum OrderLoadFlags)-1)
+ order.SetLoadType(ofs.load);
+ if (ofs.unload != (enum OrderUnloadFlags)-1)
+ order.SetUnloadType(ofs.unload);
+ }
+
if (_settings_client.gui.new_nonstop && v->IsGroundVehicle()) order.SetNonStopType(ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
order.SetStopLocation(v->type == VEH_TRAIN ? (OrderStopLocation)(_settings_client.gui.stop_location) : OSL_PLATFORM_FAR_END);
return order;
@@ -427,6 +538,7 @@ enum {
OHK_TRANSFER,
OHK_NO_UNLOAD,
OHK_NO_LOAD,
+ OHK_CLOSE,
};
/**
@@ -635,8 +747,15 @@ private:
DoCommandP(this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_UNLOAD | (unload_type << 4), CMD_MODIFY_ORDER | CMD_MSG(STR_ERROR_CAN_T_MODIFY_THIS_ORDER));
+ bool set_no_load = false;
+ if (unload_type == OUFB_TRANSFER){
+ set_no_load = _settings_client.gui.auto_noload_on_transfer;
+ }
+ else if (unload_type == OUFB_UNLOAD){
+ set_no_load = _settings_client.gui.auto_noload_on_unloadall;
+ }
/* Transfer orders with leave empty as default */
- if (unload_type == OUFB_TRANSFER) {
+ if (set_no_load) {
DoCommandP(this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_LOAD | (OLFB_NO_LOAD << 4), CMD_MODIFY_ORDER);
this->SetWidgetDirty(WID_O_FULL_LOAD);
}
@@ -1423,6 +1542,11 @@ public:
virtual EventState OnHotkey(int hotkey)
{
if (this->vehicle->owner != _local_company) return ES_NOT_HANDLED;
+ if(hotkey == OHK_GOTO && this->goto_type != OPOS_NONE){
+ this->RaiseWidget(WID_O_GOTO);
+ ResetObjectToPlace();
+ return ES_NOT_HANDLED;
+ }
switch (hotkey) {
case OHK_SKIP: this->OrderClick_Skip(); break;
@@ -1436,6 +1560,7 @@ public:
case OHK_TRANSFER: this->OrderHotkey_Transfer(); break;
case OHK_NO_UNLOAD: this->OrderHotkey_NoUnload(); break;
case OHK_NO_LOAD: this->OrderHotkey_NoLoad(); break;
+ case OHK_CLOSE: delete this; break;
default: return ES_NOT_HANDLED;
}
return ES_HANDLED;
@@ -1447,7 +1572,21 @@ public:
const Order cmd = GetOrderCmdFromTile(this->vehicle, tile);
if (cmd.IsType(OT_NOTHING)) return;
- if (DoCommandP(this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), cmd.Pack(), CMD_INSERT_ORDER | CMD_MSG(STR_ERROR_CAN_T_INSERT_NEW_ORDER))) {
+ if (gofsfeeder_ordermod != GOFS_FEEDER_NULL) {
+ if (gofsfeeder_ordermod == GOFS_FEEDER_LOAD) {
+ if (DoCommandP(this->vehicle->tile, this->vehicle->index + ((1) << 20), cmd.Pack(), CMD_INSERT_ORDER | CMD_MSG(STR_ERROR_CAN_T_INSERT_NEW_ORDER))) {
+ DoCommandP(this->vehicle->tile, this->vehicle->index, 0, CMD_DELETE_ORDER | CMD_MSG(STR_ERROR_CAN_T_DELETE_THIS_ORDER));
+ }
+
+ }
+ else if (gofsfeeder_ordermod == GOFS_FEEDER_UNLOAD) { // still flushes the whole order table
+ if (DoCommandP(this->vehicle->tile, this->vehicle->index + ((this->vehicle->GetNumOrders()) << 20), cmd.Pack(), CMD_INSERT_ORDER | CMD_MSG(STR_ERROR_CAN_T_INSERT_NEW_ORDER))) {
+ DoCommandP(this->vehicle->tile, this->vehicle->index, (this->vehicle->GetNumOrders()-2+(int)_networking) , CMD_DELETE_ORDER | CMD_MSG(STR_ERROR_CAN_T_DELETE_THIS_ORDER));
+ }
+ }
+ gofsfeeder_ordermod = GOFS_FEEDER_NULL;
+ }
+ else if (DoCommandP(this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), cmd.Pack(), CMD_INSERT_ORDER | CMD_MSG(STR_ERROR_CAN_T_INSERT_NEW_ORDER))) {
/* With quick goto the Go To button stays active */
if (!_settings_client.gui.quick_goto) ResetObjectToPlace();
}
@@ -1525,6 +1664,7 @@ static Hotkey order_hotkeys[] = {
Hotkey((uint16)0, "transfer", OHK_TRANSFER),
Hotkey((uint16)0, "no_unload", OHK_NO_UNLOAD),
Hotkey((uint16)0, "no_load", OHK_NO_LOAD),
+ Hotkey('Q', "close", OHK_CLOSE),
HOTKEY_LIST_END
};
HotkeyList OrdersWindow::hotkeys("order", order_hotkeys);
diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp
index f732b03a8f..64781eddc6 100644
--- a/src/rail_cmd.cpp
+++ b/src/rail_cmd.cpp
@@ -44,6 +44,7 @@
typedef SmallVector TrainList;
RailtypeInfo _railtypes[RAILTYPE_END];
+TileIndex _rail_track_endtile; ///< The end of a rail track; as hidden return from the rail build/remove command for GUI purposes.
assert_compile(sizeof(_original_railtypes) <= sizeof(_railtypes));
@@ -560,6 +561,7 @@ CommandCost CmdBuildSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, u
}
cost.AddCost(RailBuildCost(railtype));
+ _rail_track_endtile = tile;
return cost;
}
@@ -704,6 +706,7 @@ CommandCost CmdRemoveSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1,
if (v != NULL) TryPathReserve(v, true);
}
+ _rail_track_endtile = tile;
return cost;
}
diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp
index 7d4c88b8a3..53ff51e1c5 100644
--- a/src/rail_gui.cpp
+++ b/src/rail_gui.cpp
@@ -52,6 +52,8 @@ static bool _convert_signal_button; ///< convert signal button in the s
static SignalVariant _cur_signal_variant; ///< set the signal variant (for signal GUI)
static SignalType _cur_signal_type; ///< set the signal type (for signal GUI)
+extern TileIndex _rail_track_endtile; // rail_cmd.cpp
+
/* Map the setting: default_signal_type to the corresponding signal type */
static const SignalType _default_signal_type[] = {SIGTYPE_NORMAL, SIGTYPE_PBS, SIGTYPE_PBS_ONEWAY};
@@ -91,9 +93,9 @@ void CcPlaySound1E(const CommandCost &result, TileIndex tile, uint32 p1, uint32
if (result.Succeeded() && _settings_client.sound.confirm) SndPlayTileFx(SND_20_SPLAT_RAIL, tile);
}
-static void GenericPlaceRail(TileIndex tile, int cmd)
+static bool GenericPlaceRail(TileIndex tile, Track track)
{
- DoCommandP(tile, _cur_railtype, cmd,
+ return DoCommandP(tile, _cur_railtype, track,
_remove_button_clicked ?
CMD_REMOVE_SINGLE_RAIL | CMD_MSG(STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK) :
CMD_BUILD_SINGLE_RAIL | CMD_MSG(STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK),
@@ -276,6 +278,7 @@ void CcBuildRailTunnel(const CommandCost &result, TileIndex tile, uint32 p1, uin
if (result.Succeeded()) {
if (_settings_client.sound.confirm) SndPlayTileFx(SND_20_SPLAT_RAIL, tile);
if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
+ StoreRailPlacementEndpoints(tile, _build_tunnel_endtile, TileX(tile) == TileX(_build_tunnel_endtile) ? TRACK_Y : TRACK_X, false);
} else {
SetRedErrorSquare(_build_tunnel_endtile);
}
@@ -305,7 +308,7 @@ static bool RailToolbar_CtrlChanged(Window *w)
/* allow ctrl to switch remove mode only for these widgets */
for (uint i = WID_RAT_BUILD_NS; i <= WID_RAT_BUILD_STATION; i++) {
- if ((i <= WID_RAT_AUTORAIL || i >= WID_RAT_BUILD_WAYPOINT) && w->IsWidgetLowered(i)) {
+ if ((i <= WID_RAT_POLYRAIL || i >= WID_RAT_BUILD_WAYPOINT) && w->IsWidgetLowered(i)) {
ToggleRailButton_Remove(w);
return true;
}
@@ -349,9 +352,9 @@ static void BuildRailClick_Remove(Window *w)
}
}
-static void DoRailroadTrack(int mode)
+static bool DoRailroadTrack(TileIndex start_tile, TileIndex end_tile, Track track)
{
- DoCommandP(TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), _cur_railtype | (mode << 4),
+ return DoCommandP(start_tile, end_tile, _cur_railtype | (track << 4),
_remove_button_clicked ?
CMD_REMOVE_RAILROAD_TRACK | CMD_MSG(STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK) :
CMD_BUILD_RAILROAD_TRACK | CMD_MSG(STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK),
@@ -360,14 +363,14 @@ static void DoRailroadTrack(int mode)
static void HandleAutodirPlacement()
{
- int trackstat = _thd.drawstyle & HT_DIR_MASK; // 0..5
+ Track track = (Track)(_thd.drawstyle & HT_DIR_MASK); // 0..5
+ TileIndex start_tile = TileVirtXY(_thd.selstart.x, _thd.selstart.y);
+ TileIndex end_tile = TileVirtXY(_thd.selend.x, _thd.selend.y);
- if (_thd.drawstyle & HT_RAIL) { // one tile case
- GenericPlaceRail(TileVirtXY(_thd.selend.x, _thd.selend.y), trackstat);
- return;
+ if ((_thd.drawstyle & HT_RAIL ? GenericPlaceRail(end_tile, track) : DoRailroadTrack(start_tile, end_tile, track))
+ && !_shift_pressed) {
+ StoreRailPlacementEndpoints(start_tile, _rail_track_endtile, track, true);
}
-
- DoRailroadTrack(trackstat);
}
/**
@@ -414,6 +417,73 @@ static void HandleAutoSignalPlacement()
}
+// FIXME duplicate from road_gui.cpp
+static DiagDirection TileFractCoordsToDiagDir() {
+ bool diag = (_tile_fract_coords.x + _tile_fract_coords.y) < 16;
+ if (_tile_fract_coords.x < _tile_fract_coords.y) {
+ return diag ? DIAGDIR_NE : DIAGDIR_SE;
+ }
+ return diag ? DIAGDIR_NW : DIAGDIR_SW;
+}
+
+// FIXME duplicate from road_gui.cpp
+static DiagDirection RoadBitsToDiagDir(RoadBits bits) {
+ if (bits < ROAD_SE) {
+ return bits == ROAD_NW ? DIAGDIR_NW : DIAGDIR_SW;
+ }
+ return bits == ROAD_SE ? DIAGDIR_SE : DIAGDIR_NE;
+}
+
+RoadBits FindRailsToConnect(TileIndex tile) {
+ RoadBits directed = ROAD_NONE;
+ RoadBits passing = ROAD_NONE;
+ DiagDirection ddir;
+ for (ddir = DIAGDIR_BEGIN; ddir < DIAGDIR_END; ddir++) {
+ TileIndex cur_tile = TileAddByDiagDir(tile, ddir);
+ if (HasStationTileRail(cur_tile)) {
+ if (GetRailStationTrackBits(cur_tile) & DiagdirReachesTracks(ddir)) {
+ directed |= DiagDirToRoadBits(ddir);
+ }
+ continue;
+ }
+ if (!IsTileType(cur_tile, MP_RAILWAY)) continue;
+ if (!IsPlainRail(cur_tile)) continue;
+ passing |= DiagDirToRoadBits(ddir);
+ if (GetTrackBits(cur_tile) & DiagdirReachesTracks(ddir)) {
+ directed |= DiagDirToRoadBits(ddir);
+ }
+ }
+ // Prioritize track bits that head in this direction
+ if (directed != ROAD_NONE) {
+ return directed;
+ }
+ return passing;
+}
+
+/*
+ * Selects orientation for rail object (depot)
+ */
+static DiagDirection AutodetectRailObjectDirection(TileIndex tile) {
+ RoadBits bits = FindRailsToConnect(tile);
+ // FIXME after this point repeats road autodetection
+ if (HasExactlyOneBit(bits)) return RoadBitsToDiagDir(bits);
+ if (bits == ROAD_NONE) bits = ROAD_ALL;
+ RoadBits frac_bits = DiagDirToRoadBits(TileFractCoordsToDiagDir());
+ if (HasExactlyOneBit(frac_bits & bits)) {
+ return RoadBitsToDiagDir(frac_bits & bits);
+ }
+ frac_bits |= MirrorRoadBits(frac_bits);
+ if (HasExactlyOneBit(frac_bits & bits)) {
+ return RoadBitsToDiagDir(frac_bits & bits);
+ }
+ for (DiagDirection ddir = DIAGDIR_BEGIN; ddir < DIAGDIR_END; ddir++) {
+ if (DiagDirToRoadBits(ddir) & bits) {
+ return ddir;
+ }
+ }
+ NOT_REACHED();
+}
+
/** Rail toolbar management class. */
struct BuildRailToolbarWindow : Window {
RailType railtype; ///< Rail type to build.
@@ -461,6 +531,7 @@ struct BuildRailToolbarWindow : Window {
this->GetWidget(WID_RAT_BUILD_EW)->widget_data = rti->gui_sprites.build_ew_rail;
this->GetWidget(WID_RAT_BUILD_Y)->widget_data = rti->gui_sprites.build_y_rail;
this->GetWidget(WID_RAT_AUTORAIL)->widget_data = rti->gui_sprites.auto_rail;
+ this->GetWidget(WID_RAT_POLYRAIL)->widget_data = rti->gui_sprites.auto_rail;
this->GetWidget(WID_RAT_BUILD_DEPOT)->widget_data = rti->gui_sprites.build_depot;
this->GetWidget(WID_RAT_CONVERT_RAIL)->widget_data = rti->gui_sprites.convert_rail;
this->GetWidget(WID_RAT_BUILD_TUNNEL)->widget_data = rti->gui_sprites.build_tunnel;
@@ -489,6 +560,7 @@ struct BuildRailToolbarWindow : Window {
case WID_RAT_BUILD_EW:
case WID_RAT_BUILD_Y:
case WID_RAT_AUTORAIL:
+ case WID_RAT_POLYRAIL:
case WID_RAT_BUILD_WAYPOINT:
case WID_RAT_BUILD_STATION:
case WID_RAT_BUILD_SIGNALS:
@@ -520,6 +592,15 @@ struct BuildRailToolbarWindow : Window {
}
}
+ virtual void DrawWidget(const Rect &r, int widget) const
+ {
+ if (widget == WID_RAT_POLYRAIL) {
+ Dimension d = GetSpriteSize(SPR_BLOT);
+ uint offset = this->IsWidgetLowered(WID_RAT_POLYRAIL) ? 1 : 0;
+ DrawSprite(SPR_BLOT, PALETTE_TO_GREY, (r.left + r.right - d.width) / 2 + offset, (r.top + r.bottom - d.height) / 2 + offset);
+ }
+ }
+
virtual void OnClick(Point pt, int widget, int click_count)
{
if (widget < WID_RAT_BUILD_NS) return;
@@ -551,6 +632,11 @@ struct BuildRailToolbarWindow : Window {
this->last_user_action = widget;
break;
+ case WID_RAT_POLYRAIL:
+ HandlePlacePushButton(this, WID_RAT_POLYRAIL, GetRailTypeInfo(railtype)->cursor.autorail, HT_RAIL | HT_POLY);
+ this->last_user_action = widget;
+ break;
+
case WID_RAT_DEMOLISH:
HandlePlacePushButton(this, WID_RAT_DEMOLISH, ANIMCURSOR_DEMOLISH, HT_RECT | HT_DIAGONAL);
this->last_user_action = widget;
@@ -620,6 +706,7 @@ struct BuildRailToolbarWindow : Window {
virtual void OnPlaceObject(Point pt, TileIndex tile)
{
+ DiagDirection ddir;
switch (this->last_user_action) {
case WID_RAT_BUILD_NS:
VpStartPlaceSizing(tile, VPM_FIX_VERTICAL | VPM_RAILDIRS, DDSP_PLACE_RAIL);
@@ -638,6 +725,7 @@ struct BuildRailToolbarWindow : Window {
break;
case WID_RAT_AUTORAIL:
+ case WID_RAT_POLYRAIL:
VpStartPlaceSizing(tile, VPM_RAILDIRS, DDSP_PLACE_RAIL);
break;
@@ -646,7 +734,11 @@ struct BuildRailToolbarWindow : Window {
break;
case WID_RAT_BUILD_DEPOT:
- DoCommandP(tile, _cur_railtype, _build_depot_direction,
+ ddir = _build_depot_direction;
+ if (ddir == DIAGDIR_NW + 1) {
+ ddir = AutodetectRailObjectDirection(tile);
+ }
+ DoCommandP(tile, _cur_railtype, ddir,
CMD_BUILD_TRAIN_DEPOT | CMD_MSG(STR_ERROR_CAN_T_BUILD_TRAIN_DEPOT),
CcRailDepot);
break;
@@ -785,6 +877,7 @@ static EventState RailToolbarGlobalHotkeys(int hotkey)
}
const uint16 _railtoolbar_autorail_keys[] = {'5', 'A' | WKC_GLOBAL_HOTKEY, 0};
+const uint16 _railtoolbar_polyrail_keys[] = {'5' | WKC_CTRL, 'A' | WKC_GLOBAL_HOTKEY | WKC_CTRL, 0};
static Hotkey railtoolbar_hotkeys[] = {
Hotkey('1', "build_ns", WID_RAT_BUILD_NS),
@@ -792,6 +885,7 @@ static Hotkey railtoolbar_hotkeys[] = {
Hotkey('3', "build_ew", WID_RAT_BUILD_EW),
Hotkey('4', "build_y", WID_RAT_BUILD_Y),
Hotkey(_railtoolbar_autorail_keys, "autorail", WID_RAT_AUTORAIL),
+ Hotkey(_railtoolbar_polyrail_keys, "polyrail", WID_RAT_POLYRAIL),
Hotkey('6', "demolish", WID_RAT_DEMOLISH),
Hotkey('7', "depot", WID_RAT_BUILD_DEPOT),
Hotkey('8', "waypoint", WID_RAT_BUILD_WAYPOINT),
@@ -822,6 +916,8 @@ static const NWidgetPart _nested_build_rail_widgets[] = {
SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_RAIL_NW, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK),
NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_RAT_AUTORAIL),
SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_AUTORAIL, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_AUTORAIL),
+ NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_RAT_POLYRAIL),
+ SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_AUTORAIL, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_POLYRAIL),
NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetMinimalSize(4, 22), SetDataTip(0x0, STR_NULL), EndContainer(),
@@ -1723,6 +1819,7 @@ struct BuildRailDepotWindow : public PickerWindowBase {
case WID_BRAD_DEPOT_SE:
case WID_BRAD_DEPOT_SW:
case WID_BRAD_DEPOT_NW:
+ case WID_BRAD_DEPOT_AUTO:
this->RaiseWidget(_build_depot_direction + WID_BRAD_DEPOT_NE);
_build_depot_direction = (DiagDirection)(widget - WID_BRAD_DEPOT_NE);
this->LowerWidget(_build_depot_direction + WID_BRAD_DEPOT_NE);
@@ -1760,6 +1857,9 @@ static const NWidgetPart _nested_build_depot_widgets[] = {
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(3, 0), SetFill(1, 0),
EndContainer(),
+ NWidget(NWID_HORIZONTAL), SetPIP(2, 2, 2),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BRAD_DEPOT_AUTO), SetMinimalSize(134, 12), SetDataTip(STR_STATION_BUILD_ORIENTATION_AUTO, STR_BUILD_DEPOT_TRAIN_ORIENTATION_AUTO_TOOLTIP),
+ EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 3),
EndContainer(),
};
@@ -1880,7 +1980,7 @@ static void ShowBuildWaypointPicker(Window *parent)
*/
void InitializeRailGui()
{
- _build_depot_direction = DIAGDIR_NW;
+ _build_depot_direction = (DiagDirection)(DIAGDIR_NW + 1);
}
/**
diff --git a/src/rev.cpp b/src/rev.cpp
index afd8bb8f12..7bf02574a3 100644
--- a/src/rev.cpp
+++ b/src/rev.cpp
@@ -1,4 +1,4 @@
-/* $Id: rev.cpp.in 26440 2014-04-01 18:33:16Z frosch $ */
+/* $Id: rev.cpp.in 26482 2014-04-23 20:13:33Z rubidium $ */
/*
* This file is part of OpenTTD.
@@ -13,6 +13,8 @@
#include "core/bitmath_func.hpp"
#include "rev.h"
+#include "safeguards.h"
+
/**
* Is this version of OpenTTD a release version?
* @return True if it is a release version.
@@ -37,7 +39,7 @@ bool IsReleasedVersion()
* norev000 is for non-releases that are made on systems without
* subversion or sources that are not a checkout of subversion.
*/
-const char _openttd_revision[] = "1.4.0";
+const char _openttd_revision[] = "1.5.0-beta2";
/**
* The text version of OpenTTD's build date.
@@ -70,11 +72,11 @@ const byte _openttd_revision_modified = 0;
* final release will always have a lower version number than the released
* version, thus making comparisons on specific revisions easy.
*/
-const uint32 _openttd_newgrf_version = 1 << 28 | 4 << 24 | 0 << 20 | 1 << 19 | (26440 & ((1 << 19) - 1));
+const uint32 _openttd_newgrf_version = 1 << 28 | 5 << 24 | 0 << 20 | 0 << 19 | (27170 & ((1 << 19) - 1));
#ifdef __MORPHOS__
/**
* Variable used by MorphOS to show the version.
*/
-extern const char morphos_versions_tag[] = "$VER: OpenTTD 1.4.0 (02.04.14) OpenTTD Team [MorphOS, PowerPC]";
+extern const char morphos_versions_tag[] = "$VER: OpenTTD 1.5.0-beta2 (16.03.15) OpenTTD Team [MorphOS, PowerPC]";
#endif
diff --git a/src/rev.cpp.in b/src/rev.cpp.in
index b17c04cc24..44b2853fb4 100644
--- a/src/rev.cpp.in
+++ b/src/rev.cpp.in
@@ -39,7 +39,7 @@ bool IsReleasedVersion()
* norev000 is for non-releases that are made on systems without
* subversion or sources that are not a checkout of subversion.
*/
-const char _openttd_revision[] = "!!VERSION!!";
+const char _openttd_revision[] = "1.5.0-beta2";
/**
* The text version of OpenTTD's build date.
@@ -57,7 +57,7 @@ const char _openttd_build_date[] = __DATE__ " " __TIME__;
* (compiling from sources without any version control software)
* and 2 is for modified revision.
*/
-const byte _openttd_revision_modified = !!MODIFIED!!;
+const byte _openttd_revision_modified = 0;
/**
* The NewGRF revision of OTTD:
diff --git a/src/road_gui.cpp b/src/road_gui.cpp
index 950ac643d7..41233594cb 100644
--- a/src/road_gui.cpp
+++ b/src/road_gui.cpp
@@ -11,7 +11,9 @@
#include "stdafx.h"
#include "gui.h"
+#include "cmd_helper.h"
#include "window_gui.h"
+#include "station_func.h"
#include "station_gui.h"
#include "terraform_gui.h"
#include "viewport_func.h"
@@ -211,6 +213,107 @@ void CcRoadStop(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2)
}
}
+
+static RoadBits FindRoadsToConnect(TileIndex tile) {
+ RoadBits bits = ROAD_NONE;
+ DiagDirection ddir;
+ // Prioritize roadbits that head in this direction
+ for (ddir = DIAGDIR_BEGIN; ddir < DIAGDIR_END; ddir++) {
+ TileIndex cur_tile = TileAddByDiagDir(tile, ddir);
+ if (GetAnyRoadBits(cur_tile, ROADTYPE_ROAD, true) &
+ DiagDirToRoadBits(ReverseDiagDir(ddir)))
+ {
+ bits |= DiagDirToRoadBits(ddir);
+ }
+ }
+ if (bits != ROAD_NONE) {
+ return bits;
+ }
+ // Try to connect to any road passing by
+ for (ddir = DIAGDIR_BEGIN; ddir < DIAGDIR_END; ddir++) {
+ TileIndex cur_tile = TileAddByDiagDir(tile, ddir);
+ if (HasTileRoadType(cur_tile, ROADTYPE_ROAD) && (GetTileType(cur_tile) == MP_ROAD) &&
+ (GetRoadTileType(cur_tile) == ROAD_TILE_NORMAL)) {
+ bits |= DiagDirToRoadBits(ddir);
+ }
+ }
+ return bits;
+}
+
+static DiagDirection RoadBitsToDiagDir(RoadBits bits) {
+ if (bits < ROAD_SE) {
+ return bits == ROAD_NW ? DIAGDIR_NW : DIAGDIR_SW;
+ }
+ return bits == ROAD_SE ? DIAGDIR_SE : DIAGDIR_NE;
+}
+
+static DiagDirection TileFractCoordsToDiagDir() {
+ bool diag = (_tile_fract_coords.x + _tile_fract_coords.y) < 16;
+ if (_tile_fract_coords.x < _tile_fract_coords.y) {
+ return diag ? DIAGDIR_NE : DIAGDIR_SE;
+ }
+ return diag ? DIAGDIR_NW : DIAGDIR_SW;
+}
+/*
+ * Selects orientation for road object (depot, terminal station)
+ */
+static DiagDirection AutodetectRoadObjectDirection(TileIndex tile) {
+ RoadBits bits = FindRoadsToConnect(tile);
+ if (HasExactlyOneBit(bits)) {
+ return RoadBitsToDiagDir(bits);
+ }
+ if (bits == ROAD_NONE){
+ bits = ROAD_ALL;
+ }
+ RoadBits frac_bits = DiagDirToRoadBits(TileFractCoordsToDiagDir());
+ if (HasExactlyOneBit(frac_bits & bits)) {
+ return RoadBitsToDiagDir(frac_bits & bits);
+ }
+ frac_bits |= MirrorRoadBits(frac_bits);
+ if (HasExactlyOneBit(frac_bits & bits)) {
+ return RoadBitsToDiagDir(frac_bits & bits);
+ }
+ for (DiagDirection ddir = DIAGDIR_BEGIN; ddir < DIAGDIR_END; ddir++) {
+ if (DiagDirToRoadBits(ddir) & bits) {
+ return ddir;
+ }
+ }
+ NOT_REACHED();
+}
+
+static bool CheckDriveThroughRoadStopDirection(TileArea area, RoadBits r) {
+ TILE_AREA_LOOP(tile, area) {
+ if (!HasTileRoadType(tile, ROADTYPE_ROAD)) continue;
+ if (GetTileType(tile) != MP_ROAD) continue;
+ if (GetRoadTileType(tile) != ROAD_TILE_NORMAL) continue;
+ if (GetRoadBits(tile, ROADTYPE_ROAD) & ~r) return false;
+ }
+ return true;
+}
+
+
+/*
+ * Automaticaly selects direction to use for road stop.
+ * @param area road stop area
+ * @return selected direction
+ */
+static DiagDirection AutodetectDriveThroughRoadStopDirection(TileArea area) {
+ bool se_suits, ne_suits;
+
+ // Check which direction is available
+ // If both are not use SE, building will fail anyway
+ se_suits = CheckDriveThroughRoadStopDirection(area, ROAD_Y);
+ ne_suits = CheckDriveThroughRoadStopDirection(area, ROAD_X);
+ if (!ne_suits) return DIAGDIR_SE;
+ if (!se_suits) return DIAGDIR_NE;
+
+ // Build station along the longer direction
+ if (area.w > area.h) return DIAGDIR_NE;
+ if (area.w < area.h) return DIAGDIR_SE;
+
+ return AutodetectRoadObjectDirection(area.tile);
+}
+
/**
* Place a new road stop.
* @param start_tile First tile of the area.
@@ -225,14 +328,23 @@ static void PlaceRoadStop(TileIndex start_tile, TileIndex end_tile, uint32 p2, u
{
uint8 ddir = _road_station_picker_orientation;
SB(p2, 16, 16, INVALID_STATION); // no station to join
+ TileArea ta(start_tile, end_tile);
if (ddir >= DIAGDIR_END) {
- SetBit(p2, 1); // It's a drive-through stop.
- ddir -= DIAGDIR_END; // Adjust picker result to actual direction.
+ if (ddir < DIAGDIR_END + 2) {
+ SetBit(p2, 1); // It's a drive-through stop.
+ ddir -= DIAGDIR_END; // Adjust picker result to actual direction.
+ }
+ else if (ddir == DIAGDIR_END + 2) {
+ ddir = AutodetectRoadObjectDirection(start_tile);
+ }
+ else if (ddir == DIAGDIR_END + 3) {
+ SetBit(p2, 1); // It's a drive-through stop.
+ ddir = AutodetectDriveThroughRoadStopDirection(ta);
+ }
}
p2 |= ddir << 6; // Set the DiagDirecion into p2 bits 6 and 7.
- TileArea ta(start_tile, end_tile);
CommandContainer cmdcont = { ta.tile, ta.w | ta.h << 8, p2, cmd, CcRoadStop, "" };
ShowSelectStationIfNeeded(cmdcont, ta);
}
@@ -297,7 +409,7 @@ static bool RoadToolbar_CtrlChanged(Window *w)
if (w->IsWidgetDisabled(WID_ROT_REMOVE)) return false;
/* allow ctrl to switch remove mode only for these widgets */
- for (uint i = WID_ROT_ROAD_X; i <= WID_ROT_AUTOROAD; i++) {
+ for (uint i = WID_ROT_ROAD_X; i <= WID_ROT_FULLROAD; i++) {
if (w->IsWidgetLowered(i)) {
ToggleRoadButton_Remove(w);
return true;
@@ -382,6 +494,7 @@ struct BuildRoadToolbarWindow : Window {
case WID_ROT_ROAD_X:
case WID_ROT_ROAD_Y:
case WID_ROT_AUTOROAD:
+ case WID_ROT_FULLROAD:
this->SetWidgetsDisabledState(!this->IsWidgetLowered(clicked_widget),
WID_ROT_REMOVE,
WID_ROT_ONE_WAY,
@@ -403,6 +516,16 @@ struct BuildRoadToolbarWindow : Window {
}
}
+ virtual void DrawWidget(const Rect &r, int widget) const
+ {
+ if (widget == WID_ROT_FULLROAD) {
+ Dimension d = GetSpriteSize(SPR_BLOT);
+ uint offset = this->IsWidgetLowered(WID_ROT_FULLROAD) ? 1 : 0;
+ DrawSprite(SPR_BLOT, PALETTE_TO_GREY, (r.left + r.right - d.width) / 2 + offset, (r.top + r.bottom - d.height) / 2 + offset);
+ }
+ }
+
+
virtual void OnClick(Point pt, int widget, int click_count)
{
_remove_button_clicked = false;
@@ -423,6 +546,11 @@ struct BuildRoadToolbarWindow : Window {
this->last_started_action = widget;
break;
+ case WID_ROT_FULLROAD:
+ HandlePlacePushButton(this, WID_ROT_FULLROAD, _road_type_infos[_cur_roadtype].cursor_autoroad, HT_RECT);
+ this->last_started_action = widget;
+ break;
+
case WID_ROT_DEMOLISH:
HandlePlacePushButton(this, WID_ROT_DEMOLISH, ANIMCURSOR_DEMOLISH, HT_RECT | HT_DIAGONAL);
this->last_started_action = widget;
@@ -491,6 +619,7 @@ struct BuildRoadToolbarWindow : Window {
virtual void OnPlaceObject(Point pt, TileIndex tile)
{
+ DiagDirection ddir;
_remove_button_clicked = this->IsWidgetLowered(WID_ROT_REMOVE);
_one_way_button_clicked = this->IsWidgetLowered(WID_ROT_ONE_WAY);
switch (this->last_started_action) {
@@ -513,12 +642,21 @@ struct BuildRoadToolbarWindow : Window {
VpStartPlaceSizing(tile, VPM_X_OR_Y, DDSP_PLACE_AUTOROAD);
break;
+ case WID_ROT_FULLROAD:
+ _place_road_flag = RF_NONE;
+ VpStartPlaceSizing(tile, VPM_X_OR_Y, DDSP_PLACE_FULLROAD);
+ break;
+
case WID_ROT_DEMOLISH:
PlaceProc_DemolishArea(tile);
break;
case WID_ROT_DEPOT:
- DoCommandP(tile, _cur_roadtype << 2 | _road_depot_orientation, 0,
+ ddir = _road_depot_orientation;
+ if (ddir == DIAGDIR_NW + 1) {
+ ddir = AutodetectRoadObjectDirection(tile);
+ }
+ DoCommandP(tile, _cur_roadtype << 2 | ddir, 0,
CMD_BUILD_ROAD_DEPOT | CMD_MSG(_road_type_infos[_cur_roadtype].err_depot), CcRoadDepot);
break;
@@ -596,6 +734,21 @@ struct BuildRoadToolbarWindow : Window {
break;
+ case DDSP_PLACE_FULLROAD:
+ /* For autoroad we need to update the
+ * direction of the road */
+ if (_thd.size.x > _thd.size.y || (_thd.size.x == _thd.size.y &&
+ ( (_tile_fract_coords.x < _tile_fract_coords.y && (_tile_fract_coords.x + _tile_fract_coords.y) < 16) ||
+ (_tile_fract_coords.x > _tile_fract_coords.y && (_tile_fract_coords.x + _tile_fract_coords.y) > 16) ))) {
+ /* Set dir = X */
+ _place_road_flag &= ~RF_DIR_Y;
+ }
+ else {
+ /* Set dir = Y */
+ _place_road_flag |= RF_DIR_Y;
+ }
+ break;
+
default:
break;
}
@@ -632,6 +785,16 @@ struct BuildRoadToolbarWindow : Window {
CMD_BUILD_LONG_ROAD | CMD_MSG(_road_type_infos[_cur_roadtype].err_build_road), CcPlaySound1D);
break;
+ case DDSP_PLACE_FULLROAD:
+ DoCommandP(start_tile, end_tile,
+ _place_road_flag | (_cur_roadtype << 3) |
+ (_one_way_button_clicked << 5) | (1 << 6) |
+ (start_tile > end_tile ? 1 : 2), // always build full roads
+ _remove_button_clicked ?
+ CMD_REMOVE_LONG_ROAD | CMD_MSG(_road_type_infos[_cur_roadtype].err_remove_road) :
+ CMD_BUILD_LONG_ROAD | CMD_MSG(_road_type_infos[_cur_roadtype].err_build_road), CcPlaySound1D);
+ break;
+
case DDSP_BUILD_BUSSTOP:
PlaceRoadStop(start_tile, end_tile, (_ctrl_pressed << 5) | RoadTypeToRoadTypes(_cur_roadtype) << 2 | ROADSTOP_BUS, CMD_BUILD_ROAD_STOP | CMD_MSG(_road_type_infos[_cur_roadtype].err_build_station[ROADSTOP_BUS]));
break;
@@ -706,6 +869,7 @@ static Hotkey roadtoolbar_hotkeys[] = {
Hotkey('6', "bus_station", WID_ROT_BUS_STATION),
Hotkey('7', "truck_station", WID_ROT_TRUCK_STATION),
Hotkey('8', "oneway", WID_ROT_ONE_WAY),
+ Hotkey('9', "fullroad", WID_ROT_FULLROAD),
Hotkey('B', "bridge", WID_ROT_BUILD_BRIDGE),
Hotkey('T', "tunnel", WID_ROT_BUILD_TUNNEL),
Hotkey('R', "remove", WID_ROT_REMOVE),
@@ -738,6 +902,8 @@ static const NWidgetPart _nested_build_road_widgets[] = {
NWidget(WWT_PANEL, COLOUR_DARK_GREEN, -1), SetMinimalSize(0, 22), SetFill(1, 1), EndContainer(),
NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_ONE_WAY),
SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_ONE_WAY, STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_ONE_WAY_ROAD),
+ NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_FULLROAD),
+ SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_AUTOROAD, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_FULLROAD),
NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUILD_BRIDGE),
SetFill(0, 1), SetMinimalSize(43, 22), SetDataTip(SPR_IMG_BRIDGE, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_BRIDGE),
NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUILD_TUNNEL),
@@ -864,7 +1030,7 @@ struct BuildRoadDepotWindow : public PickerWindowBase {
this->LowerWidget(_road_depot_orientation + WID_BROD_DEPOT_NE);
if ( _cur_roadtype == ROADTYPE_TRAM) {
this->GetWidget(WID_BROD_CAPTION)->widget_data = STR_BUILD_DEPOT_TRAM_ORIENTATION_CAPTION;
- for (int i = WID_BROD_DEPOT_NE; i <= WID_BROD_DEPOT_NW; i++) this->GetWidget(i)->tool_tip = STR_BUILD_DEPOT_TRAM_ORIENTATION_SELECT_TOOLTIP;
+ for (int i = WID_BROD_DEPOT_NE; i <= WID_BROD_DEPOT_AUTO; i++) this->GetWidget(i)->tool_tip = STR_BUILD_DEPOT_TRAM_ORIENTATION_SELECT_TOOLTIP;
}
this->FinishInitNested(TRANSPORT_ROAD);
@@ -892,6 +1058,7 @@ struct BuildRoadDepotWindow : public PickerWindowBase {
case WID_BROD_DEPOT_NE:
case WID_BROD_DEPOT_SW:
case WID_BROD_DEPOT_SE:
+ case WID_BROD_DEPOT_AUTO:
this->RaiseWidget(_road_depot_orientation + WID_BROD_DEPOT_NE);
_road_depot_orientation = (DiagDirection)(widget - WID_BROD_DEPOT_NE);
this->LowerWidget(_road_depot_orientation + WID_BROD_DEPOT_NE);
@@ -931,6 +1098,9 @@ static const NWidgetPart _nested_build_road_depot_widgets[] = {
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(3, 0), SetFill(1, 0),
EndContainer(),
+ NWidget(NWID_HORIZONTAL), SetPIP(2, 2, 2),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROD_DEPOT_AUTO), SetMinimalSize(134, 12), SetDataTip(STR_STATION_BUILD_ORIENTATION_AUTO, STR_BUILD_DEPOT_ROAD_ORIENTATION_AUTO_TOOLTIP),
+ EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 3),
EndContainer(),
};
@@ -1031,6 +1201,8 @@ struct BuildRoadStationWindow : public PickerWindowBase {
case WID_BROS_STATION_NW:
case WID_BROS_STATION_X:
case WID_BROS_STATION_Y:
+ case WID_BROS_STATION_AUTO:
+ case WID_BROS_STATION_XY_AUTO:
this->RaiseWidget(_road_station_picker_orientation + WID_BROS_STATION_NE);
_road_station_picker_orientation = (DiagDirection)(widget - WID_BROS_STATION_NE);
this->LowerWidget(_road_station_picker_orientation + WID_BROS_STATION_NE);
@@ -1082,6 +1254,13 @@ static const NWidgetPart _nested_rv_station_picker_widgets[] = {
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_Y), SetMinimalSize(66, 50), EndContainer(),
NWidget(NWID_SPACER), SetFill(1, 0),
EndContainer(),
+ NWidget(NWID_SPACER), SetMinimalSize(0, 2),
+ NWidget(NWID_HORIZONTAL), SetPIP(0, 2, 0),
+ NWidget(NWID_SPACER), SetFill(1, 0),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROS_STATION_AUTO), SetMinimalSize(134, 12), SetDataTip(STR_STATION_BUILD_ORIENTATION_AUTO, STR_STATION_BUILD_ORIENTATION_AUTO_TOOLTIP),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROS_STATION_XY_AUTO), SetMinimalSize(66, 12), SetDataTip(STR_STATION_BUILD_ORIENTATION_AUTO, STR_STATION_BUILD_ORIENTATION_AUTO_TOOLTIP),
+ NWidget(NWID_SPACER), SetFill(1, 0),
+ EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 1),
NWidget(NWID_HORIZONTAL), SetPIP(2, 0, 2),
NWidget(WWT_LABEL, COLOUR_DARK_GREEN, WID_BROS_INFO), SetMinimalSize(140, 14), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL),
@@ -1113,6 +1292,6 @@ static void ShowRVStationPicker(Window *parent, RoadStopType rs)
void InitializeRoadGui()
{
- _road_depot_orientation = DIAGDIR_NW;
- _road_station_picker_orientation = DIAGDIR_NW;
+ _road_depot_orientation = (DiagDirection)(DIAGDIR_NW + 1);
+ _road_station_picker_orientation = (DiagDirection)(DIAGDIR_END + 3);
}
diff --git a/src/saveload/town_sl.cpp b/src/saveload/town_sl.cpp
index 8776c40526..b5d645bf3b 100644
--- a/src/saveload/town_sl.cpp
+++ b/src/saveload/town_sl.cpp
@@ -32,6 +32,10 @@ void RebuildTownCaches()
FOR_ALL_TOWNS(town) {
town->cache.population = 0;
town->cache.num_houses = 0;
+ town->cache.potential_pop = 0;
+ town->houses_construction = 0;
+ town->houses_reconstruction = 0;
+ town->houses_demolished = 0;
}
for (TileIndex t = 0; t < MapSize(); t++) {
@@ -41,6 +45,10 @@ void RebuildTownCaches()
town = Town::GetByTile(t);
IncreaseBuildingCount(town, house_id);
if (IsHouseCompleted(t)) town->cache.population += HouseSpec::Get(house_id)->population;
+ else{
+ town->houses_construction++;
+ }
+ town->cache.potential_pop += HouseSpec::Get(house_id)->population;
/* Increase the number of houses for every house, but only once. */
if (GetHouseNorthPart(house_id) == 0) town->cache.num_houses++;
@@ -111,6 +119,7 @@ void UpdateHousesAndTowns()
}
RebuildTownCaches();
+ ResetTownsGrowthTiles();
}
/** Save and load of towns. */
diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp
index 8f58d80482..3ddb6fe6e0 100644
--- a/src/settings_gui.cpp
+++ b/src/settings_gui.cpp
@@ -1524,6 +1524,10 @@ static SettingsContainer &GetSettingsTree()
viewports->Add(new SettingEntry("gui.measure_tooltip"));
viewports->Add(new SettingEntry("gui.loading_indicators"));
viewports->Add(new SettingEntry("gui.show_track_reservation"));
+ viewports->Add(new SettingEntry("gui.cb_distance_check"));
+ viewports->Add(new SettingEntry("gui.old_depot_train_length_calc"));
+ viewports->Add(new SettingEntry("gui.enable_extra_tooltips"));
+ viewports->Add(new SettingEntry("gui.polyrail_double_click"));
}
SettingsPage *construction = interface->Add(new SettingsPage(STR_CONFIG_SETTING_INTERFACE_CONSTRUCTION));
@@ -1602,6 +1606,26 @@ static SettingsContainer &GetSettingsTree()
SettingsPage *vehicles = main->Add(new SettingsPage(STR_CONFIG_SETTING_VEHICLES));
{
+ /** Vehicle control page */
+ SettingsPage *veh_control = vehicles->Add(new SettingsPage(STR_CONFIG_SETTING_VEHICLES_CTRL));
+ {
+ veh_control->Add(new SettingEntry("gui.enable_ctrl_click_start_stop"));
+ veh_control->Add(new SettingEntry("gui.new_nonstop"));
+ veh_control->Add(new SettingEntry("gui.auto_noload_on_transfer"));
+ veh_control->Add(new SettingEntry("gui.auto_noload_on_unloadall"));
+ }
+
+ /** Order Shorcuts page */
+ SettingsPage *orders = veh_control->Add(new SettingsPage(STR_CONFIG_SETTING_ORDER_SHORTCUTS));
+ {
+ orders->Add(new SettingEntry("gui.goto_shortcuts_ctrl_lclick"));
+ orders->Add(new SettingEntry("gui.goto_shortcuts_shift_lclick"));
+ orders->Add(new SettingEntry("gui.goto_shortcuts_ctrlshift_lclick"));
+ orders->Add(new SettingEntry("gui.goto_shortcuts_alt_lclick"));
+ orders->Add(new SettingEntry("gui.goto_shortcuts_altshift_lclick"));
+ orders->Add(new SettingEntry("gui.goto_shortcuts_altctrl_lclick"));
+ }
+
SettingsPage *physics = vehicles->Add(new SettingsPage(STR_CONFIG_SETTING_VEHICLES_PHYSICS));
{
physics->Add(new SettingEntry("vehicle.train_acceleration_model"));
diff --git a/src/settings_type.h b/src/settings_type.h
index 41b26b5468..87be200980 100644
--- a/src/settings_type.h
+++ b/src/settings_type.h
@@ -79,6 +79,15 @@ struct GUISettings {
bool vehicle_income_warn; ///< if a vehicle isn't generating income, show a warning
bool show_finances; ///< show finances at end of year
bool sg_new_nonstop; ///< ttdpatch compatible nonstop handling read from pre v93 savegames
+ bool enable_ctrl_click_start_stop; ///< allow ctrl+click to start or stop vehicles
+ uint8 goto_shortcuts_ctrl_lclick; ///< goto action shortcut CTRL+LEFT-CLICK
+ uint8 goto_shortcuts_shift_lclick; ///< goto action shortcut SHIFT+LEFT-CLICK
+ uint8 goto_shortcuts_ctrlshift_lclick; ///< goto action shortcut CTRL+SHIFT+LEFT-CLICK
+ uint8 goto_shortcuts_alt_lclick; ///< goto action shortcut ALT+LEFT-CLICK
+ uint8 goto_shortcuts_altshift_lclick; ///< goto action shortcut ALT+SHIFT+LEFT-CLICK
+ uint8 goto_shortcuts_altctrl_lclick; ///< goto action shortcut ALT+CTRL+LEFT-CLICK
+ bool auto_noload_on_transfer; ///< automatically set no-loading when ordering to transfer all cargo
+ bool auto_noload_on_unloadall; ///< automatically set no-loading when ordering to unload all cargo
bool new_nonstop; ///< ttdpatch compatible nonstop handling
uint8 stop_location; ///< what is the default stop location of trains?
uint8 auto_scrolling; ///< scroll when moving mouse to the edge (see #ViewportAutoscrolling)
@@ -158,6 +167,11 @@ struct GUISettings {
bool newgrf_show_old_versions; ///< whether to show old versions in the NewGRF list
uint8 newgrf_default_palette; ///< default palette to use for NewGRFs without action 14 palette information
+ bool old_depot_train_length_calc; ///< display vehicle length in whole numbers - old style
+ uint8 cb_distance_check; ///< zoning cb distance
+ bool enable_extra_tooltips; ///< enable extra tooltips when hovering over various elements
+ bool polyrail_double_click; ///< finish polyrail with mouse double click
+
/**
* Returns true when the user has sufficient privileges to edit newgrfs on a running game
* @return whether the user has sufficient privileges to edit newgrfs in an existing game
diff --git a/src/smallmap_gui.cpp b/src/smallmap_gui.cpp
index 618cee5875..024a00c4b2 100644
--- a/src/smallmap_gui.cpp
+++ b/src/smallmap_gui.cpp
@@ -894,7 +894,7 @@ void SmallMapWindow::DrawTowns(const DrawPixelInfo *dpi) const
y < dpi->top + dpi->height) {
/* And draw it. */
SetDParam(0, t->index);
- DrawString(x, x + t->cache.sign.width_small, y, STR_SMALLMAP_TOWN);
+ DrawString(x, x + t->cache.sign.width_small, y, t->larger_town ? STR_SMALLMAP_TOWN_LARGE : STR_SMALLMAP_TOWN);
}
}
}
diff --git a/src/station_gui.cpp b/src/station_gui.cpp
index d7109b4f3d..5878734f19 100644
--- a/src/station_gui.cpp
+++ b/src/station_gui.cpp
@@ -2234,16 +2234,17 @@ static const NWidgetPart _nested_select_station_widgets[] = {
* @tparam T The type of station to join with
*/
template
-struct SelectStationWindow : Window {
+struct SelectStationWindow : WindowPopup {
CommandContainer select_station_cmd; ///< Command to build new station
TileArea area; ///< Location of new station
Scrollbar *vscroll;
SelectStationWindow(WindowDesc *desc, const CommandContainer &cmd, TileArea ta) :
- Window(desc),
+ WindowPopup(desc, WPUT_WIDGET_RELATIVE),
select_station_cmd(cmd),
area(ta)
{
+ this->wpu_widget = WID_JS_PANEL;
this->CreateNestedTree();
this->vscroll = this->GetScrollbar(WID_JS_SCROLLBAR);
this->GetWidget(WID_JS_CAPTION)->widget_data = T::EXPECTED_FACIL == FACIL_WAYPOINT ? STR_JOIN_WAYPOINT_CAPTION : STR_JOIN_STATION_CAPTION;
diff --git a/src/table/settings.ini b/src/table/settings.ini
index 5bd2059806..a1d1c9551f 100644
--- a/src/table/settings.ini
+++ b/src/table/settings.ini
@@ -3936,5 +3936,138 @@ strhelp = STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_HELPTEXT
strval = STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND
cat = SC_BASIC
+; //MODGUI *********************************
+[SDTC_BOOL]
+var = gui.enable_ctrl_click_start_stop
+flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
+def = true
+str = STR_CONFIG_SETTING_CTRL_ENABLE_CTRLCLICK_STARTSTOP
+
+[SDTC_BOOL]
+var = gui.auto_noload_on_transfer
+flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
+def = true
+str = STR_CONFIG_SETTING_AUTOSET_NOLOAD_ON_TRANSFER
+
+[SDTC_BOOL]
+var = gui.auto_noload_on_unloadall
+flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
+def = false
+str = STR_CONFIG_SETTING_AUTOSET_NOLOAD_ON_UNLOAD
+
+[SDTC_VAR]
+var = gui.goto_shortcuts_ctrl_lclick
+type = SLE_UINT8
+flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
+guiflags = SGF_MULTISTRING
+def = 1
+min = 0
+max = 6
+interval = 1
+str = STR_CONFIG_SETTING_CTRL_GOTOSHORTCUT_CTRLLCLICK
+strval = STR_CONFIG_SETTING_CTRL_GOTOSHORTOPTS_NONE
+proc = RedrawScreen
+cat = SC_BASIC
+
+[SDTC_VAR]
+var = gui.goto_shortcuts_shift_lclick
+type = SLE_UINT8
+flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
+guiflags = SGF_MULTISTRING
+def = 0
+min = 0
+max = 6
+interval = 1
+str = STR_CONFIG_SETTING_CTRL_GOTOSHORTCUT_SHIFTLCLICK
+strval = STR_CONFIG_SETTING_CTRL_GOTOSHORTOPTS_NONE
+proc = RedrawScreen
+cat = SC_BASIC
+
+[SDTC_VAR]
+var = gui.goto_shortcuts_ctrlshift_lclick
+type = SLE_UINT8
+flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
+guiflags = SGF_MULTISTRING
+def = 0
+min = 0
+max = 6
+interval = 1
+str = STR_CONFIG_SETTING_CTRL_GOTOSHORTCUT_CTRLSHIFTLCLICK
+strval = STR_CONFIG_SETTING_CTRL_GOTOSHORTOPTS_NONE
+proc = RedrawScreen
+cat = SC_BASIC
+
+[SDTC_VAR]
+var = gui.goto_shortcuts_alt_lclick
+type = SLE_UINT8
+flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
+guiflags = SGF_MULTISTRING
+def = 0
+min = 0
+max = 6
+interval = 1
+str = STR_CONFIG_SETTING_CTRL_GOTOSHORTCUT_ALTLCLICK
+strval = STR_CONFIG_SETTING_CTRL_GOTOSHORTOPTS_NONE
+proc = RedrawScreen
+cat = SC_BASIC
+
+[SDTC_VAR]
+var = gui.goto_shortcuts_altshift_lclick
+type = SLE_UINT8
+flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
+guiflags = SGF_MULTISTRING
+def = 0
+min = 0
+max = 6
+interval = 1
+str = STR_CONFIG_SETTING_CTRL_GOTOSHORTCUT_ALTSHIFTCLICK
+strval = STR_CONFIG_SETTING_CTRL_GOTOSHORTOPTS_NONE
+proc = RedrawScreen
+cat = SC_BASIC
+
+[SDTC_VAR]
+var = gui.goto_shortcuts_altctrl_lclick
+type = SLE_UINT8
+flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
+guiflags = SGF_MULTISTRING
+def = 0
+min = 0
+max = 6
+interval = 1
+str = STR_CONFIG_SETTING_CTRL_GOTOSHORTCUT_CTRLALTLCLICK
+strval = STR_CONFIG_SETTING_CTRL_GOTOSHORTOPTS_NONE
+proc = RedrawScreen
+cat = SC_BASIC
+
+[SDTC_BOOL]
+var = gui.old_depot_train_length_calc
+flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
+def = true
+str = STR_OLD_DEPOT_TRAINT_LENGTH
+
+[SDTC_VAR]
+var = gui.cb_distance_check
+type = SLE_UINT8
+flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
+def = 25
+min = 0
+max = 100
+interval = 5
+str = STR_CB_DISTANCE_CHECK
+strval = STR_JUST_COMMA
+proc = RedrawScreen
+
+[SDTC_BOOL]
+var = gui.enable_extra_tooltips
+flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
+def = true
+str = STR_CONFIG_SETTING_ENABLE_EXTRA_TOOLTIPS
+
+[SDTC_BOOL]
+var = gui.polyrail_double_click
+flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
+def = false
+str = STR_CONFIG_SETTING_POLYRAIL_DOUBLECLICK_TOOLTIPS
+
[SDT_END]
diff --git a/src/table/sprites.h b/src/table/sprites.h
index c296abdbcf..311f3f493a 100644
--- a/src/table/sprites.h
+++ b/src/table/sprites.h
@@ -296,8 +296,22 @@ static const uint16 EMPTY_BOUNDING_BOX_SPRITE_COUNT = 1;
static const SpriteID SPR_PALETTE_BASE = SPR_EMPTY_BOUNDING_BOX + EMPTY_BOUNDING_BOX_SPRITE_COUNT;
static const uint16 PALETTE_SPRITE_COUNT = 1;
+/* zoning stuff */
+static const SpriteID SPR_INNER_HIGHLIGHT_BASE = SPR_PALETTE_BASE + PALETTE_SPRITE_COUNT;
+static const SpriteID SPR_IMG_COMPANY_CARGO = SPR_INNER_HIGHLIGHT_BASE + 19;
+static const SpriteID SPR_IMG_COMPANY_GOAL = SPR_INNER_HIGHLIGHT_BASE + 20;
+static const SpriteID SPR_PALETTE_ZONING_RED = SPR_INNER_HIGHLIGHT_BASE + 21;
+static const SpriteID SPR_PALETTE_ZONING_GREEN = SPR_INNER_HIGHLIGHT_BASE + 22;
+static const SpriteID SPR_PALETTE_ZONING_BLACK = SPR_INNER_HIGHLIGHT_BASE + 23;
+static const SpriteID SPR_PALETTE_ZONING_LIGHT_BLUE = SPR_INNER_HIGHLIGHT_BASE + 24;
+static const SpriteID SPR_PALETTE_ZONING_ORANGE = SPR_INNER_HIGHLIGHT_BASE + 25;
+static const SpriteID SPR_PALETTE_ZONING_WHITE = SPR_INNER_HIGHLIGHT_BASE + 26;
+static const SpriteID SPR_PALETTE_ZONING_YELLOW = SPR_INNER_HIGHLIGHT_BASE + 27;
+static const SpriteID SPR_PALETTE_ZONING_PURPLE = SPR_INNER_HIGHLIGHT_BASE + 28;
+static const SpriteID SPR_INNER_HIGHLIGHT_COUNT = 29;
+
/* From where can we start putting NewGRFs? */
-static const SpriteID SPR_NEWGRFS_BASE = SPR_PALETTE_BASE + PALETTE_SPRITE_COUNT;
+static const SpriteID SPR_NEWGRFS_BASE = SPR_INNER_HIGHLIGHT_BASE + SPR_INNER_HIGHLIGHT_COUNT;
/* Manager face sprites */
static const SpriteID SPR_GRADIENT = 874; // background gradient behind manager face
diff --git a/src/tile_cmd.h b/src/tile_cmd.h
index db9287a02c..b06b504f41 100644
--- a/src/tile_cmd.h
+++ b/src/tile_cmd.h
@@ -64,6 +64,7 @@ struct TileDesc {
uint64 dparam[2]; ///< Parameters of the \a str string
uint16 rail_speed; ///< Speed limit of rail (bridges and track)
uint16 road_speed; ///< Speed limit of road (bridges)
+ uint16 population;
};
/**
diff --git a/src/tilehighlight_func.h b/src/tilehighlight_func.h
index f4d2c42059..4789426c76 100644
--- a/src/tilehighlight_func.h
+++ b/src/tilehighlight_func.h
@@ -14,6 +14,7 @@
#include "gfx_type.h"
#include "tilehighlight_type.h"
+#include "track_type.h"
void PlaceProc_DemolishArea(TileIndex tile);
bool GUIPlaceProcDragXY(ViewportDragDropSelectionProcess proc, TileIndex start_tile, TileIndex end_tile);
@@ -30,6 +31,9 @@ void VpSetPlaceSizingLimit(int limit);
void UpdateTileSelection();
+void StoreRailPlacementEndpoints(TileIndex start_tile, TileIndex end_tile, Track start_track, bool bidirectional = true);
+void ClearRailPlacementEndpoints();
+
extern TileHighlightData _thd;
#endif /* TILEHIGHLIGHT_FUNC_H */
diff --git a/src/tilehighlight_type.h b/src/tilehighlight_type.h
index 8b765a5153..49f38479fa 100644
--- a/src/tilehighlight_type.h
+++ b/src/tilehighlight_type.h
@@ -28,6 +28,7 @@ enum HighLightStyle {
HT_RAIL = 0x080, ///< autorail (one piece), lower bits: direction
HT_VEHICLE = 0x100, ///< vehicle is accepted as target as well (bitmask)
HT_DIAGONAL = 0x200, ///< Also allow 'diagonal rectangles'. Only usable in combination with #HT_RECT or #HT_POINT.
+ HT_POLY = 0x400, ///< polyline mode; connect highlighted track with previous one
HT_DRAG_MASK = 0x0F8, ///< Mask for the tile drag-type modes.
/* lower bits (used with HT_LINE and HT_RAIL):
@@ -54,11 +55,15 @@ struct TileHighlightData {
Point new_pos; ///< New value for \a pos; used to determine whether to redraw the selection.
Point new_size; ///< New value for \a size; used to determine whether to redraw the selection.
+ Point new_offs; ///< New value for \a offs; used to determine whether to redraw the selection.
Point new_outersize; ///< New value for \a outersize; used to determine whether to redraw the selection.
byte dirty; ///< Whether the build station window needs to redraw due to the changed selection.
Point selstart; ///< The location where the dragging started.
Point selend; ///< The location where the drag currently ends.
+ Point selstart2; ///< The location where the second segment of a polyline track starts.
+ Point selend2; ///< The location where the second segment of a polyline track ends.
+ HighLightStyle dir2; ///< Direction of the second segment of a polyline track, HT_DIR_END if second segment is not selected.
byte sizelimit; ///< Whether the selection is limited in length, and what the maximum length is.
HighLightStyle drawstyle; ///< Lower bits 0-3 are reserved for detailed highlight information.
diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp
index 44f7271e71..ca7de1070b 100644
--- a/src/toolbar_gui.cpp
+++ b/src/toolbar_gui.cpp
@@ -53,6 +53,10 @@
#include "network/network.h"
#include "network/network_gui.h"
#include "network/network_func.h"
+#include "cargo_table_gui.h"
+#include "object_type.h"
+#include "zoning.h"
+#include "watch_gui.h"
#include "safeguards.h"
@@ -77,11 +81,12 @@ enum CallBackFunction {
CBF_NONE,
CBF_PLACE_SIGN,
CBF_PLACE_LANDINFO,
+ CBF_BUILD_HQ,
};
/**
* Drop down list entry for showing a checked/unchecked toggle item.
- */
+ */ /*
class DropDownListCheckedItem : public DropDownListStringItem {
uint checkmark_width;
public:
@@ -107,18 +112,20 @@ public:
}
DrawString(left + WD_FRAMERECT_LEFT + (rtl ? 0 : this->checkmark_width), right - WD_FRAMERECT_RIGHT - (rtl ? this->checkmark_width : 0), top, this->String(), sel ? TC_WHITE : TC_BLACK);
}
-};
+};*/
/**
* Drop down list entry for showing a company entry, with companies 'blob'.
*/
class DropDownListCompanyItem : public DropDownListItem {
Dimension icon_size;
+ uint lockwidth;
public:
bool greyed;
DropDownListCompanyItem(int result, bool masked, bool greyed) : DropDownListItem(result, masked), greyed(greyed)
{
+ this->lockwidth = _networking ? GetSpriteSize(SPR_LOCK).width + 3 : 0;
this->icon_size = GetSpriteSize(SPR_COMPANY_ICON);
}
@@ -134,7 +141,7 @@ public:
CompanyID company = (CompanyID)this->result;
SetDParam(0, company);
SetDParam(1, company);
- return GetStringBoundingBox(STR_COMPANY_NAME_COMPANY_NUM).width + this->icon_size.width + 3;
+ return GetStringBoundingBox(STR_COMPANY_NAME_COMPANY_NUM).width + this->icon_size.width + this->lockwidth + 3;
}
uint Height(uint width) const
@@ -154,6 +161,10 @@ public:
int text_offset = (bottom - top - FONT_HEIGHT_NORMAL) / 2;
DrawCompanyIcon(company, rtl ? right - this->icon_size.width - WD_FRAMERECT_RIGHT : left + WD_FRAMERECT_LEFT, top + icon_offset);
+ if (_networking && NetworkCompanyIsPassworded(company)){
+ DrawSprite(SPR_LOCK, PAL_NONE, rtl ? right - this->icon_size.width - this->lockwidth - WD_FRAMERECT_RIGHT : left + WD_FRAMERECT_LEFT + 3 + this->icon_size.width, top + text_offset);
+ //DrawSprite(SPR_LOCK, PAL_NONE, left + WD_FRAMERECT_LEFT + 3 + this->icon_size.width, top + text_offset);
+ }
SetDParam(0, company);
SetDParam(1, company);
@@ -163,7 +174,9 @@ public:
} else {
col = sel ? TC_WHITE : TC_BLACK;
}
- DrawString(left + WD_FRAMERECT_LEFT + (rtl ? 0 : 3 + this->icon_size.width), right - WD_FRAMERECT_RIGHT - (rtl ? 3 + this->icon_size.width : 0), top + text_offset, STR_COMPANY_NAME_COMPANY_NUM, col);
+ int text_x_ofs = 3 + this->icon_size.width + this->lockwidth;
+ DrawString(left + WD_FRAMERECT_LEFT + (rtl ? 0 : text_x_ofs), right - WD_FRAMERECT_RIGHT - (rtl ? text_x_ofs : 0), top + text_offset, STR_COMPANY_NAME_COMPANY_NUM, col);
+ //DrawString(left + WD_FRAMERECT_LEFT + (rtl ? 0 : 3 + this->icon_size.width + this->lockwidth), right - WD_FRAMERECT_RIGHT - (rtl ? 3 + this->icon_size.width : 0), top + text_offset, STR_COMPANY_NAME_COMPANY_NUM, col);
}
};
@@ -256,6 +269,18 @@ static CallBackFunction SelectSignTool()
}
}
+/* hq hotkey */
+static CallBackFunction BuildCompanyHQ(){
+ if (_cursor.sprite == SPR_CURSOR_HQ) {
+ ResetObjectToPlace();
+ return CBF_NONE;
+ } else {
+ SetObjectToPlace(SPR_CURSOR_HQ, PAL_NONE, HT_RECT, WC_MAIN_TOOLBAR, 0);
+ SetTileSelectSize(2, 2);
+ return CBF_BUILD_HQ;
+ }
+}
+
/* --- Pausing --- */
static CallBackFunction ToolbarPauseClick(Window *w)
@@ -289,6 +314,7 @@ enum OptionMenuEntries {
OME_SETTINGS,
OME_SCRIPT_SETTINGS,
OME_NEWGRFSETTINGS,
+ OME_ZONING,
OME_TRANSPARENCIES,
OME_SHOW_TOWNNAMES,
OME_SHOW_STATIONNAMES,
@@ -317,6 +343,7 @@ static CallBackFunction ToolbarOptionsClick(Window *w)
* to network clients. */
if (!_networking || _network_server) *list->Append() = new DropDownListStringItem(STR_SETTINGS_MENU_SCRIPT_SETTINGS, OME_SCRIPT_SETTINGS, false);
*list->Append() = new DropDownListStringItem(STR_SETTINGS_MENU_NEWGRF_SETTINGS, OME_NEWGRFSETTINGS, false);
+ *list->Append() = new DropDownListStringItem(STR_SETTINGS_MENU_ZONING, OME_ZONING, false);
*list->Append() = new DropDownListStringItem(STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS, OME_TRANSPARENCIES, false);
*list->Append() = new DropDownListItem(-1, false);
*list->Append() = new DropDownListCheckedItem(STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED, OME_SHOW_TOWNNAMES, false, HasBit(_display_opt, DO_SHOW_TOWN_NAMES));
@@ -347,6 +374,7 @@ static CallBackFunction MenuClickSettings(int index)
case OME_SETTINGS: ShowGameSettings(); return CBF_NONE;
case OME_SCRIPT_SETTINGS: ShowAIConfigWindow(); return CBF_NONE;
case OME_NEWGRFSETTINGS: ShowNewGRFSettings(!_networking && _settings_client.gui.UserIsAllowedToChangeNewGRFs(), true, true, &_grfconfig); return CBF_NONE;
+ case OME_ZONING: ShowZoningToolbar(); break;
case OME_TRANSPARENCIES: ShowTransparencyToolbar(); break;
case OME_SHOW_TOWNNAMES: ToggleBit(_display_opt, DO_SHOW_TOWN_NAMES); break;
@@ -582,6 +610,37 @@ static CallBackFunction MenuClickFinances(int index)
return CBF_NONE;
}
+/* --- CARGOS button menu --- */
+
+static CallBackFunction ToolbarCargosClick(Window *w)
+{
+ PopupMainCompanyToolbMenu(w, WID_TN_CARGOS);
+ return CBF_NONE;
+}
+
+static CallBackFunction MenuClickCargos(int index)
+{
+ ShowCompanyCargos((CompanyID)index);
+ return CBF_NONE;
+}
+
+/* --- WATCH button menu --- */
+
+static CallBackFunction ToolbarWatchClick(Window *w)
+{
+ PopupMainCompanyToolbMenu(w, WID_TN_WATCH);
+ return CBF_NONE;
+}
+
+static CallBackFunction MenuClickWatch(int index)
+{
+ if(Company::IsValidID((CompanyID)index)){
+ ShowWatchWindow((CompanyID)index, 0);
+ }
+ else ShowWatchWindow(INVALID_COMPANY, 0);
+ return CBF_NONE;
+}
+
/* --- Company's button menu --- */
static CallBackFunction ToolbarCompaniesClick(Window *w)
@@ -1042,7 +1101,7 @@ static CallBackFunction PlaceLandBlockInfo()
static CallBackFunction ToolbarHelpClick(Window *w)
{
- PopupMainToolbMenu(w, WID_TN_HELP, STR_ABOUT_MENU_LAND_BLOCK_INFO, _settings_client.gui.newgrf_developer_tools ? 12 : 9);
+ PopupMainToolbMenu(w, WID_TN_HELP, STR_ABOUT_MENU_LAND_BLOCK_INFO, _settings_client.gui.newgrf_developer_tools ? 13 : 9);
return CBF_NONE;
}
@@ -1137,7 +1196,13 @@ void SetStartingYear(Year year)
static CallBackFunction MenuClickHelp(int index)
{
switch (index) {
- case 0: return PlaceLandBlockInfo();
+ case 0: return PlaceLandBlockInfo();
+ case 1:
+ extern bool _novahost;
+ if (_networking && _novahost){
+ ShowCommandsToolbar();
+ }
+ break;
case 2: IConsoleSwitch(); break;
case 3: ShowAIDebugWindow(); break;
case 4: MenuClickSmallScreenshot(); break;
@@ -1148,6 +1213,7 @@ static CallBackFunction MenuClickHelp(int index)
case 9: ShowSpriteAlignerWindow(); break;
case 10: ToggleBoundingBoxes(); break;
case 11: ToggleDirtyBlocks(); break;
+ case 12: ShowLoginWindow(); break;
}
return CBF_NONE;
}
@@ -1281,9 +1347,11 @@ static MenuClickedProc * const _menu_clicked_procs[] = {
MenuClickSubsidies, // 6
MenuClickStations, // 7
MenuClickFinances, // 8
+ MenuClickCargos, // 8.5
MenuClickCompany, // 9
MenuClickStory, // 10
MenuClickGoal, // 11
+ MenuClickWatch, // 11.5
MenuClickGraphs, // 12
MenuClickLeague, // 13
MenuClickIndustry, // 14
@@ -1495,7 +1563,7 @@ class NWidgetMainToolbarContainer : public NWidgetToolbarContainer {
0, 1, 3, 4, 7, 8, 9, 12, 14, 27, 21, 22, 23, 24, 25, 10, 28, 19, 20, 29,
};
static const byte arrange_all[] = {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30
};
/* If at least BIGGEST_ARRANGEMENT fit, just spread all the buttons nicely */
@@ -1537,14 +1605,14 @@ class NWidgetScenarioToolbarContainer : public NWidgetToolbarContainer {
/* virtual */ const byte *GetButtonArrangement(uint &width, uint &arrangable_count, uint &button_count, uint &spacer_count) const
{
static const byte arrange_all[] = {
- 0, 1, 2, 3, 4, 18, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 26, 28,
+ 0, 1, 2, 3, 4, 18, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 28, 30,
};
static const byte arrange_nopanel[] = {
- 0, 1, 2, 3, 18, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 26, 28,
+ 0, 1, 2, 3, 18, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 28, 30,
};
static const byte arrange_switch[] = {
- 18, 8, 11, 12, 13, 14, 15, 16, 17, 29,
- 0, 1, 2, 3, 18, 9, 10, 26, 28, 29,
+ 18, 8, 11, 12, 13, 14, 15, 16, 17, 31,
+ 0, 1, 2, 3, 18, 9, 10, 28, 30, 31,
};
/* If we can place all buttons *and* the panels, show them. */
@@ -1590,9 +1658,11 @@ static ToolbarButtonProc * const _toolbar_button_procs[] = {
ToolbarSubsidiesClick,
ToolbarStationsClick,
ToolbarFinancesClick,
+ ToolbarCargosClick,
ToolbarCompaniesClick,
ToolbarStoryClick,
ToolbarGoalClick,
+ ToolbarWatchClick,
ToolbarGraphsClick,
ToolbarLeagueClick,
ToolbarIndustryClick,
@@ -1652,6 +1722,14 @@ enum MainToolbarHotkeys {
MTHK_EXTRA_VIEWPORT,
MTHK_CLIENT_LIST,
MTHK_SIGN_LIST,
+ MTHK_BUILD_HQ,
+ MTHK_COMMANDS_GUI,
+ MTHK_CARGOTABLE,
+ MTHK_TREES,
+ MTHK_ZONING,
+ MTHK_LOGINWINDOW,
+ MTHK_SETTINGS_ADV,
+ MTHK_NEWGRF,
};
/** Main toolbar. */
@@ -1682,7 +1760,7 @@ struct MainToolbarWindow : Window {
* Since enabled state is the default, just disable when needed */
this->SetWidgetsDisabledState(_local_company == COMPANY_SPECTATOR, WID_TN_RAILS, WID_TN_ROADS, WID_TN_WATER, WID_TN_AIR, WID_TN_LANDSCAPE, WIDGET_LIST_END);
/* disable company list drop downs, if there are no companies */
- this->SetWidgetsDisabledState(Company::GetNumItems() == 0, WID_TN_STATIONS, WID_TN_FINANCES, WID_TN_TRAINS, WID_TN_ROADVEHS, WID_TN_SHIPS, WID_TN_AIRCRAFTS, WIDGET_LIST_END);
+ this->SetWidgetsDisabledState(Company::GetNumItems() == 0, WID_TN_STATIONS, WID_TN_FINANCES, WID_TN_CARGOS, WID_TN_WATCH, WID_TN_TRAINS, WID_TN_ROADVEHS, WID_TN_SHIPS, WID_TN_AIRCRAFTS, WIDGET_LIST_END);
this->SetWidgetDisabledState(WID_TN_GOAL, Goal::GetNumItems() == 0);
this->SetWidgetDisabledState(WID_TN_STORY, StoryPage::GetNumItems() == 0);
@@ -1745,13 +1823,39 @@ struct MainToolbarWindow : Window {
case MTHK_EXTRA_VIEWPORT: ShowExtraViewPortWindowForTileUnderCursor(); break;
#ifdef ENABLE_NETWORK
case MTHK_CLIENT_LIST: if (_networking) ShowClientList(); break;
+ case MTHK_COMMANDS_GUI: extern bool _novahost; if (_networking && _novahost){ ShowCommandsToolbar(); } break;
#endif
+ case MTHK_BUILD_HQ: if(_current_company != COMPANY_SPECTATOR){ this->last_started_action = CBF_BUILD_HQ; BuildCompanyHQ(); } break;
+ case MTHK_CARGOTABLE: if(_current_company != COMPANY_SPECTATOR){ ShowCompanyCargos(_current_company); } break;
+ case MTHK_TREES: if(_current_company != COMPANY_SPECTATOR){ BuildTreesWindow(); } break;
case MTHK_SIGN_LIST: ShowSignList(); break;
+ case MTHK_ZONING: ShowZoningToolbar(); break;
+ case MTHK_LOGINWINDOW: ShowLoginWindow(); break;
+ case MTHK_SETTINGS_ADV: ShowGameSettings(); break;
+ case MTHK_NEWGRF: ShowNewGRFSettings(!_networking && _settings_client.gui.UserIsAllowedToChangeNewGRFs(), true, true, &_grfconfig); break;
default: return ES_NOT_HANDLED;
}
return ES_HANDLED;
}
+ virtual void BuildTreesWindow(){
+ ShowBuildTreesToolbar();
+ Window *w = FindWindowById(WC_BUILD_TREES, 0);
+ if(w != NULL){
+ if(w->IsWidgetLowered(WID_BT_TYPE_RANDOM)){
+ w->RaiseWidget(WID_BT_TYPE_RANDOM);
+ ResetObjectToPlace();
+ }
+ else{
+ w->OnHotkey(WID_BT_TYPE_RANDOM);
+ }
+
+ }
+ /*
+ if (!w->IsWidgetLowered(WID_BT_TYPE_RANDOM))
+ w->OnClick(Point(), WID_BT_TYPE_RANDOM, 1);*/
+ }
+
virtual void OnPlaceObject(Point pt, TileIndex tile)
{
switch (this->last_started_action) {
@@ -1763,6 +1867,13 @@ struct MainToolbarWindow : Window {
ShowLandInfo(tile);
break;
+ case CBF_BUILD_HQ:
+ if(DoCommandP(tile, OBJECT_HQ, 0, CMD_BUILD_OBJECT | CMD_MSG(STR_ERROR_CAN_T_BUILD_COMPANY_HEADQUARTERS))){
+ ResetObjectToPlace();
+ this->RaiseButtons();
+ }
+ break;
+
default: NOT_REACHED();
}
}
@@ -1850,7 +1961,15 @@ static Hotkey maintoolbar_hotkeys[] = {
Hotkey('V', "extra_viewport", MTHK_EXTRA_VIEWPORT),
#ifdef ENABLE_NETWORK
Hotkey((uint16)0, "client_list", MTHK_CLIENT_LIST),
+ Hotkey('N', "nova_commands", MTHK_COMMANDS_GUI),
+ Hotkey(WKC_CTRL | WKC_F2, "cargo_table", MTHK_CARGOTABLE),
#endif
+ Hotkey(WKC_CTRL | 'H', "build_hq", MTHK_BUILD_HQ),
+ Hotkey('I', "trees", MTHK_TREES),
+ Hotkey((uint16)0, "zoning", MTHK_ZONING),
+ Hotkey((uint16)0, "login_window", MTHK_LOGINWINDOW),
+ Hotkey((uint16)0, "settings_advanced", MTHK_SETTINGS_ADV),
+ Hotkey((uint16)0, "newgrf_window", MTHK_NEWGRF),
Hotkey((uint16)0, "sign_list", MTHK_SIGN_LIST),
HOTKEY_LIST_END
};
@@ -1869,9 +1988,11 @@ static NWidgetBase *MakeMainToolbar(int *biggest_index)
SPR_IMG_SUBSIDIES, // WID_TN_SUBSIDIES
SPR_IMG_COMPANY_LIST, // WID_TN_STATIONS
SPR_IMG_COMPANY_FINANCE, // WID_TN_FINANCES
+ SPR_IMG_COMPANY_CARGO, // WID_TN_CARGOS
SPR_IMG_COMPANY_GENERAL, // WID_TN_COMPANIES
SPR_IMG_STORY_BOOK, // WID_TN_STORY
SPR_IMG_GOAL, // WID_TN_GOAL
+ SPR_CENTRE_VIEW_VEHICLE, // WID_TN_WATCH
SPR_IMG_GRAPHS, // WID_TN_GRAPHS
SPR_IMG_COMPANY_LEAGUE, // WID_TN_LEAGUE
SPR_IMG_INDUSTRY, // WID_TN_INDUSTRIES
@@ -1895,7 +2016,7 @@ static NWidgetBase *MakeMainToolbar(int *biggest_index)
NWidgetMainToolbarContainer *hor = new NWidgetMainToolbarContainer();
for (uint i = 0; i < WID_TN_END; i++) {
switch (i) {
- case 4: case 8: case 15: case 19: case 21: case 26: hor->Add(new NWidgetSpacer(0, 0)); break;
+ case 4: case 8: case 17: case 21: case 23: case 28: hor->Add(new NWidgetSpacer(0, 0)); break;
}
hor->Add(new NWidgetLeaf(i == WID_TN_SAVE ? WWT_IMGBTN_2 : WWT_IMGBTN, COLOUR_GREY, i, toolbar_button_sprites[i], STR_TOOLBAR_TOOLTIP_PAUSE_GAME + i));
}
diff --git a/src/town.h b/src/town.h
index 0d580d6db5..eb2ac9db4d 100644
--- a/src/town.h
+++ b/src/town.h
@@ -15,10 +15,14 @@
#include "viewport_type.h"
#include "town_map.h"
#include "subsidy_type.h"
+#include "openttd.h"
+#include "table/strings.h"
+#include "company_func.h"
#include "newgrf_storage.h"
#include "cargotype.h"
#include "tilematrix_type.hpp"
#include
+#include