(svn r12712) [NoAI] -Sync with trunk r12672:12711.
--- a/projects/openttd_vs80.vcproj Mon Apr 14 16:24:00 2008 +0000
+++ b/projects/openttd_vs80.vcproj Mon Apr 14 21:21:10 2008 +0000
@@ -800,6 +800,10 @@
>
</File>
<File
+ RelativePath=".\..\src\core\alloc_type.hpp"
+ >
+ </File>
+ <File
RelativePath=".\..\src\articulated_vehicles.h"
>
</File>
--- a/projects/openttd_vs90.vcproj Mon Apr 14 16:24:00 2008 +0000
+++ b/projects/openttd_vs90.vcproj Mon Apr 14 21:21:10 2008 +0000
@@ -797,6 +797,10 @@
>
</File>
<File
+ RelativePath=".\..\src\core\alloc_type.hpp"
+ >
+ </File>
+ <File
RelativePath=".\..\src\articulated_vehicles.h"
>
</File>
--- a/source.list Mon Apr 14 16:24:00 2008 +0000
+++ b/source.list Mon Apr 14 21:21:10 2008 +0000
@@ -121,6 +121,7 @@
airport.h
airport_movement.h
core/alloc_func.hpp
+core/alloc_type.hpp
articulated_vehicles.h
autoreplace_base.h
autoreplace_func.h
--- a/src/ai/api/ai_order.hpp Mon Apr 14 16:24:00 2008 +0000
+++ b/src/ai/api/ai_order.hpp Mon Apr 14 21:21:10 2008 +0000
@@ -36,9 +36,9 @@
/** Just go to the station/depot, stop unload if possible and load if needed. */
AIOF_NONE = 0,
- /** Do not stop at the stations that are passed when going to the destination. */
+ /** Do not stop at the stations that are passed when going to the destination. Only for trains and road vehicles. */
AIOF_NON_STOP_INTERMEDIATE = 1 << 0,
- /** Do not stop at the destionation station. */
+ /** Do not stop at the destionation station. Only for trains and road vehicles. */
AIOF_NON_STOP_DESTINATION = 1 << 1,
/** Always unload the vehicle; only for stations. Cannot be set when AIOF_TRANSFER or AIOF_NO_UNLOAD is set. */
--- a/src/airport_gui.cpp Mon Apr 14 16:24:00 2008 +0000
+++ b/src/airport_gui.cpp Mon Apr 14 21:21:10 2008 +0000
@@ -144,13 +144,30 @@
if (_patches.link_terraform_toolbar) ShowTerraformToolbar(w);
}
+enum {
+ BAW_BOTTOMPANEL = 10,
+ BAW_SMALL_AIRPORT,
+ BAW_CITY_AIRPORT,
+ BAW_HELIPORT,
+ BAW_METRO_AIRPORT,
+ BAW_STR_INTERNATIONAL_AIRPORT,
+ BAW_COMMUTER_AIRPORT,
+ BAW_HELIDEPOT,
+ BAW_STR_INTERCONTINENTAL_AIRPORT,
+ BAW_HELISTATION,
+ BAW_LAST_AIRPORT = BAW_HELISTATION,
+ BAW_AIRPORT_COUNT = BAW_LAST_AIRPORT - BAW_SMALL_AIRPORT,
+ BAW_BTN_DONTHILIGHT = BAW_LAST_AIRPORT + 1,
+ BAW_BTN_DOHILIGHT,
+};
+
static void BuildAirportPickerWndProc(Window *w, WindowEvent *e)
{
switch (e->event) {
case WE_CREATE:
- w->SetWidgetLoweredState(16, !_station_show_coverage);
- w->SetWidgetLoweredState(17, _station_show_coverage);
- w->LowerWidget(_selected_airport_type + 7);
+ w->SetWidgetLoweredState(BAW_BTN_DONTHILIGHT, !_station_show_coverage);
+ w->SetWidgetLoweredState(BAW_BTN_DOHILIGHT, _station_show_coverage);
+ w->LowerWidget(_selected_airport_type + BAW_SMALL_AIRPORT);
break;
case WE_PAINT: {
@@ -162,18 +179,18 @@
avail_airports = GetValidAirports();
- w->RaiseWidget(_selected_airport_type + 7);
+ w->RaiseWidget(_selected_airport_type + BAW_SMALL_AIRPORT);
if (!HasBit(avail_airports, 0) && _selected_airport_type == AT_SMALL) _selected_airport_type = AT_LARGE;
if (!HasBit(avail_airports, 1) && _selected_airport_type == AT_LARGE) _selected_airport_type = AT_SMALL;
- w->LowerWidget(_selected_airport_type + 7);
+ w->LowerWidget(_selected_airport_type + BAW_SMALL_AIRPORT);
- /* 'Country Airport' starts at widget 7, and if its bit is set, it is
+ /* 'Country Airport' starts at widget BAW_SMALL_AIRPORT, and if its bit is set, it is
* available, so take its opposite value to set the disabled state.
* There are 9 buildable airports
* XXX TODO : all airports should be held in arrays, with all relevant data.
* This should be part of newgrf-airports, i suppose
*/
- for (i = 0; i < 9; i++) w->SetWidgetDisabledState(i + 7, !HasBit(avail_airports, i));
+ for (i = 0; i < BAW_AIRPORT_COUNT; i++) w->SetWidgetDisabledState(i + BAW_SMALL_AIRPORT, !HasBit(avail_airports, i));
/* select default the coverage area to 'Off' (16) */
airport = GetAirport(_selected_airport_type);
@@ -187,9 +204,9 @@
/* strings such as 'Size' and 'Coverage Area' */
int text_end = DrawStationCoverageAreaText(2, 206, SCT_ALL, rad, false);
text_end = DrawStationCoverageAreaText(2, text_end + 4, SCT_ALL, rad, true) + 4;
- if (text_end != w->widget[6].bottom) {
+ if (text_end != w->widget[BAW_BOTTOMPANEL].bottom) {
SetWindowDirty(w);
- ResizeWindowForWidget(w, 6, 0, text_end - w->widget[6].bottom);
+ ResizeWindowForWidget(w, BAW_BOTTOMPANEL, 0, text_end - w->widget[BAW_BOTTOMPANEL].bottom);
SetWindowDirty(w);
}
break;
@@ -197,18 +214,20 @@
case WE_CLICK: {
switch (e->we.click.widget) {
- case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15:
- w->RaiseWidget(_selected_airport_type + 7);
- _selected_airport_type = e->we.click.widget - 7;
- w->LowerWidget(_selected_airport_type + 7);
+ case BAW_SMALL_AIRPORT: case BAW_CITY_AIRPORT: case BAW_HELIPORT: case BAW_METRO_AIRPORT:
+ case BAW_STR_INTERNATIONAL_AIRPORT: case BAW_COMMUTER_AIRPORT: case BAW_HELIDEPOT:
+ case BAW_STR_INTERCONTINENTAL_AIRPORT: case BAW_HELISTATION:
+ w->RaiseWidget(_selected_airport_type + BAW_SMALL_AIRPORT);
+ _selected_airport_type = e->we.click.widget - BAW_SMALL_AIRPORT;
+ w->LowerWidget(_selected_airport_type + BAW_SMALL_AIRPORT);
SndPlayFx(SND_15_BEEP);
SetWindowDirty(w);
break;
- case 16: case 17:
- _station_show_coverage = (e->we.click.widget != 16);
- w->SetWidgetLoweredState(16, !_station_show_coverage);
- w->SetWidgetLoweredState(17, _station_show_coverage);
+ case BAW_BTN_DONTHILIGHT: case BAW_BTN_DOHILIGHT:
+ _station_show_coverage = (e->we.click.widget != BAW_BTN_DONTHILIGHT);
+ w->SetWidgetLoweredState(BAW_BTN_DONTHILIGHT, !_station_show_coverage);
+ w->SetWidgetLoweredState(BAW_BTN_DOHILIGHT, _station_show_coverage);
SndPlayFx(SND_15_BEEP);
SetWindowDirty(w);
break;
@@ -234,10 +253,14 @@
{ WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
{ WWT_CAPTION, RESIZE_NONE, 7, 11, 147, 0, 13, STR_3001_AIRPORT_SELECTION, STR_018C_WINDOW_TITLE_DRAG_THIS},
{ WWT_PANEL, RESIZE_NONE, 7, 0, 147, 14, 52, 0x0, STR_NULL},
+{ WWT_LABEL, RESIZE_NONE, 7, 0, 147, 14, 27, STR_SMALL_AIRPORTS, STR_NULL},
{ WWT_PANEL, RESIZE_NONE, 7, 0, 147, 53, 89, 0x0, STR_NULL},
+{ WWT_LABEL, RESIZE_NONE, 7, 0, 147, 52, 65, STR_LARGE_AIRPORTS, STR_NULL},
{ WWT_PANEL, RESIZE_NONE, 7, 0, 147, 90, 127, 0x0, STR_NULL},
+{ WWT_LABEL, RESIZE_NONE, 7, 0, 147, 90, 103, STR_HUB_AIRPORTS, STR_NULL},
{ WWT_PANEL, RESIZE_NONE, 7, 0, 147, 128, 177, 0x0, STR_NULL},
-{ WWT_PANEL, RESIZE_NONE, 7, 0, 147, 178, 239, 0x0, STR_NULL},
+{ WWT_LABEL, RESIZE_NONE, 7, 0, 147, 128, 141, STR_HELIPORTS, STR_NULL},
+{ WWT_PANEL, RESIZE_NONE, 7, 0, 147, 178, 239, 0x0, STR_NULL}, // bottom general box
{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 145, 27, 38, STR_SMALL_AIRPORT, STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT},
{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 145, 65, 76, STR_CITY_AIRPORT, STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT},
{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 145, 141, 152, STR_HELIPORT, STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT},
@@ -249,10 +272,6 @@
{ WWT_TEXTBTN, RESIZE_NONE, 14, 2, 145, 153, 164, STR_HELISTATION, STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT},
{ WWT_TEXTBTN, RESIZE_NONE, 14, 14, 73, 191, 202, STR_02DB_OFF, STR_3065_DON_T_HIGHLIGHT_COVERAGE},
{ WWT_TEXTBTN, RESIZE_NONE, 14, 74, 133, 191, 202, STR_02DA_ON, STR_3064_HIGHLIGHT_COVERAGE_AREA},
-{ WWT_LABEL, RESIZE_NONE, 7, 0, 147, 14, 27, STR_SMALL_AIRPORTS, STR_NULL},
-{ WWT_LABEL, RESIZE_NONE, 7, 0, 147, 52, 65, STR_LARGE_AIRPORTS, STR_NULL},
-{ WWT_LABEL, RESIZE_NONE, 7, 0, 147, 90, 103, STR_HUB_AIRPORTS, STR_NULL},
-{ WWT_LABEL, RESIZE_NONE, 7, 0, 147, 128, 141, STR_HELIPORTS, STR_NULL},
{ WWT_LABEL, RESIZE_NONE, 7, 0, 147, 178, 191, STR_3066_COVERAGE_AREA_HIGHLIGHT, STR_NULL},
{ WIDGETS_END},
};
--- a/src/core/alloc_func.hpp Mon Apr 14 16:24:00 2008 +0000
+++ b/src/core/alloc_func.hpp Mon Apr 14 21:21:10 2008 +0000
@@ -90,56 +90,4 @@
return t_ptr;
}
-/**
- * A small 'wrapper' for allocations that can be done on most OSes on the
- * stack, but are just too large to fit in the stack on devices with a small
- * stack such as the NDS.
- * So when it is possible a stack allocation is made, otherwise a heap
- * allocation is made and this is freed once the struct goes out of scope.
- * @param T the type to make the allocation for
- * @param length the amount of items to allocate
- */
-template <typename T, size_t length>
-struct SmallStackSafeStackAlloc {
-#if !defined(__NDS__)
- /** Storing the data on the stack */
- T data[length];
-#else
- /** Storing it on the heap */
- T *data;
- /** The length (in elements) of data in this allocator. */
- size_t len;
-
- /** Allocating the memory */
- SmallStackSafeStackAlloc() : data(MallocT<T>(length)), len(length) {}
- /** And freeing when it goes out of scope */
- ~SmallStackSafeStackAlloc() { free(data); }
-#endif
-
- /**
- * Gets a pointer to the data stored in this wrapper.
- * @return the pointer.
- */
- inline operator T* () { return data; }
-
- /**
- * Gets a pointer to the data stored in this wrapper.
- * @return the pointer.
- */
- inline T* operator -> () { return data; }
-
- /**
- * Gets a pointer to the last data element stored in this wrapper.
- * @note needed because endof does not work properly for pointers.
- * @return the 'endof' pointer.
- */
- inline T* EndOf() {
-#if !defined(__NDS__)
- return endof(data);
-#else
- return &data[len];
-#endif
- }
-};
-
#endif /* ALLOC_FUNC_HPP */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/alloc_type.hpp Mon Apr 14 21:21:10 2008 +0000
@@ -0,0 +1,102 @@
+
+/* $Id$ */
+
+/** @file alloc_type.hpp Helper types related to the allocation of memory */
+
+#ifndef ALLOC_TYPE_HPP
+#define ALLOC_TYPE_HPP
+
+#include "alloc_func.hpp"
+
+/**
+ * A small 'wrapper' for allocations that can be done on most OSes on the
+ * stack, but are just too large to fit in the stack on devices with a small
+ * stack such as the NDS.
+ * So when it is possible a stack allocation is made, otherwise a heap
+ * allocation is made and this is freed once the struct goes out of scope.
+ * @param T the type to make the allocation for
+ * @param length the amount of items to allocate
+ */
+template <typename T, size_t length>
+struct SmallStackSafeStackAlloc {
+#if !defined(__NDS__)
+ /** Storing the data on the stack */
+ T data[length];
+#else
+ /** Storing it on the heap */
+ T *data;
+ /** The length (in elements) of data in this allocator. */
+ size_t len;
+
+ /** Allocating the memory */
+ SmallStackSafeStackAlloc() : data(MallocT<T>(length)), len(length) {}
+ /** And freeing when it goes out of scope */
+ ~SmallStackSafeStackAlloc() { free(data); }
+#endif
+
+ /**
+ * Gets a pointer to the data stored in this wrapper.
+ * @return the pointer.
+ */
+ inline operator T* () { return data; }
+
+ /**
+ * Gets a pointer to the data stored in this wrapper.
+ * @return the pointer.
+ */
+ inline T* operator -> () { return data; }
+
+ /**
+ * Gets a pointer to the last data element stored in this wrapper.
+ * @note needed because endof does not work properly for pointers.
+ * @return the 'endof' pointer.
+ */
+ inline T* EndOf() {
+#if !defined(__NDS__)
+ return endof(data);
+#else
+ return &data[len];
+#endif
+ }
+};
+
+/**
+ * Base class that provides memory initialization on dynamically created objects.
+ * All allocated memory will be zeroed.
+ */
+class ZeroedMemoryAllocator
+{
+public:
+ ZeroedMemoryAllocator() {}
+ virtual ~ZeroedMemoryAllocator() {}
+
+ /**
+ * Memory allocator for a single class instance.
+ * @param size the amount of bytes to allocate.
+ * @return the given amounts of bytes zeroed.
+ */
+ void *operator new(size_t size) { return CallocT<byte>(size); }
+
+ /**
+ * Memory allocator for an array of class instances.
+ * @param size the amount of bytes to allocate.
+ * @return the given amounts of bytes zeroed.
+ */
+ void *operator new[](size_t size) { return CallocT<byte>(size); }
+
+ /**
+ * Memory release for a single class instance.
+ * @param ptr the memory to free.
+ * @param size the amount of allocated memory (unused).
+ */
+ void operator delete(void *ptr, size_t size) { free(ptr); }
+
+ /**
+ * Memory release for an array of class instances.
+ * @param ptr the memory to free.
+ * @param size the amount of allocated memory (unused).
+ */
+ void operator delete[](void *ptr, size_t size) { free(ptr); }
+};
+
+#endif /* ALLOC_TYPE_HPP */
--- a/src/debug.h Mon Apr 14 16:24:00 2008 +0000
+++ b/src/debug.h Mon Apr 14 21:21:10 2008 +0000
@@ -103,7 +103,13 @@
#ifdef DEBUG_DUMP_COMMANDS
void CDECL DebugDumpCommands(const char *s, ...);
#else /* DEBUG_DUMP_COMMANDS */
- static inline void DebugDumpCommands(const char *s, ...) {}
+ /* when defined as an empty function with variable argument list,
+ * it can't be inlined - so define it as an empty macro */
+ #if defined(__GNUC__) && (__GNUC__ < 3)
+ #define DebugDumpCommands(s, args...)
+ #else
+ #define DebugDumpCommands(s, ...)
+ #endif
#endif /* DEBUG_DUMP_COMMANDS */
#endif /* DEBUG_H */
--- a/src/lang/english.txt Mon Apr 14 16:24:00 2008 +0000
+++ b/src/lang/english.txt Mon Apr 14 21:21:10 2008 +0000
@@ -1364,6 +1364,8 @@
STR_NETWORK_GAME_NAME_TIP :{BLACK}Name of the game
STR_NETWORK_INFO_ICONS_TIP :{BLACK}Language, server version, etc.
STR_NETWORK_CLICK_GAME_TO_SELECT :{BLACK}Click a game from the list to select it
+STR_NETWORK_LAST_JOINED_SERVER :{BLACK}The server you joined last time:
+STR_NETWORK_CLICK_TO_SELECT_LAST :{BLACK}Click to select the server you played last time
STR_NETWORK_FIND_SERVER :{BLACK}Find server
STR_NETWORK_FIND_SERVER_TIP :{BLACK}Search network for a server
@@ -2724,7 +2726,6 @@
STR_CONDITIONAL_NUM :Jump to order {COMMA} when {STRING} {STRING} {COMMA}
STR_CONDITIONAL_TRUE_FALSE :Jump to order {COMMA} when {STRING} {STRING}
-STR_TIMETABLE_GO_TO :{STRING4} {STRING2}
STR_TIMETABLE_TRAVEL_NOT_TIMETABLED :Travel (not timetabled)
STR_TIMETABLE_TRAVEL_FOR :Travel for {STRING1}
STR_TIMETABLE_STAY_FOR :and stay for {STRING1}
@@ -2781,6 +2782,7 @@
STR_882D_VALUE :{LTBLUE}{ENGINE}{BLACK} Value: {LTBLUE}{CURRENCY}
STR_882E :{WHITE}{VEHICLE}
STR_882F_LOADING_UNLOADING :{LTBLUE}Loading / Unloading
+STR_LEAVING :{LTBLUE}Leaving
STR_TRAIN_MUST_BE_STOPPED :{WHITE}Train must be stopped inside a depot
STR_8830_CAN_T_SEND_TRAIN_TO_DEPOT :{WHITE}Can't send train to depot...
STR_8831_NO_MORE_SPACE_FOR_ORDERS :{WHITE}No more space for orders
--- a/src/misc.cpp Mon Apr 14 16:24:00 2008 +0000
+++ b/src/misc.cpp Mon Apr 14 21:21:10 2008 +0000
@@ -24,7 +24,7 @@
#include "texteff.hpp"
#include "string_func.h"
#include "gfx_func.h"
-#include "core/alloc_func.hpp"
+#include "core/alloc_type.hpp"
#include "settings_type.h"
#include "table/strings.h"
--- a/src/misc_gui.cpp Mon Apr 14 16:24:00 2008 +0000
+++ b/src/misc_gui.cpp Mon Apr 14 21:21:10 2008 +0000
@@ -778,7 +778,7 @@
case SCT_ALL: break;
default: NOT_REACHED();
}
- if (cargo[i] >= (supplies ? 1 : 8)) {
+ if (cargo[i] >= (supplies ? 1U : 8U)) {
if (first) {
first = false;
} else {
--- a/src/network/network_gamelist.cpp Mon Apr 14 16:24:00 2008 +0000
+++ b/src/network/network_gamelist.cpp Mon Apr 14 21:21:10 2008 +0000
@@ -25,6 +25,8 @@
* @return a point to the newly added or already existing item */
NetworkGameList *NetworkGameListAddItem(uint32 ip, uint16 port)
{
+ if (ip == 0) return NULL;
+
NetworkGameList *item, *prev_item;
prev_item = NULL;
--- a/src/network/network_gui.cpp Mon Apr 14 16:24:00 2008 +0000
+++ b/src/network/network_gui.cpp Mon Apr 14 21:21:10 2008 +0000
@@ -218,28 +218,69 @@
/** Enum for NetworkGameWindow, referring to _network_game_window_widgets */
enum NetworkGameWindowWidgets {
- NGWW_CLOSE = 0, ///< Close 'X' button
- NGWW_CONN_BTN = 4, ///< 'Connection' droplist button
- NGWW_PLAYER = 5, ///< Panel with editbox to set player name
+ NGWW_CLOSE, ///< Close 'X' button
+ NGWW_CAPTION, ///< Caption of the window
+ NGWW_RESIZE, ///< Resize button
- NGWW_NAME = 6, ///< 'Name' button
+ NGWW_CONNECTION, ///< Label in from of connection droplist
+ NGWW_CONN_BTN, ///< 'Connection' droplist button
+ NGWW_PLAYER, ///< Panel with editbox to set player name
+
+ NGWW_NAME, ///< 'Name' button
NGWW_CLIENTS, ///< 'Clients' button
NGWW_INFO, ///< Third button in the game list panel
- NGWW_MATRIX = 9, ///< Panel with list of games
+ NGWW_MATRIX, ///< Panel with list of games
+ NGWW_SCROLLBAR, ///< Scrollbar of matrix
- NGWW_DETAILS = 11, ///< Panel with game details
- NGWW_JOIN = 12, ///< 'Join game' button
- NGWW_REFRESH = 13, ///< 'Refresh server' button
- NGWW_NEWGRF = 14, ///< 'NewGRF Settings' button
+ NGWW_LASTJOINED_LABEL, ///< Label "Last joined server:"
+ NGWW_LASTJOINED, ///< Info about the last joined server
- NGWW_FIND = 15, ///< 'Find server' button
+ NGWW_DETAILS, ///< Panel with game details
+ NGWW_JOIN, ///< 'Join game' button
+ NGWW_REFRESH, ///< 'Refresh server' button
+ NGWW_NEWGRF, ///< 'NewGRF Settings' button
+
+ NGWW_FIND, ///< 'Find server' button
NGWW_ADD, ///< 'Add server' button
NGWW_START, ///< 'Start server' button
NGWW_CANCEL, ///< 'Cancel' button
};
/**
+ * Draw a single server line.
+ * @param cur_item the server to draw.
+ * @param y from where to draw?
+ * @param highlight does the line need to be highlighted?
+ */
+static void DrawServerLine(const Window *w, const NetworkGameList *cur_item, uint y, bool highlight)
+{
+ /* show highlighted item with a different colour */
+ if (highlight) GfxFillRect(w->widget[NGWW_NAME].left + 1, y - 2, w->widget[NGWW_INFO].right - 1, y + 9, 10);
+
+ SetDParamStr(0, cur_item->info.server_name);
+ DrawStringTruncated(w->widget[NGWW_NAME].left + 5, y, STR_02BD, TC_BLACK, w->widget[NGWW_NAME].right - w->widget[NGWW_NAME].left - 5);
+
+ SetDParam(0, cur_item->info.clients_on);
+ SetDParam(1, cur_item->info.clients_max);
+ SetDParam(2, cur_item->info.companies_on);
+ SetDParam(3, cur_item->info.companies_max);
+ DrawStringCentered(w->widget[NGWW_CLIENTS].left + 39, y, STR_NETWORK_GENERAL_ONLINE, TC_GOLD);
+
+ /* only draw icons if the server is online */
+ if (cur_item->online) {
+ /* draw a lock if the server is password protected */
+ if (cur_item->info.use_password) DrawSprite(SPR_LOCK, PAL_NONE, w->widget[NGWW_INFO].left + 5, y - 1);
+
+ /* draw red or green icon, depending on compatibility with server */
+ DrawSprite(SPR_BLOT, (cur_item->info.compatible ? PALETTE_TO_GREEN : (cur_item->info.version_compatible ? PALETTE_TO_YELLOW : PALETTE_TO_RED)), w->widget[NGWW_INFO].left + 15, y);
+
+ /* draw flag according to server language */
+ DrawSprite(SPR_FLAGS_BASE + cur_item->info.server_lang, PAL_NONE, w->widget[NGWW_INFO].left + 25, y);
+ }
+}
+
+/**
* Handler of actions done in the NetworkStartServer window
*
* @param w pointer to the Window structure
@@ -256,7 +297,7 @@
switch (e->event) {
case WE_CREATE: // Focus input box
- w->vscroll.cap = 13;
+ w->vscroll.cap = 11;
w->resize.step_height = NET_PRC__SIZE_OF_ROW;
nd->field = NGWW_PLAYER;
@@ -309,7 +350,6 @@
uint16 y = NET_PRC__OFFSET_TOP_WIDGET + 3;
int32 n = 0;
int32 pos = w->vscroll.pos;
- uint max_name_width = w->widget[NGWW_NAME].right - w->widget[NGWW_NAME].left - 5;
const NetworkGameList *cur_item = _network_game_list;
while (pos > 0 && cur_item != NULL) {
@@ -318,35 +358,17 @@
}
while (cur_item != NULL) {
- /* show highlighted item with a different colour */
- if (cur_item == sel) GfxFillRect(w->widget[NGWW_NAME].left + 1, y - 2, w->widget[NGWW_INFO].right - 1, y + 9, 10);
-
- SetDParamStr(0, cur_item->info.server_name);
- DrawStringTruncated(w->widget[NGWW_NAME].left + 5, y, STR_02BD, TC_BLACK, max_name_width);
-
- SetDParam(0, cur_item->info.clients_on);
- SetDParam(1, cur_item->info.clients_max);
- SetDParam(2, cur_item->info.companies_on);
- SetDParam(3, cur_item->info.companies_max);
- DrawStringCentered(w->widget[NGWW_CLIENTS].left + 39, y, STR_NETWORK_GENERAL_ONLINE, TC_GOLD);
-
- /* only draw icons if the server is online */
- if (cur_item->online) {
- /* draw a lock if the server is password protected */
- if (cur_item->info.use_password) DrawSprite(SPR_LOCK, PAL_NONE, w->widget[NGWW_INFO].left + 5, y - 1);
-
- /* draw red or green icon, depending on compatibility with server */
- DrawSprite(SPR_BLOT, (cur_item->info.compatible ? PALETTE_TO_GREEN : (cur_item->info.version_compatible ? PALETTE_TO_YELLOW : PALETTE_TO_RED)), w->widget[NGWW_INFO].left + 15, y);
-
- /* draw flag according to server language */
- DrawSprite(SPR_FLAGS_BASE + cur_item->info.server_lang, PAL_NONE, w->widget[NGWW_INFO].left + 25, y);
- }
+ DrawServerLine(w, cur_item, y, cur_item == sel);
cur_item = cur_item->next;
y += NET_PRC__SIZE_OF_ROW;
if (++n == w->vscroll.cap) break; // max number of games in the window
}
+ const NetworkGameList *last_joined = NetworkGameListAddItem(inet_addr(_network_last_host), _network_last_port);
+ /* Draw the last joined server, if any */
+ if (last_joined != NULL) DrawServerLine(w, last_joined, y = w->widget[NGWW_LASTJOINED].top + 3, last_joined == sel);
+
/* Draw the right menu */
GfxFillRect(w->widget[NGWW_DETAILS].left + 1, 43, w->widget[NGWW_DETAILS].right - 1, 92, 157);
if (sel == NULL) {
@@ -462,6 +484,14 @@
SetWindowDirty(w);
} break;
+ case NGWW_LASTJOINED: {
+ NetworkGameList *last_joined = NetworkGameListAddItem(inet_addr(_network_last_host), _network_last_port);
+ if (last_joined != NULL) {
+ nd->server = last_joined;
+ SetWindowDirty(w);
+ }
+ } break;
+
case NGWW_FIND: // Find server automatically
switch (_network_lan_internet) {
case 0: NetworkUDPSearchGame(); break;
@@ -579,10 +609,10 @@
static const Widget _network_game_window_widgets[] = {
/* TOP */
{ WWT_CLOSEBOX, RESIZE_NONE, BGC, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, // NGWW_CLOSE
-{ WWT_CAPTION, RESIZE_RIGHT, BGC, 11, 449, 0, 13, STR_NETWORK_MULTIPLAYER, STR_NULL},
-{ WWT_PANEL, RESIZE_RB, BGC, 0, 449, 14, 263, 0x0, STR_NULL},
+{ WWT_CAPTION, RESIZE_RIGHT, BGC, 11, 449, 0, 13, STR_NETWORK_MULTIPLAYER, STR_NULL}, // NGWW_CAPTION
+{ WWT_PANEL, RESIZE_RB, BGC, 0, 449, 14, 263, 0x0, STR_NULL}, // NGWW_RESIZE
-{ WWT_TEXT, RESIZE_NONE, BGC, 9, 85, 23, 35, STR_NETWORK_CONNECTION, STR_NULL},
+{ WWT_TEXT, RESIZE_NONE, BGC, 9, 85, 23, 35, STR_NETWORK_CONNECTION, STR_NULL}, // NGWW_CONNECTION
{ WWT_DROPDOWNIN, RESIZE_NONE, BGC, 90, 181, 22, 33, STR_NETWORK_LAN_INTERNET_COMBO, STR_NETWORK_CONNECTION_TIP}, // NGWW_CONN_BTN
{ WWT_EDITBOX, RESIZE_LR, BGC, 290, 440, 22, 33, STR_NETWORK_PLAYER_NAME_OSKTITLE, STR_NETWORK_ENTER_NAME_TIP}, // NGWW_PLAYER
@@ -592,8 +622,10 @@
{ WWT_PUSHTXTBTN, RESIZE_LR, BTC, 71, 150, 42, 53, STR_NETWORK_CLIENTS_CAPTION, STR_NETWORK_CLIENTS_CAPTION_TIP}, // NGWW_CLIENTS
{ WWT_PUSHTXTBTN, RESIZE_LR, BTC, 151, 190, 42, 53, STR_EMPTY, STR_NETWORK_INFO_ICONS_TIP}, // NGWW_INFO
-{ WWT_MATRIX, RESIZE_RB, BGC, 10, 190, 54, 236, (13 << 8) + 1, STR_NETWORK_CLICK_GAME_TO_SELECT}, // NGWW_MATRIX
-{ WWT_SCROLLBAR, RESIZE_LRB, BGC, 191, 202, 42, 236, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
+{ WWT_MATRIX, RESIZE_RB, BGC, 10, 190, 54, 208, (11 << 8) + 1, STR_NETWORK_CLICK_GAME_TO_SELECT}, // NGWW_MATRIX
+{ WWT_SCROLLBAR, RESIZE_LRB, BGC, 191, 202, 42, 208, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST}, // NGWW_SCROLLBAR
+{ WWT_TEXT, RESIZE_RTB, BGC, 10, 190, 211, 222, STR_NETWORK_LAST_JOINED_SERVER, STR_NULL}, // NGWW_LASTJOINED_LABEL
+{ WWT_PANEL, RESIZE_RTB, BGC, 10, 190, 223, 236, 0x0, STR_NETWORK_CLICK_TO_SELECT_LAST}, // NGWW_LASTJOINED
/* RIGHT SIDE */
{ WWT_PANEL, RESIZE_LRB, BGC, 210, 440, 42, 236, 0x0, STR_NULL}, // NGWW_DETAILS
--- a/src/newgrf_station.cpp Mon Apr 14 16:24:00 2008 +0000
+++ b/src/newgrf_station.cpp Mon Apr 14 21:21:10 2008 +0000
@@ -754,7 +754,7 @@
const RailtypeInfo *rti = GetRailTypeInfo(railtype);
SpriteID relocation;
SpriteID image;
- SpriteID pal = PLAYER_SPRITE_COLOR(_local_player);
+ SpriteID palette = PLAYER_SPRITE_COLOR(_local_player);
uint tile = 2;
statspec = GetCustomStationSpec(sclass, station);
@@ -792,6 +792,17 @@
image += relocation;
}
+ SpriteID pal;
+ if (HasBit(image, PALETTE_MODIFIER_TRANSPARENT) || HasBit(image, PALETTE_MODIFIER_COLOR)) {
+ if (seq->image.pal > 0) {
+ pal = seq->image.pal;
+ } else {
+ pal = palette;
+ }
+ } else {
+ pal = PAL_NONE;
+ }
+
if ((byte)seq->delta_z != 0x80) {
pt = RemapCoords(seq->delta_x, seq->delta_y, seq->delta_z);
DrawSprite(image, pal, x + pt.x, y + pt.y);
--- a/src/news_gui.cpp Mon Apr 14 16:24:00 2008 +0000
+++ b/src/news_gui.cpp Mon Apr 14 21:21:10 2008 +0000
@@ -998,6 +998,7 @@
if (_total_news == 0) {
assert(_latest_news == _oldest_news);
_latest_news = INVALID_NEWS;
+ _current_news = INVALID_NEWS;
}
/* Since we only imitate a FIFO removing an arbitrary element does need
--- a/src/news_type.h Mon Apr 14 16:24:00 2008 +0000
+++ b/src/news_type.h Mon Apr 14 21:21:10 2008 +0000
@@ -66,12 +66,13 @@
/**
* Kinds of bankrupcy
+ * @note These flags are or'd with player index
*/
enum NewsBankrupcy {
- NB_BTROUBLE, ///< Company is in trouble (warning)
- NB_BMERGER, ///< Company has been bought by another company
- NB_BBANKRUPT, ///< Company has gone bankrupt
- NB_BNEWCOMPANY, ///< A new company has been started
+ NB_BTROUBLE = (1 << 4), ///< Company is in trouble (warning)
+ NB_BMERGER = (2 << 4), ///< Company has been bought by another company
+ NB_BBANKRUPT = (3 << 4), ///< Company has gone bankrupt
+ NB_BNEWCOMPANY = (4 << 4), ///< A new company has been started
};
struct NewsItem {
--- a/src/openttd.cpp Mon Apr 14 16:24:00 2008 +0000
+++ b/src/openttd.cpp Mon Apr 14 21:21:10 2008 +0000
@@ -2311,6 +2311,40 @@
}
}
+
+ if (CheckSavegameVersion(93)) {
+ /* Rework of orders. */
+ Order *order;
+ FOR_ALL_ORDERS(order) order->ConvertFromOldSavegame();
+
+ Vehicle *v;
+ FOR_ALL_VEHICLES(v) {
+ if (v->orders != NULL && !v->orders->IsValid()) v->orders = NULL;
+
+ v->current_order.ConvertFromOldSavegame();
+ if (v->type == VEH_ROAD && v->IsPrimaryVehicle() && v->prev_shared == NULL) {
+ FOR_VEHICLE_ORDERS(v, order) order->SetNonStopType(ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
+ }
+ }
+ } else if (CheckSavegameVersion(94)) {
+ /* Unload and transfer are now mutual exclusive. */
+ Order *order;
+ FOR_ALL_ORDERS(order) {
+ if ((order->GetUnloadType() & (OUFB_UNLOAD | OUFB_TRANSFER)) == (OUFB_UNLOAD | OUFB_TRANSFER)) {
+ order->SetUnloadType(OUFB_TRANSFER);
+ order->SetLoadType(OLFB_NO_LOAD);
+ }
+ }
+
+ Vehicle *v;
+ FOR_ALL_VEHICLES(v) {
+ if ((v->current_order.GetUnloadType() & (OUFB_UNLOAD | OUFB_TRANSFER)) == (OUFB_UNLOAD | OUFB_TRANSFER)) {
+ v->current_order.SetUnloadType(OUFB_TRANSFER);
+ v->current_order.SetLoadType(OLFB_NO_LOAD);
+ }
+ }
+ }
+
if (CheckSavegameVersion(84)) {
/* Update go to buoy orders because they are just waypoints */
Order *order;
@@ -2455,32 +2489,6 @@
}
}
- if (CheckSavegameVersion(93)) {
- /* Rework of orders. */
- Order *order;
- FOR_ALL_ORDERS(order) order->ConvertFromOldSavegame();
-
- Vehicle *v;
- FOR_ALL_VEHICLES(v) v->current_order.ConvertFromOldSavegame();
- } else if (CheckSavegameVersion(94)) {
- /* Unload and transfer are now mutual exclusive. */
- Order *order;
- FOR_ALL_ORDERS(order) {
- if ((order->GetUnloadType() & (OUFB_UNLOAD | OUFB_TRANSFER)) == (OUFB_UNLOAD | OUFB_TRANSFER)) {
- order->SetUnloadType(OUFB_TRANSFER);
- order->SetLoadType(OLFB_NO_LOAD);
- }
- }
-
- Vehicle *v;
- FOR_ALL_VEHICLES(v) {
- if ((v->current_order.GetUnloadType() & (OUFB_UNLOAD | OUFB_TRANSFER)) == (OUFB_UNLOAD | OUFB_TRANSFER)) {
- v->current_order.SetUnloadType(OUFB_TRANSFER);
- v->current_order.SetLoadType(OLFB_NO_LOAD);
- }
- }
- }
-
return InitializeWindowsAndCaches();
}
--- a/src/order_cmd.cpp Mon Apr 14 16:24:00 2008 +0000
+++ b/src/order_cmd.cpp Mon Apr 14 21:21:10 2008 +0000
@@ -216,9 +216,7 @@
* Sanity check
* TTD stores invalid orders as OT_NOTHING with non-zero flags/station
*/
- if (!order.IsValid() && (order.GetLoadType() != 0 || order.GetUnloadType() != 0 || order.GetDestination() != 0)) {
- order.MakeDummy();
- }
+ if (!order.IsValid() && packed != 0) order.MakeDummy();
return order;
}
@@ -358,7 +356,7 @@
}
/* Non stop not allowed for non-trains. */
- if (new_order.GetNonStopType() != ONSF_STOP_EVERYWHERE && v->type != VEH_TRAIN) return CMD_ERROR;
+ if (new_order.GetNonStopType() != ONSF_STOP_EVERYWHERE && v->type != VEH_TRAIN && v->type != VEH_ROAD) return CMD_ERROR;
/* Full load and unload are mutual exclusive. */
if ((new_order.GetLoadType() & OLFB_FULL_LOAD) && (new_order.GetUnloadType() & OUFB_UNLOAD)) return CMD_ERROR;
@@ -412,7 +410,7 @@
if (!IsPlayerBuildableVehicleType(v)) return CMD_ERROR;
}
- if (new_order.GetNonStopType() != ONSF_STOP_EVERYWHERE && v->type != VEH_TRAIN) return CMD_ERROR;
+ if (new_order.GetNonStopType() != ONSF_STOP_EVERYWHERE && v->type != VEH_TRAIN && v->type != VEH_ROAD) return CMD_ERROR;
if (new_order.GetDepotOrderType() & ~ODTFB_PART_OF_ORDERS) return CMD_ERROR;
if (new_order.GetDepotActionType() & ~ODATFB_NEAREST_DEPOT) return CMD_ERROR;
break;
@@ -869,6 +867,7 @@
default: NOT_REACHED();
case MOF_NON_STOP:
+ if (v->type != VEH_TRAIN && v->type != VEH_ROAD) return CMD_ERROR;
if (data >= ONSF_END) return CMD_ERROR;
if (data == order->GetNonStopType()) return CMD_ERROR;
break;
@@ -1644,7 +1643,7 @@
}
/* If it is unchanged, keep it. */
- if (order->Equals(v->current_order) &&
+ if (order->Equals(v->current_order) && (v->type == VEH_AIRCRAFT || v->dest_tile != 0) &&
(v->type != VEH_SHIP || !order->IsType(OT_GOTO_STATION) || GetStation(order->GetDestination())->dock_tile != 0)) {
return false;
}
--- a/src/order_func.h Mon Apr 14 16:24:00 2008 +0000
+++ b/src/order_func.h Mon Apr 14 21:21:10 2008 +0000
@@ -37,6 +37,8 @@
void DeleteVehicleOrders(Vehicle *v);
bool ProcessOrders(Vehicle *v);
+void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int y, bool selected, bool timetable);
+
#define MIN_SERVINT_PERCENT 5
#define MAX_SERVINT_PERCENT 90
#define MIN_SERVINT_DAYS 30
--- a/src/order_gui.cpp Mon Apr 14 16:24:00 2008 +0000
+++ b/src/order_gui.cpp Mon Apr 14 21:21:10 2008 +0000
@@ -211,6 +211,105 @@
extern uint ConvertDisplaySpeedToSpeed(uint speed);
+void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int y, bool selected, bool timetable)
+{
+ StringID str = (v->cur_order_index == order_index) ? STR_8805 : STR_8804;
+ SetDParam(6, STR_EMPTY);
+
+ switch (order->GetType()) {
+ case OT_DUMMY:
+ SetDParam(1, STR_INVALID_ORDER);
+ SetDParam(2, order->GetDestination());
+ break;
+
+ case OT_GOTO_STATION: {
+ OrderLoadFlags load = order->GetLoadType();
+ OrderUnloadFlags unload = order->GetUnloadType();
+
+ SetDParam(1, STR_GO_TO_STATION);
+ SetDParam(2, STR_ORDER_GO_TO + ((v->type == VEH_TRAIN || v->type == VEH_ROAD) ? order->GetNonStopType() : 0));
+ SetDParam(3, order->GetDestination());
+
+ if (timetable) {
+ SetDParam(4, STR_EMPTY);
+
+ if (order->wait_time > 0) {
+ SetDParam(6, STR_TIMETABLE_STAY_FOR);
+ SetTimetableParams(7, 8, order->wait_time);
+ }
+ } else {
+ SetDParam(4, (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) ? STR_EMPTY : _station_load_types[unload][load]);
+ }
+ } break;
+
+ case OT_GOTO_DEPOT:
+ if (v->type == VEH_AIRCRAFT) {
+ if (order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) {
+ SetDParam(1, STR_GO_TO_NEAREST_DEPOT);
+ SetDParam(3, STR_ORDER_NEAREST_HANGAR);
+ } else {
+ SetDParam(1, STR_GO_TO_HANGAR);
+ SetDParam(3, order->GetDestination());
+ }
+ SetDParam(4, STR_EMPTY);
+ } else {
+ if (order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) {
+ SetDParam(1, STR_GO_TO_NEAREST_DEPOT);
+ SetDParam(3, STR_ORDER_NEAREST_DEPOT);
+ } else {
+ SetDParam(1, STR_GO_TO_DEPOT);
+ SetDParam(3, GetDepot(order->GetDestination())->town_index);
+ }
+
+ switch (v->type) {
+ case VEH_TRAIN: SetDParam(4, STR_ORDER_TRAIN_DEPOT); break;
+ case VEH_ROAD: SetDParam(4, STR_ORDER_ROAD_DEPOT); break;
+ case VEH_SHIP: SetDParam(4, STR_ORDER_SHIP_DEPOT); break;
+ default: NOT_REACHED();
+ }
+ }
+
+ if (order->GetDepotOrderType() & ODTFB_SERVICE) {
+ SetDParam(2, (order->GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS) ? STR_ORDER_SERVICE_NON_STOP_AT : STR_ORDER_SERVICE_AT);
+ } else {
+ SetDParam(2, (order->GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS) ? STR_ORDER_GO_NON_STOP_TO : STR_ORDER_GO_TO);
+ }
+
+ if (!timetable && order->IsRefit()) {
+ SetDParam(6, STR_REFIT_ORDER);
+ SetDParam(7, GetCargo(order->GetRefitCargo())->name);
+ }
+ break;
+
+ case OT_GOTO_WAYPOINT:
+ SetDParam(1, (order->GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS) ? STR_GO_NON_STOP_TO_WAYPOINT : STR_GO_TO_WAYPOINT);
+ SetDParam(2, order->GetDestination());
+ break;
+
+ case OT_CONDITIONAL:
+ SetDParam(2, order->GetConditionSkipToOrder() + 1);
+ if (order->GetConditionVariable() == OCV_UNCONDITIONALLY) {
+ SetDParam(1, STR_CONDITIONAL_UNCONDITIONAL);
+ } else {
+ OrderConditionComparator occ = order->GetConditionComparator();
+ SetDParam(1, (occ == OCC_IS_TRUE || occ == OCC_IS_FALSE) ? STR_CONDITIONAL_TRUE_FALSE : STR_CONDITIONAL_NUM);
+ SetDParam(3, STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE + order->GetConditionVariable());
+ SetDParam(4, STR_ORDER_CONDITIONAL_COMPARATOR_EQUALS + occ);
+
+ uint value = order->GetConditionValue();
+ if (order->GetConditionVariable() == OCV_MAX_SPEED) value = ConvertSpeedToDisplaySpeed(value);
+ SetDParam(5, value);
+ }
+ break;
+
+ default: NOT_REACHED();
+ }
+
+ SetDParam(0, order_index + 1);
+ DrawString(2, y, str, selected ? TC_WHITE : TC_BLACK);
+}
+
+
static void DrawOrdersWindow(Window *w)
{
const Vehicle *v = GetVehicle(w->window_number);
@@ -237,7 +336,7 @@
(uint)v->num_orders + ((shared_orders || v->num_orders != 0) ? 1 : 0) <= (uint)WP(w, order_d).sel);
/* non-stop only for trains */
- w->SetWidgetDisabledState(ORDER_WIDGET_NON_STOP, v->type != VEH_TRAIN || order == NULL);
+ w->SetWidgetDisabledState(ORDER_WIDGET_NON_STOP, (v->type != VEH_TRAIN && v->type != VEH_ROAD) || order == NULL);
w->SetWidgetDisabledState(ORDER_WIDGET_FULL_LOAD, order == NULL || (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) != 0); // full load
w->SetWidgetDisabledState(ORDER_WIDGET_UNLOAD, order == NULL || (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) != 0); // unload
/* Disable list of vehicles with the same shared orders if there is no list */
@@ -310,94 +409,11 @@
order = GetVehicleOrder(v, i);
StringID str;
while (order != NULL) {
- str = (v->cur_order_index == i) ? STR_8805 : STR_8804;
- SetDParam(6, STR_EMPTY);
-
- if (i - w->vscroll.pos < w->vscroll.cap) {
- switch (order->GetType()) {
- case OT_DUMMY:
- SetDParam(1, STR_INVALID_ORDER);
- SetDParam(2, order->GetDestination());
- break;
-
- case OT_GOTO_STATION: {
- OrderLoadFlags load = order->GetLoadType();
- OrderUnloadFlags unload = order->GetUnloadType();
-
- SetDParam(1, STR_GO_TO_STATION);
- SetDParam(2, STR_ORDER_GO_TO + (v->type == VEH_TRAIN ? order->GetNonStopType() : 0));
- SetDParam(3, order->GetDestination());
- SetDParam(4, (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) ? STR_EMPTY : _station_load_types[unload][load]);
- } break;
-
- case OT_GOTO_DEPOT:
- if (v->type == VEH_AIRCRAFT) {
- if (order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) {
- SetDParam(1, STR_GO_TO_NEAREST_DEPOT);
- SetDParam(3, STR_ORDER_NEAREST_HANGAR);
- } else {
- SetDParam(1, STR_GO_TO_HANGAR);
- SetDParam(3, order->GetDestination());
- }
- SetDParam(4, STR_EMPTY);
- } else {
- if (order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) {
- SetDParam(1, STR_GO_TO_NEAREST_DEPOT);
- SetDParam(3, STR_ORDER_NEAREST_DEPOT);
- } else {
- SetDParam(1, STR_GO_TO_DEPOT);
- SetDParam(3, GetDepot(order->GetDestination())->town_index);
- }
+ /* Don't draw anything if it extends past the end of the window. */
+ if (i - w->vscroll.pos >= w->vscroll.cap) break;
- switch (v->type) {
- case VEH_TRAIN: SetDParam(4, STR_ORDER_TRAIN_DEPOT); break;
- case VEH_ROAD: SetDParam(4, STR_ORDER_ROAD_DEPOT); break;
- case VEH_SHIP: SetDParam(4, STR_ORDER_SHIP_DEPOT); break;
- default: NOT_REACHED();
- }
- }
-
- if (order->GetDepotOrderType() & ODTFB_SERVICE) {
- SetDParam(2, (order->GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS) ? STR_ORDER_SERVICE_NON_STOP_AT : STR_ORDER_SERVICE_AT);
- } else {
- SetDParam(2, (order->GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS) ? STR_ORDER_GO_NON_STOP_TO : STR_ORDER_GO_TO);
- }
-
- if (order->IsRefit()) {
- SetDParam(6, STR_REFIT_ORDER);
- SetDParam(7, GetCargo(order->GetRefitCargo())->name);
- }
- break;
-
- case OT_GOTO_WAYPOINT:
- SetDParam(1, (order->GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS) ? STR_GO_NON_STOP_TO_WAYPOINT : STR_GO_TO_WAYPOINT);
- SetDParam(2, order->GetDestination());
- break;
-
- case OT_CONDITIONAL:
- SetDParam(2, order->GetConditionSkipToOrder() + 1);
- if (order->GetConditionVariable() == OCV_UNCONDITIONALLY) {
- SetDParam(1, STR_CONDITIONAL_UNCONDITIONAL);
- } else {
- OrderConditionComparator occ = order->GetConditionComparator();
- SetDParam(1, (occ == OCC_IS_TRUE || occ == OCC_IS_FALSE) ? STR_CONDITIONAL_TRUE_FALSE : STR_CONDITIONAL_NUM);
- SetDParam(3, STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE + order->GetConditionVariable());
- SetDParam(4, STR_ORDER_CONDITIONAL_COMPARATOR_EQUALS + occ);
-
- uint value = order->GetConditionValue();
- if (order->GetConditionVariable() == OCV_MAX_SPEED) value = ConvertSpeedToDisplaySpeed(value);
- SetDParam(5, value);
- }
- break;
-
- default: NOT_REACHED();
- }
-
- SetDParam(0, i + 1);
- DrawString(2, y, str, (i == WP(w, order_d).sel) ? TC_WHITE : TC_BLACK);
-
- y += 10;
- }
+ DrawOrderString(v, order, i, y, i == WP(w, order_d).sel, false);
+ y += 10;
i++;
order = order->next;
@@ -422,6 +438,7 @@
if (v->type == VEH_TRAIN && IsTileOwner(tile, _local_player)) {
if (IsRailDepot(tile)) {
order.MakeGoToDepot(GetDepotByTile(tile)->index, ODTFB_PART_OF_ORDERS);
+ if (_patches.new_nonstop) order.SetNonStopType(ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
return order;
}
}
@@ -430,6 +447,7 @@
case MP_ROAD:
if (IsRoadDepot(tile) && v->type == VEH_ROAD && IsTileOwner(tile, _local_player)) {
order.MakeGoToDepot(GetDepotByTile(tile)->index, ODTFB_PART_OF_ORDERS);
+ if (_patches.new_nonstop) order.SetNonStopType(ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
return order;
}
break;
@@ -463,6 +481,7 @@
IsTileOwner(tile, _local_player) &&
IsRailWaypoint(tile)) {
order.MakeGoToWaypoint(GetWaypointByTile(tile)->index);
+ if (_patches.new_nonstop) order.SetNonStopType(ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
return order;
}
@@ -479,7 +498,7 @@
(facil = FACIL_TRUCK_STOP, 1);
if (st->facilities & facil) {
order.MakeGoToStation(st_index);
- if (_patches.new_nonstop && v->type == VEH_TRAIN) order.SetNonStopType(ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
+ if (_patches.new_nonstop && (v->type == VEH_TRAIN || v->type == VEH_ROAD)) order.SetNonStopType(ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
return order;
}
}
@@ -1167,7 +1186,7 @@
if (v->owner != _local_player) {
w = AllocateWindowDescFront(&_other_orders_desc, veh);
} else {
- w = AllocateWindowDescFront((v->type == VEH_TRAIN) ? &_orders_train_desc : &_orders_desc, veh);
+ w = AllocateWindowDescFront((v->type == VEH_TRAIN || v->type == VEH_ROAD) ? &_orders_train_desc : &_orders_desc, veh);
}
if (w != NULL) {
--- a/src/pathfind.cpp Mon Apr 14 16:24:00 2008 +0000
+++ b/src/pathfind.cpp Mon Apr 14 21:21:10 2008 +0000
@@ -17,7 +17,7 @@
#include "depot.h"
#include "tunnelbridge_map.h"
#include "core/random_func.hpp"
-#include "core/alloc_func.hpp"
+#include "core/alloc_type.hpp"
#include "tunnelbridge.h"
/* remember which tiles we have already visited so we don't visit them again. */
--- a/src/player_gui.cpp Mon Apr 14 16:24:00 2008 +0000
+++ b/src/player_gui.cpp Mon Apr 14 21:21:10 2008 +0000
@@ -29,6 +29,7 @@
#include "string_func.h"
#include "settings_type.h"
#include "widgets/dropdown_func.h"
+#include "widgets/dropdown_type.h"
#include "table/sprites.h"
#include "table/strings.h"
@@ -283,7 +284,6 @@
STR_00DE_BROWN,
STR_00DF_GREY,
STR_00E0_WHITE,
- INVALID_STRING_ID
};
/* Association of liveries to livery classes */
@@ -324,6 +324,29 @@
PLW_WIDGET_MATRIX,
};
+class DropDownListColourItem : public DropDownListItem {
+public:
+ DropDownListColourItem(int result, bool masked) : DropDownListItem(result, masked) {}
+
+ virtual ~DropDownListColourItem() {}
+
+ virtual StringID String() const
+ {
+ return _colour_dropdown[this->result];
+ }
+
+ virtual uint Height(uint width) const
+ {
+ return 14;
+ }
+
+ virtual void Draw(int x, int y, uint width, uint height, bool sel) const
+ {
+ DrawSprite(SPR_VEH_BUS_SIDE_VIEW, PALETTE_RECOLOR_START + this->result, x + 16, y + 7);
+ DrawStringTruncated(x + 32, y + 3, this->String(), sel ? TC_WHITE : TC_BLACK, x + width - 30);
+ }
+};
+
static void ShowColourDropDownMenu(Window *w, uint32 widget)
{
uint32 used_colours = 0;
@@ -345,7 +368,12 @@
if (scheme == LS_END) scheme = LS_DEFAULT;
livery = &GetPlayer((PlayerID)w->window_number)->livery[scheme];
- ShowDropDownMenu(w, _colour_dropdown, widget == PLW_WIDGET_PRI_COL_DROPDOWN ? livery->colour1 : livery->colour2, widget, used_colours, 0);
+ DropDownList *list = new DropDownList();
+ for (uint i = 0; i < lengthof(_colour_dropdown); i++) {
+ list->push_back(new DropDownListColourItem(i, HasBit(used_colours, i)));
+ }
+
+ ShowDropDownList(w, list, widget == PLW_WIDGET_PRI_COL_DROPDOWN ? livery->colour1 : livery->colour2, widget);
}
static void SelectPlayerLiveryWndProc(Window *w, WindowEvent *e)
--- a/src/road_cmd.cpp Mon Apr 14 16:24:00 2008 +0000
+++ b/src/road_cmd.cpp Mon Apr 14 21:21:10 2008 +0000
@@ -150,7 +150,7 @@
* @param rt roadtype to remove
* @param crossing_check should we check if there is a tram track when we are removing road from crossing?
*/
-static CommandCost RemoveRoad(TileIndex tile, uint32 flags, RoadBits pieces, RoadType rt, bool crossing_check)
+static CommandCost RemoveRoad(TileIndex tile, uint32 flags, RoadBits pieces, RoadType rt, bool crossing_check, bool town_check = true)
{
/* cost for removing inner/edge -roads */
static const uint16 road_remove_cost[2] = {50, 18};
@@ -188,7 +188,7 @@
/* check if you're allowed to remove the street owned by a town
* removal allowance depends on difficulty setting */
- if (!CheckforTownRating(flags, t, ROAD_REMOVE)) return CMD_ERROR;
+ if (town_check && !CheckforTownRating(flags, t, ROAD_REMOVE)) return CMD_ERROR;
if (!IsTileType(tile, MP_ROAD)) {
/* If it's the last roadtype, just clear the whole tile */
@@ -254,7 +254,7 @@
return CMD_ERROR;
}
- ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM);
+ if (town_check) ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM);
if (flags & DC_EXEC) {
if (present == ROAD_NONE) {
RoadTypes rts = GetRoadTypes(tile) & ComplementRoadTypes(RoadTypeToRoadTypes(rt));
@@ -291,7 +291,7 @@
if (rt == ROADTYPE_ROAD && HasTileRoadType(tile, ROADTYPE_TRAM) && (flags & DC_EXEC || crossing_check)) return CMD_ERROR;
if (rt == ROADTYPE_ROAD) {
- ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM);
+ if (town_check) ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM);
}
if (flags & DC_EXEC) {
@@ -768,7 +768,7 @@
_additional_cash_required = DoCommand(end_tile, start_tile, p2, flags & ~DC_EXEC, CMD_REMOVE_LONG_ROAD).GetCost();
return cost;
}
- RemoveRoad(tile, flags, bits, rt, true);
+ RemoveRoad(tile, flags, bits, rt, true, false);
}
cost.AddCost(ret);
}
--- a/src/roadveh_cmd.cpp Mon Apr 14 16:24:00 2008 +0000
+++ b/src/roadveh_cmd.cpp Mon Apr 14 21:21:10 2008 +0000
@@ -1711,7 +1711,7 @@
if (IsRoadVehFront(v) && ((IsInsideMM(v->u.road.state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END) &&
_road_veh_data_1[v->u.road.state - RVSB_IN_ROAD_STOP + (_opt.road_side << RVS_DRIVE_SIDE)] == v->u.road.frame) ||
(IsInsideMM(v->u.road.state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) &&
- v->current_order.GetDestination() == GetStationIndex(v->tile) &&
+ v->current_order.ShouldStopAtStation(v, GetStationIndex(v->tile)) &&
GetRoadStopType(v->tile) == (IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? ROADSTOP_BUS : ROADSTOP_TRUCK) &&
v->u.road.frame == RVC_DRIVE_THROUGH_STOP_FRAME))) {
@@ -1721,8 +1721,7 @@
/* Vehicle is at the stop position (at a bay) in a road stop.
* Note, if vehicle is loading/unloading it has already been handled,
* so if we get here the vehicle has just arrived or is just ready to leave. */
- if (!v->current_order.IsType(OT_LEAVESTATION) &&
- !v->current_order.IsType(OT_GOTO_DEPOT)) {
+ if (!v->current_order.IsType(OT_LEAVESTATION)) {
/* Vehicle has arrived at a bay in a road stop */
if (IsDriveThroughStopTile(v->tile)) {
@@ -1750,10 +1749,15 @@
rs->SetEntranceBusy(false);
- v->last_station_visited = GetStationIndex(v->tile);
+ v->last_station_visited = st->index;
- RoadVehArrivesAt(v, st);
- v->BeginLoading();
+ if (IsDriveThroughStopTile(v->tile) || v->current_order.GetDestination() == st->index) {
+ RoadVehArrivesAt(v, st);
+ v->BeginLoading();
+ } else {
+ v->current_order.MakeLeaveStation();
+ InvalidateVehicleOrder(v);
+ }
return false;
}
@@ -1809,6 +1813,8 @@
return false;
}
+ if (v->current_order.IsType(OT_LEAVESTATION) && IsDriveThroughStopTile(v->tile)) v->current_order.Free();
+
/* Move to next frame unless vehicle arrived at a stop position
* in a depot or entered a tunnel/bridge */
if (!HasBit(r, VETS_ENTERED_WORMHOLE)) v->u.road.frame++;
--- a/src/saveload.cpp Mon Apr 14 16:24:00 2008 +0000
+++ b/src/saveload.cpp Mon Apr 14 21:21:10 2008 +0000
@@ -76,13 +76,24 @@
enum NeedLengthValues {NL_NONE = 0, NL_WANTLENGTH = 1, NL_CALCLENGTH = 2};
+/** Error handler, calls longjmp to simulate an exception.
+ * @todo this was used to have a central place to handle errors, but it is
+ * pretty ugly, and seriously interferes with any multithreaded approaches */
+static void NORETURN SlError(StringID string, const char *extra_msg = NULL)
+{
+ _sl.error_str = string;
+ free(_sl.extra_msg);
+ _sl.extra_msg = (extra_msg == NULL) ? NULL : strdup(extra_msg);
+ throw std::exception();
+}
+
/**
* Fill the input buffer by reading from the file with the given reader
*/
static void SlReadFill()
{
uint len = _sl.read_bytes();
- assert(len != 0);
+ if (len == 0) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Unexpected end of chunk");
_sl.bufp = _sl.buf;
_sl.bufe = _sl.buf + len;
@@ -137,17 +148,6 @@
_sl.bufe = _sl.buf + _sl.bufsize;
}
-/** Error handler, calls longjmp to simulate an exception.
- * @todo this was used to have a central place to handle errors, but it is
- * pretty ugly, and seriously interferes with any multithreaded approaches */
-static void NORETURN SlError(StringID string, const char *extra_msg = NULL)
-{
- _sl.error_str = string;
- free(_sl.extra_msg);
- _sl.extra_msg = (extra_msg == NULL) ? NULL : strdup(extra_msg);
- throw std::exception();
-}
-
/** Read in a single byte from file. If the temporary buffer is full,
* flush it to its final destination
* @return return the read byte from file
@@ -1524,7 +1524,7 @@
uint i;
uint count = 1 << Savegame_POOL_BLOCK_SIZE_BITS;
- assert(_ts.count == _sl.offs_base);
+ if (_ts.count != _sl.offs_base) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Unexpected size of chunk");
for (i = 0; i != _Savegame_pool.GetBlockCount() - 1; i++) {
_sl.buf = _Savegame_pool.blocks[i];
fmt->writer(count);
@@ -1537,7 +1537,7 @@
}
fmt->uninit_write();
- assert(_ts.count == _sl.offs_base);
+ if (_ts.count != _sl.offs_base) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Unexpected size of chunk");
GetSavegameFormat("memory")->uninit_write(); // clean the memorypool
fclose(_sl.fh);
--- a/src/settings.cpp Mon Apr 14 16:24:00 2008 +0000
+++ b/src/settings.cpp Mon Apr 14 21:21:10 2008 +0000
@@ -1333,6 +1333,8 @@
SDTG_VAR("min_players", SLE_UINT8, S, 0, _network_min_players, 0, 0, 10, 0, STR_NULL, NULL),
SDTG_OMANY("server_lang", SLE_UINT8, S, 0, _network_game_info.server_lang, 0, 35, "ANY|ENGLISH|GERMAN|FRENCH|BRAZILIAN|BULGARIAN|CHINESE|CZECH|DANISH|DUTCH|ESPERANTO|FINNISH|HUNGARIAN|ICELANDIC|ITALIAN|JAPANESE|KOREAN|LITHUANIAN|NORWEGIAN|POLISH|PORTUGUESE|ROMANIAN|RUSSIAN|SLOVAK|SLOVENIAN|SPANISH|SWEDISH|TURKISH|UKRAINIAN|AFRIKAANS|CROATIAN|CATALAN|ESTONIAN|GALICIAN|GREEK|LATVIAN", STR_NULL, NULL),
SDTG_BOOL("reload_cfg", S, 0, _network_reload_cfg, false, STR_NULL, NULL),
+ SDTG_STR("last_host", SLE_STRB, S, 0, _network_last_host, "0.0.0.0", STR_NULL, NULL),
+ SDTG_VAR("last_port", SLE_UINT16, S, 0, _network_last_port, 0, 0, UINT16_MAX, 0, STR_NULL ,NULL),
SDTG_END()
};
#endif /* ENABLE_NETWORK */
--- a/src/ship_cmd.cpp Mon Apr 14 16:24:00 2008 +0000
+++ b/src/ship_cmd.cpp Mon Apr 14 21:21:10 2008 +0000
@@ -243,7 +243,7 @@
{
if (station == this->last_station_visited) this->last_station_visited = INVALID_STATION;
- Station *st = GetStation(station);
+ const Station *st = GetStation(station);
if (st->dock_tile != 0) {
return TILE_ADD(st->dock_tile, ToTileIndexDiff(GetDockOffset(st->dock_tile)));
} else {
--- a/src/signs_gui.cpp Mon Apr 14 16:24:00 2008 +0000
+++ b/src/signs_gui.cpp Mon Apr 14 21:21:10 2008 +0000
@@ -68,63 +68,49 @@
static void SignListWndProc(Window *w, WindowEvent *e)
{
switch (e->event) {
- case WE_PAINT: {
- int y = 16; // offset from top of widget
-
- if (_sign_sort_dirty)
- GlobalSortSignList();
-
- SetVScrollCount(w, _num_sign_sort);
+ case WE_PAINT: {
+ if (_sign_sort_dirty) GlobalSortSignList();
- SetDParam(0, w->vscroll.count);
- DrawWindowWidgets(w);
+ SetVScrollCount(w, _num_sign_sort);
- /* No signs? */
- if (w->vscroll.count == 0) {
- DrawString(2, y, STR_304A_NONE, TC_FROMSTRING);
- return;
- }
+ SetDParam(0, w->vscroll.count);
+ DrawWindowWidgets(w);
- {
- uint16 i;
+ /* No signs? */
+ int y = 16; // offset from top of widget
+ if (w->vscroll.count == 0) {
+ DrawString(2, y, STR_304A_NONE, TC_FROMSTRING);
+ return;
+ }
/* Start drawing the signs */
- for (i = w->vscroll.pos; i < w->vscroll.cap + w->vscroll.pos && i < w->vscroll.count; i++) {
+ for (uint16 i = w->vscroll.pos; i < w->vscroll.cap + w->vscroll.pos && i < w->vscroll.count; i++) {
const Sign *si = _sign_sort[i];
- if (si->owner != OWNER_NONE)
- DrawPlayerIcon(si->owner, 4, y + 1);
+ if (si->owner != OWNER_NONE) DrawPlayerIcon(si->owner, 4, y + 1);
SetDParam(0, si->index);
DrawString(22, y, STR_SIGN_NAME, TC_YELLOW);
y += 10;
}
- }
- } break;
-
- case WE_CLICK: {
- switch (e->we.click.widget) {
- case 3: {
- uint32 id_v = (e->we.click.pt.y - 15) / 10;
- const Sign *si;
-
- if (id_v >= w->vscroll.cap)
- return;
+ } break;
- id_v += w->vscroll.pos;
-
- if (id_v >= w->vscroll.count)
- return;
+ case WE_CLICK:
+ if (e->we.click.widget == 3) {
+ uint32 id_v = (e->we.click.pt.y - 15) / 10;
- si = _sign_sort[id_v];
- ScrollMainWindowToTile(TileVirtXY(si->x, si->y));
- } break;
- }
- } break;
+ if (id_v >= w->vscroll.cap) return;
+ id_v += w->vscroll.pos;
+ if (id_v >= w->vscroll.count) return;
- case WE_RESIZE:
- w->vscroll.cap += e->we.sizing.diff.y / 10;
- break;
+ const Sign *si = _sign_sort[id_v];
+ ScrollMainWindowToTile(TileVirtXY(si->x, si->y));
+ }
+ break;
+
+ case WE_RESIZE:
+ w->vscroll.cap += e->we.sizing.diff.y / 10;
+ break;
}
}
@@ -149,9 +135,7 @@
void ShowSignList()
{
- Window *w;
-
- w = AllocateWindowDescFront(&_sign_list_desc, 0);
+ Window *w = AllocateWindowDescFront(&_sign_list_desc, 0);
if (w != NULL) {
w->vscroll.cap = 12;
w->resize.step_height = 10;
@@ -159,8 +143,7 @@
}
}
-/* Edit sign window stuff */
-
+/** Edit sign window stuff */
struct editsign_d : querystr_d {
SignID cur_sign;
};
@@ -314,13 +297,11 @@
void ShowRenameSignWindow(const Sign *si)
{
- Window *w;
-
/* Delete all other edit windows and the save window */
DeleteWindowById(WC_QUERY_STRING, 0);
DeleteWindowById(WC_SAVELOAD, 0);
- w = AllocateWindowDesc(&_query_sign_edit_desc);
+ Window *w = AllocateWindowDesc(&_query_sign_edit_desc);
WP(w, editsign_d).caption = STR_280B_EDIT_SIGN_TEXT;
WP(w, editsign_d).afilter = CS_ALPHANUMERAL;
@@ -328,6 +309,3 @@
UpdateSignEditWindow(w, si);
}
-
-
-
--- a/src/sound/win32_s.cpp Mon Apr 14 16:24:00 2008 +0000
+++ b/src/sound/win32_s.cpp Mon Apr 14 21:21:10 2008 +0000
@@ -59,7 +59,7 @@
wfex.nBlockAlign = (wfex.nChannels * wfex.wBitsPerSample) / 8;
wfex.nAvgBytesPerSec = wfex.nSamplesPerSec * wfex.nBlockAlign;
- _bufsize = GetDriverParamInt(parm, "bufsize", 2048);
+ _bufsize = GetDriverParamInt(parm, "bufsize", (GB(GetVersion(), 0, 8) > 5) ? 2048 : 1024);
if (waveOutOpen(&_waveout, WAVE_MAPPER, &wfex, (DWORD_PTR)&waveOutProc, 0, CALLBACK_FUNCTION) != MMSYSERR_NOERROR)
return "waveOutOpen failed";
--- a/src/station_cmd.cpp Mon Apr 14 16:24:00 2008 +0000
+++ b/src/station_cmd.cpp Mon Apr 14 21:21:10 2008 +0000
@@ -2199,10 +2199,14 @@
}
SpriteID pal;
- if (!(!HasBit(image, SPRITE_MODIFIER_OPAQUE) && IsTransparencySet(TO_BUILDINGS)) && HasBit(image, PALETTE_MODIFIER_COLOR)) {
- pal = palette;
+ if (HasBit(image, PALETTE_MODIFIER_TRANSPARENT) || HasBit(image, PALETTE_MODIFIER_COLOR)) {
+ if (dtss->image.pal > 0) {
+ pal = dtss->image.pal;
+ } else {
+ pal = palette;
+ }
} else {
- pal = dtss->image.pal;
+ pal = PAL_NONE;
}
if ((byte)dtss->delta_z != 0x80) {
@@ -2402,9 +2406,9 @@
static VehicleEnterTileStatus VehicleEnter_Station(Vehicle *v, TileIndex tile, int x, int y)
{
StationID station_id = GetStationIndex(tile);
- if (!v->current_order.ShouldStopAtStation(v, station_id)) return VETSB_CONTINUE;
if (v->type == VEH_TRAIN) {
+ if (!v->current_order.ShouldStopAtStation(v, station_id)) return VETSB_CONTINUE;
if (IsRailwayStation(tile) && IsFrontEngine(v) &&
!IsCompatibleTrainStationTile(tile + TileOffsByDiagDir(DirToDiagDir(v->direction)), tile)) {
DiagDirection dir = DirToDiagDir(v->direction);
@@ -2432,6 +2436,8 @@
RoadStop *rs = GetRoadStopByTile(tile, GetRoadStopType(tile));
if (IsDriveThroughStopTile(tile)) {
+ if (!v->current_order.ShouldStopAtStation(v, station_id)) return VETSB_CONTINUE;
+
/* Vehicles entering a drive-through stop from the 'normal' side use first bay (bay 0). */
byte side = ((DirToDiagDir(v->direction) == ReverseDiagDir(GetRoadStopDir(tile))) == (v->u.road.overtaking == 0)) ? 0 : 1;
--- a/src/tgp.cpp Mon Apr 14 16:24:00 2008 +0000
+++ b/src/tgp.cpp Mon Apr 14 21:21:10 2008 +0000
@@ -683,14 +683,6 @@
}
-/* The following decimals are the octave power modifiers for the Perlin noise */
-static const double _perlin_p_values[][7] = { // perlin frequency per power
- { 0.35, 0.35, 0.35, 0.35, 0.35, 0.25, 0.539 }, ///< Very smooth
- { 0.45, 0.55, 0.45, 0.45, 0.35, 0.25, 0.89 }, ///< Smooth
- { 0.85, 0.80, 0.70, 0.45, 0.45, 0.35, 1.825 }, ///< Rough 1.825
- { 0.95, 0.85, 0.80, 0.55, 0.55, 0.45, 2.245 } //< Very Rough 2.25
-};
-
/**
* The Perlin Noise calculation using large primes
* The initial number is adjusted by two values; the generation_seed, and the
--- a/src/timetable.h Mon Apr 14 16:24:00 2008 +0000
+++ b/src/timetable.h Mon Apr 14 21:21:10 2008 +0000
@@ -7,5 +7,6 @@
void ShowTimetableWindow(const Vehicle *v);
void UpdateVehicleTimetable(Vehicle *v, bool travelling);
+void SetTimetableParams(int param1, int param2, uint32 time);
#endif /* TIMETABLE_H */
--- a/src/timetable_gui.cpp Mon Apr 14 16:24:00 2008 +0000
+++ b/src/timetable_gui.cpp Mon Apr 14 21:21:10 2008 +0000
@@ -16,6 +16,7 @@
#include "string_func.h"
#include "gfx_func.h"
#include "player_func.h"
+#include "order_func.h"
#include "settings_type.h"
#include "table/strings.h"
@@ -57,7 +58,7 @@
return (sel <= v->num_orders * 2 && sel >= 0) ? sel : INVALID_ORDER;
}
-static inline void SetTimetableParams(int param1, int param2, uint32 time)
+void SetTimetableParams(int param1, int param2, uint32 time)
{
if (_patches.timetable_in_ticks) {
SetDParam(param1, STR_TIMETABLE_TICKS);
@@ -116,90 +117,7 @@
if (i - w->vscroll.pos >= w->vscroll.cap) break;
if (i % 2 == 0) {
- SetDParam(5, STR_EMPTY);
-
- switch (order->GetType()) {
- case OT_DUMMY:
- SetDParam(0, STR_INVALID_ORDER);
- break;
-
- case OT_GOTO_STATION:
- SetDParam(0, STR_GO_TO_STATION);
- SetDParam(1, STR_ORDER_GO_TO + order->GetNonStopType());
- SetDParam(2, order->GetDestination());
- SetDParam(3, STR_EMPTY);
-
- if (order->wait_time > 0) {
- SetDParam(5, STR_TIMETABLE_STAY_FOR);
- SetTimetableParams(6, 7, order->wait_time);
- } else {
- SetDParam(4, STR_EMPTY);
- }
-
- break;
-
- case OT_GOTO_DEPOT:
- SetDParam(4, STR_EMPTY);
- if (v->type == VEH_AIRCRAFT) {
- if (order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) {
- SetDParam(0, STR_GO_TO_NEAREST_DEPOT);
- SetDParam(2, STR_ORDER_NEAREST_HANGAR);
- } else {
- SetDParam(0, STR_GO_TO_HANGAR);
- SetDParam(2, order->GetDestination());
- }
- SetDParam(3, STR_EMPTY);
- } else {
- if (order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) {
- SetDParam(0, STR_GO_TO_NEAREST_DEPOT);
- SetDParam(2, STR_ORDER_NEAREST_DEPOT);
- } else {
- SetDParam(0, STR_GO_TO_DEPOT);
- SetDParam(2, GetDepot(order->GetDestination())->town_index);
- }
-
- switch (v->type) {
- case VEH_TRAIN: SetDParam(3, STR_ORDER_TRAIN_DEPOT); break;
- case VEH_ROAD: SetDParam(3, STR_ORDER_ROAD_DEPOT); break;
- case VEH_SHIP: SetDParam(3, STR_ORDER_SHIP_DEPOT); break;
- default: NOT_REACHED();
- }
- }
-
- if (order->GetDepotOrderType() & ODTFB_SERVICE) {
- SetDParam(1, (order->GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS) ? STR_ORDER_SERVICE_NON_STOP_AT : STR_ORDER_SERVICE_AT);
- } else {
- SetDParam(1, (order->GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS) ? STR_ORDER_GO_NON_STOP_TO : STR_ORDER_GO_TO);
- }
- break;
-
- case OT_GOTO_WAYPOINT:
- SetDParam(0, (order->GetNonStopType() != ONSF_STOP_EVERYWHERE) ? STR_GO_NON_STOP_TO_WAYPOINT : STR_GO_TO_WAYPOINT);
- SetDParam(1, order->GetDestination());
- break;
-
-
- case OT_CONDITIONAL:
- SetDParam(1, order->GetConditionSkipToOrder() + 1);
- if (order->GetConditionVariable() == OCV_UNCONDITIONALLY) {
- SetDParam(0, STR_CONDITIONAL_UNCONDITIONAL);
- } else {
- extern uint ConvertSpeedToDisplaySpeed(uint speed);
- OrderConditionComparator occ = order->GetConditionComparator();
- SetDParam(0, (occ == OCC_IS_TRUE || occ == OCC_IS_FALSE) ? STR_CONDITIONAL_TRUE_FALSE : STR_CONDITIONAL_NUM);
- SetDParam(2, STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE + order->GetConditionVariable());
- SetDParam(3, STR_ORDER_CONDITIONAL_COMPARATOR_EQUALS + occ);
-
- uint value = order->GetConditionValue();
- if (order->GetConditionVariable() == OCV_MAX_SPEED) value = ConvertSpeedToDisplaySpeed(value);
- SetDParam(4, value);
- }
- break;
-
- default: break;
- }
-
- DrawString(2, y, STR_TIMETABLE_GO_TO, (i == selected) ? TC_WHITE : TC_BLACK);
+ DrawOrderString(v, order, order_id, y, i == selected, true);
order_id++;
@@ -219,7 +137,7 @@
string = STR_TIMETABLE_TRAVEL_FOR;
}
- DrawString(12, y, string, (i == selected) ? TC_WHITE : TC_BLACK);
+ DrawString(22, y, string, (i == selected) ? TC_WHITE : TC_BLACK);
if (final_order) break;
}
--- a/src/town_gui.cpp Mon Apr 14 16:24:00 2008 +0000
+++ b/src/town_gui.cpp Mon Apr 14 21:21:10 2008 +0000
@@ -142,117 +142,118 @@
static void TownAuthorityWndProc(Window *w, WindowEvent *e)
{
switch (e->event) {
- case WE_PAINT: {
- const Town *t = GetTown(w->window_number);
- int numact;
- uint buttons = GetMaskOfTownActions(&numact, _local_player, t);
-
- SetVScrollCount(w, numact + 1);
-
- if (WP(w, def_d).data_1 != -1 && !HasBit(buttons, WP(w,def_d).data_1))
- WP(w, def_d).data_1 = -1;
-
- w->SetWidgetDisabledState(6, WP(w, def_d).data_1 == -1);
-
- {
- int y;
- const Player *p;
- int r;
- StringID str;
-
- SetDParam(0, w->window_number);
- DrawWindowWidgets(w);
-
- DrawString(2, 15, STR_2023_TRANSPORT_COMPANY_RATINGS, TC_FROMSTRING);
+ case WE_PAINT: {
+ const Town *t = GetTown(w->window_number);
+ int numact;
+ uint buttons = GetMaskOfTownActions(&numact, _local_player, t);
- /* Draw list of players */
- y = 25;
- FOR_ALL_PLAYERS(p) {
- if (p->is_active && (HasBit(t->have_ratings, p->index) || t->exclusivity == p->index)) {
- DrawPlayerIcon(p->index, 2, y);
-
- SetDParam(0, p->index);
- SetDParam(1, p->index);
+ SetVScrollCount(w, numact + 1);
- r = t->ratings[p->index];
- (str = STR_3035_APPALLING, r <= RATING_APPALLING) || // Apalling
- (str++, r <= RATING_VERYPOOR) || // Very Poor
- (str++, r <= RATING_POOR) || // Poor
- (str++, r <= RATING_MEDIOCRE) || // Mediocore
- (str++, r <= RATING_GOOD) || // Good
- (str++, r <= RATING_VERYGOOD) || // Very Good
- (str++, r <= RATING_EXCELLENT) || // Excellent
- (str++, true); // Outstanding
+ if (WP(w, def_d).data_1 != -1 && !HasBit(buttons, WP(w,def_d).data_1))
+ WP(w, def_d).data_1 = -1;
- SetDParam(2, str);
- if (t->exclusivity == p->index) { // red icon for player with exclusive rights
- DrawSprite(SPR_BLOT, PALETTE_TO_RED, 18, y);
+ w->SetWidgetDisabledState(6, WP(w, def_d).data_1 == -1);
+
+ {
+ int y;
+ const Player *p;
+ int r;
+ StringID str;
+
+ SetDParam(0, w->window_number);
+ DrawWindowWidgets(w);
+
+ DrawString(2, 15, STR_2023_TRANSPORT_COMPANY_RATINGS, TC_FROMSTRING);
+
+ /* Draw list of players */
+ y = 25;
+ FOR_ALL_PLAYERS(p) {
+ if (p->is_active && (HasBit(t->have_ratings, p->index) || t->exclusivity == p->index)) {
+ DrawPlayerIcon(p->index, 2, y);
+
+ SetDParam(0, p->index);
+ SetDParam(1, p->index);
+
+ r = t->ratings[p->index];
+ (str = STR_3035_APPALLING, r <= RATING_APPALLING) || // Apalling
+ (str++, r <= RATING_VERYPOOR) || // Very Poor
+ (str++, r <= RATING_POOR) || // Poor
+ (str++, r <= RATING_MEDIOCRE) || // Mediocore
+ (str++, r <= RATING_GOOD) || // Good
+ (str++, r <= RATING_VERYGOOD) || // Very Good
+ (str++, r <= RATING_EXCELLENT) || // Excellent
+ (str++, true); // Outstanding
+
+ SetDParam(2, str);
+ if (t->exclusivity == p->index) { // red icon for player with exclusive rights
+ DrawSprite(SPR_BLOT, PALETTE_TO_RED, 18, y);
+ }
+
+ DrawString(28, y, STR_2024, TC_FROMSTRING);
+ y += 10;
}
-
- DrawString(28, y, STR_2024, TC_FROMSTRING);
- y += 10;
}
}
- }
-
- /* Draw actions list */
- {
- int y = 107, i;
- int pos = w->vscroll.pos;
- if (--pos < 0) {
- DrawString(2, y, STR_2045_ACTIONS_AVAILABLE, TC_FROMSTRING);
- y += 10;
- }
- for (i = 0; buttons; i++, buttons >>= 1) {
- if (pos <= -5) break; ///< Draw only the 5 fitting lines
+ /* Draw actions list */
+ {
+ int y = 107, i;
+ int pos = w->vscroll.pos;
- if ((buttons & 1) && --pos < 0) {
- DrawString(3, y, STR_2046_SMALL_ADVERTISING_CAMPAIGN + i, TC_ORANGE);
+ if (--pos < 0) {
+ DrawString(2, y, STR_2045_ACTIONS_AVAILABLE, TC_FROMSTRING);
y += 10;
}
+
+ for (i = 0; buttons; i++, buttons >>= 1) {
+ if (pos <= -5) break; ///< Draw only the 5 fitting lines
+
+ if ((buttons & 1) && --pos < 0) {
+ DrawString(3, y, STR_2046_SMALL_ADVERTISING_CAMPAIGN + i, TC_ORANGE);
+ y += 10;
+ }
+ }
}
- }
-
- {
- int i = WP(w, def_d).data_1;
-
- if (i != -1) {
- SetDParam(1, (_price.build_industry >> 8) * _town_action_costs[i]);
- SetDParam(0, STR_2046_SMALL_ADVERTISING_CAMPAIGN + i);
- DrawStringMultiLine(2, 159, STR_204D_INITIATE_A_SMALL_LOCAL + i, 313);
- }
- }
-
- } break;
- case WE_DOUBLE_CLICK:
- case WE_CLICK:
- switch (e->we.click.widget) {
- case TWA_COMMAND_LIST: {
- const Town *t = GetTown(w->window_number);
- int y = (e->we.click.pt.y - 0x6B) / 10;
+ {
+ int i = WP(w, def_d).data_1;
- if (!IsInsideMM(y, 0, 5)) return;
-
- y = GetNthSetBit(GetMaskOfTownActions(NULL, _local_player, t), y + w->vscroll.pos - 1);
- if (y >= 0) {
- WP(w, def_d).data_1 = y;
- SetWindowDirty(w);
+ if (i != -1) {
+ SetDParam(1, (_price.build_industry >> 8) * _town_action_costs[i]);
+ SetDParam(0, STR_2046_SMALL_ADVERTISING_CAMPAIGN + i);
+ DrawStringMultiLine(2, 159, STR_204D_INITIATE_A_SMALL_LOCAL + i, 313);
}
- /* Fall through to clicking in case we are double-clicked */
- if (e->event != WE_DOUBLE_CLICK || y < 0) break;
}
- case TWA_EXECUTE:
- DoCommandP(GetTown(w->window_number)->xy, w->window_number, WP(w, def_d).data_1, NULL, CMD_DO_TOWN_ACTION | CMD_MSG(STR_00B4_CAN_T_DO_THIS));
- break;
- }
- break;
+ } break;
- case WE_4:
- SetWindowDirty(w);
- break;
+ case WE_DOUBLE_CLICK:
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case TWA_COMMAND_LIST: {
+ const Town *t = GetTown(w->window_number);
+ int y = (e->we.click.pt.y - 0x6B) / 10;
+
+ if (!IsInsideMM(y, 0, 5)) return;
+
+ y = GetNthSetBit(GetMaskOfTownActions(NULL, _local_player, t), y + w->vscroll.pos - 1);
+ if (y >= 0) {
+ WP(w, def_d).data_1 = y;
+ SetWindowDirty(w);
+ }
+ /* Fall through to clicking in case we are double-clicked */
+ if (e->event != WE_DOUBLE_CLICK || y < 0) break;
+ }
+
+ case TWA_EXECUTE:
+ DoCommandP(GetTown(w->window_number)->xy, w->window_number, WP(w, def_d).data_1, NULL, CMD_DO_TOWN_ACTION | CMD_MSG(STR_00B4_CAN_T_DO_THIS));
+ break;
+ }
+ break;
+
+ case WE_4:
+ SetWindowDirty(w);
+ break;
}
}
@@ -274,68 +275,78 @@
}
}
+
+enum TownViewWidget {
+ TVW_CAPTION = 1,
+ TVW_CENTERVIEW = 6,
+ TVW_SHOWAUTORITY,
+ TVW_CHANGENAME,
+ TVW_EXPAND,
+ TVW_DELETE,
+};
+
static void TownViewWndProc(Window *w, WindowEvent *e)
{
Town *t = GetTown(w->window_number);
switch (e->event) {
- case WE_CREATE:
- if (t->larger_town) w->widget[1].data = STR_CITY;
- break;
-
- case WE_PAINT:
- /* disable renaming town in network games if you are not the server */
- w->SetWidgetDisabledState(8, _networking && !_network_server);
-
- SetDParam(0, t->index);
- DrawWindowWidgets(w);
-
- SetDParam(0, t->population);
- SetDParam(1, t->num_houses);
- DrawString(2, 107, STR_2006_POPULATION, TC_FROMSTRING);
-
- SetDParam(0, t->act_pass);
- SetDParam(1, t->max_pass);
- DrawString(2, 117, STR_200D_PASSENGERS_LAST_MONTH_MAX, TC_FROMSTRING);
-
- SetDParam(0, t->act_mail);
- SetDParam(1, t->max_mail);
- DrawString(2, 127, STR_200E_MAIL_LAST_MONTH_MAX, TC_FROMSTRING);
-
- DrawWindowViewport(w);
- break;
+ case WE_CREATE:
+ if (t->larger_town) w->widget[TVW_CAPTION].data = STR_CITY;
+ break;
- case WE_CLICK:
- switch (e->we.click.widget) {
- case 6: /* scroll to location */
- ScrollMainWindowToTile(t->xy);
- break;
-
- case 7: /* town authority */
- ShowTownAuthorityWindow(w->window_number);
- break;
-
- case 8: /* rename */
- SetDParam(0, w->window_number);
- ShowQueryString(STR_TOWN, STR_2007_RENAME_TOWN, 31, 130, w, CS_ALPHANUMERAL);
- break;
+ case WE_PAINT:
+ /* disable renaming town in network games if you are not the server */
+ w->SetWidgetDisabledState(TVW_CHANGENAME, _networking && !_network_server);
- case 9: /* expand town */
- ExpandTown(t);
- break;
+ SetDParam(0, t->index);
+ DrawWindowWidgets(w);
- case 10: /* delete town */
- delete t;
- break;
- } break;
+ SetDParam(0, t->population);
+ SetDParam(1, t->num_houses);
+ DrawString(2, 107, STR_2006_POPULATION, TC_FROMSTRING);
- case WE_ON_EDIT_TEXT:
- if (e->we.edittext.str[0] != '\0') {
- _cmd_text = e->we.edittext.str;
- DoCommandP(0, w->window_number, 0, NULL,
- CMD_RENAME_TOWN | CMD_MSG(STR_2008_CAN_T_RENAME_TOWN));
- }
- break;
+ SetDParam(0, t->act_pass);
+ SetDParam(1, t->max_pass);
+ DrawString(2, 117, STR_200D_PASSENGERS_LAST_MONTH_MAX, TC_FROMSTRING);
+
+ SetDParam(0, t->act_mail);
+ SetDParam(1, t->max_mail);
+ DrawString(2, 127, STR_200E_MAIL_LAST_MONTH_MAX, TC_FROMSTRING);
+
+ DrawWindowViewport(w);
+ break;
+
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case TVW_CENTERVIEW: /* scroll to location */
+ ScrollMainWindowToTile(t->xy);
+ break;
+
+ case TVW_SHOWAUTORITY: /* town authority */
+ ShowTownAuthorityWindow(w->window_number);
+ break;
+
+ case TVW_CHANGENAME: /* rename */
+ SetDParam(0, w->window_number);
+ ShowQueryString(STR_TOWN, STR_2007_RENAME_TOWN, 31, 130, w, CS_ALPHANUMERAL);
+ break;
+
+ case TVW_EXPAND: /* expand town - only available on Scenario editor */
+ ExpandTown(t);
+ break;
+
+ case TVW_DELETE: /* delete town - only available on Scenario editor */
+ delete t;
+ break;
+ } break;
+
+ case WE_ON_EDIT_TEXT:
+ if (e->we.edittext.str[0] != '\0') {
+ _cmd_text = e->we.edittext.str;
+ DoCommandP(0, w->window_number, 0, NULL,
+ CMD_RENAME_TOWN | CMD_MSG(STR_2008_CAN_T_RENAME_TOWN));
+ }
+ break;
}
}
@@ -480,79 +491,79 @@
static void TownDirectoryWndProc(Window *w, WindowEvent *e)
{
switch (e->event) {
- case WE_PAINT: {
- if (_town_sort_dirty) {
- _town_sort_dirty = false;
- MakeSortedTownList();
- }
-
- SetVScrollCount(w, _num_town_sort);
-
- DrawWindowWidgets(w);
- DrawSortButtonState(w, (_town_sort_order <= 1) ? TDW_SORTNAME : TDW_SORTPOPULATION, _town_sort_order & 1 ? SBS_DOWN : SBS_UP);
-
- {
- int n = 0;
- uint16 i = w->vscroll.pos;
- int y = 28;
-
- while (i < _num_town_sort) {
- const Town* t = _town_sort[i];
-
- assert(t->xy);
-
- SetDParam(0, t->index);
- SetDParam(1, t->population);
- DrawString(2, y, STR_2057, TC_FROMSTRING);
-
- y += 10;
- i++;
- if (++n == w->vscroll.cap) break; // max number of towns in 1 window
+ case WE_PAINT: {
+ if (_town_sort_dirty) {
+ _town_sort_dirty = false;
+ MakeSortedTownList();
}
- SetDParam(0, GetWorldPopulation());
- DrawString(3, w->height - 12 + 2, STR_TOWN_POPULATION, TC_FROMSTRING);
- }
- } break;
- case WE_CLICK:
- switch (e->we.click.widget) {
- case TDW_SORTNAME: { /* Sort by Name ascending/descending */
- _town_sort_order = (_town_sort_order == 0) ? 1 : 0;
- _town_sort_dirty = true;
- SetWindowDirty(w);
- } break;
-
- case TDW_SORTPOPULATION: { /* Sort by Population ascending/descending */
- _town_sort_order = (_town_sort_order == 2) ? 3 : 2;
- _town_sort_dirty = true;
- SetWindowDirty(w);
- } break;
-
- case TDW_CENTERTOWN: { /* Click on Town Matrix */
- const Town* t;
-
- uint16 id_v = (e->we.click.pt.y - 28) / 10;
+ SetVScrollCount(w, _num_town_sort);
- if (id_v >= w->vscroll.cap) return; // click out of bounds
-
- id_v += w->vscroll.pos;
-
- if (id_v >= _num_town_sort) return; // click out of town bounds
+ DrawWindowWidgets(w);
+ DrawSortButtonState(w, (_town_sort_order <= 1) ? TDW_SORTNAME : TDW_SORTPOPULATION, _town_sort_order & 1 ? SBS_DOWN : SBS_UP);
- t = _town_sort[id_v];
- assert(t->xy);
- ScrollMainWindowToTile(t->xy);
- } break;
- }
- break;
+ {
+ int n = 0;
+ uint16 i = w->vscroll.pos;
+ int y = 28;
- case WE_4:
- SetWindowDirty(w);
- break;
+ while (i < _num_town_sort) {
+ const Town* t = _town_sort[i];
- case WE_RESIZE:
- w->vscroll.cap += e->we.sizing.diff.y / 10;
- break;
+ assert(t->xy);
+
+ SetDParam(0, t->index);
+ SetDParam(1, t->population);
+ DrawString(2, y, STR_2057, TC_FROMSTRING);
+
+ y += 10;
+ i++;
+ if (++n == w->vscroll.cap) break; // max number of towns in 1 window
+ }
+ SetDParam(0, GetWorldPopulation());
+ DrawString(3, w->height - 12 + 2, STR_TOWN_POPULATION, TC_FROMSTRING);
+ }
+ } break;
+
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case TDW_SORTNAME: /* Sort by Name ascending/descending */
+ _town_sort_order = (_town_sort_order == 0) ? 1 : 0;
+ _town_sort_dirty = true;
+ SetWindowDirty(w);
+ break;
+
+ case TDW_SORTPOPULATION: /* Sort by Population ascending/descending */
+ _town_sort_order = (_town_sort_order == 2) ? 3 : 2;
+ _town_sort_dirty = true;
+ SetWindowDirty(w);
+ break;
+
+ case TDW_CENTERTOWN: { /* Click on Town Matrix */
+ const Town* t;
+
+ uint16 id_v = (e->we.click.pt.y - 28) / 10;
+
+ if (id_v >= w->vscroll.cap) return; // click out of bounds
+
+ id_v += w->vscroll.pos;
+
+ if (id_v >= _num_town_sort) return; // click out of town bounds
+
+ t = _town_sort[id_v];
+ assert(t->xy);
+ ScrollMainWindowToTile(t->xy);
+ } break;
+ }
+ break;
+
+ case WE_4:
+ SetWindowDirty(w);
+ break;
+
+ case WE_RESIZE:
+ w->vscroll.cap += e->we.sizing.diff.y / 10;
+ break;
}
}
@@ -591,6 +602,16 @@
DoCommandP(tile, size, mode, CcBuildTown, CMD_BUILD_TOWN | CMD_MSG(STR_0236_CAN_T_BUILD_TOWN_HERE));
}
+enum TownScenarioEditorWidget {
+ TSEW_NEWTOWN = 4,
+ TSEW_RANDOMTOWN,
+ TSEW_MANYRANDOMTOWNS,
+ TSEW_SMALLTOWN,
+ TSEW_MEDIUMTOWN,
+ TSEW_LARGETOWN,
+ TSEW_CITY,
+};
+
static const Widget _scen_edit_town_gen_widgets[] = {
{ WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
{ WWT_CAPTION, RESIZE_NONE, 7, 11, 147, 0, 13, STR_0233_TOWN_GENERATION, STR_018C_WINDOW_TITLE_DRAG_THIS},
@@ -610,68 +631,68 @@
static void ScenEditTownGenWndProc(Window *w, WindowEvent *e)
{
switch (e->event) {
- case WE_PAINT:
- DrawWindowWidgets(w);
- break;
-
- case WE_CREATE:
- w->LowerWidget(_scengen_town_size + 7);
- break;
-
- case WE_CLICK:
- switch (e->we.click.widget) {
- case 4: // new town
- HandlePlacePushButton(w, 4, SPR_CURSOR_TOWN, VHM_RECT, PlaceProc_Town);
+ case WE_PAINT:
+ DrawWindowWidgets(w);
break;
- case 5: {// random town
- Town *t;
- uint size = min(_scengen_town_size, (int)TSM_CITY);
- TownSizeMode mode = _scengen_town_size > TSM_CITY ? TSM_CITY : TSM_FIXED;
- w->HandleButtonClick(5);
- _generating_world = true;
- t = CreateRandomTown(20, mode, size);
- _generating_world = false;
-
- if (t == NULL) {
- ShowErrorMessage(STR_NO_SPACE_FOR_TOWN, STR_CANNOT_GENERATE_TOWN, 0, 0);
- } else {
- ScrollMainWindowToTile(t->xy);
- }
-
+ case WE_CREATE:
+ w->LowerWidget(_scengen_town_size + TSEW_SMALLTOWN);
break;
- }
- case 6: {// many random towns
- w->HandleButtonClick(6);
- _generating_world = true;
- if (!GenerateTowns()) ShowErrorMessage(STR_NO_SPACE_FOR_TOWN, STR_CANNOT_GENERATE_TOWN, 0, 0);
- _generating_world = false;
- break;
- }
+ case WE_CLICK:
+ switch (e->we.click.widget) {
+ case TSEW_NEWTOWN:
+ HandlePlacePushButton(w, TSEW_NEWTOWN, SPR_CURSOR_TOWN, VHM_RECT, PlaceProc_Town);
+ break;
- case 7: case 8: case 9: case 10:
- w->RaiseWidget(_scengen_town_size + 7);
- _scengen_town_size = e->we.click.widget - 7;
- w->LowerWidget(_scengen_town_size + 7);
+ case TSEW_RANDOMTOWN: {
+ Town *t;
+ uint size = min(_scengen_town_size, (int)TSM_CITY);
+ TownSizeMode mode = _scengen_town_size > TSM_CITY ? TSM_CITY : TSM_FIXED;
+
+ w->HandleButtonClick(TSEW_RANDOMTOWN);
+ _generating_world = true;
+ t = CreateRandomTown(20, mode, size);
+ _generating_world = false;
+
+ if (t == NULL) {
+ ShowErrorMessage(STR_NO_SPACE_FOR_TOWN, STR_CANNOT_GENERATE_TOWN, 0, 0);
+ } else {
+ ScrollMainWindowToTile(t->xy);
+ }
+ } break;
+
+ case TSEW_MANYRANDOMTOWNS:
+ w->HandleButtonClick(TSEW_MANYRANDOMTOWNS);
+
+ _generating_world = true;
+ if (!GenerateTowns()) ShowErrorMessage(STR_NO_SPACE_FOR_TOWN, STR_CANNOT_GENERATE_TOWN, 0, 0);
+ _generating_world = false;
+ break;
+
+ case TSEW_SMALLTOWN: case TSEW_MEDIUMTOWN: case TSEW_LARGETOWN: case TSEW_CITY:
+ w->RaiseWidget(_scengen_town_size + TSEW_SMALLTOWN);
+ _scengen_town_size = e->we.click.widget - TSEW_SMALLTOWN;
+ w->LowerWidget(_scengen_town_size + TSEW_SMALLTOWN);
+ SetWindowDirty(w);
+ break;
+ } break;
+
+ case WE_TIMEOUT:
+ w->RaiseWidget(TSEW_RANDOMTOWN);
+ w->RaiseWidget(TSEW_MANYRANDOMTOWNS);
SetWindowDirty(w);
break;
- }
- break;
- case WE_TIMEOUT:
- w->RaiseWidget(5);
- w->RaiseWidget(6);
- SetWindowDirty(w);
- break;
- case WE_PLACE_OBJ:
- _place_proc(e->we.place.tile);
- break;
- case WE_ABORT_PLACE_OBJ:
- w->RaiseButtons();
- w->LowerWidget(_scengen_town_size + 7);
- SetWindowDirty(w);
- break;
+ case WE_PLACE_OBJ:
+ _place_proc(e->we.place.tile);
+ break;
+
+ case WE_ABORT_PLACE_OBJ:
+ w->RaiseButtons();
+ w->LowerWidget(_scengen_town_size + TSEW_SMALLTOWN);
+ SetWindowDirty(w);
+ break;
}
}
--- a/src/train_cmd.cpp Mon Apr 14 16:24:00 2008 +0000
+++ b/src/train_cmd.cpp Mon Apr 14 21:21:10 2008 +0000
@@ -1812,8 +1812,7 @@
InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
}
- /* set reversed flag on all parts */
- for (Vehicle *u = v; u != NULL; u = u->Next()) ToggleBit(u->u.rail.flags, VRF_TOGGLE_REVERSE);
+ ToggleBit(v->u.rail.flags, VRF_TOGGLE_REVERSE);
ClrBit(v->u.rail.flags, VRF_REVERSING);
@@ -2564,7 +2563,14 @@
{
if (station == this->last_station_visited) this->last_station_visited = INVALID_STATION;
- return GetStation(station)->xy;
+ const Station *st = GetStation(station);
+ if (!(st->facilities & FACIL_TRAIN)) {
+ /* The destination station has no trainstation tiles. */
+ this->cur_order_index++;
+ return 0;
+ }
+
+ return st->xy;
}
void Train::MarkDirty()
--- a/src/vehicle.cpp Mon Apr 14 16:24:00 2008 +0000
+++ b/src/vehicle.cpp Mon Apr 14 21:21:10 2008 +0000
@@ -137,7 +137,7 @@
{
if (_patches.gotodepot && VehicleHasDepotOrders(this)) return false;
if (this->current_order.IsType(OT_LOADING)) return false;
- if (this->current_order.IsType(OT_GOTO_DEPOT) && this->current_order.GetDepotActionType() & ODATFB_HALT) return false;
+ if (this->current_order.IsType(OT_GOTO_DEPOT) && this->current_order.GetDepotOrderType() != ODTFB_SERVICE) return false;
return NeedsServicing();
}
@@ -2188,8 +2188,7 @@
if (!IsFrontEngine(v)) v = v->First();
UpdateSignalsOnSegment(v->tile, INVALID_DIAGDIR, v->owner);
v->load_unload_time_rem = 0;
- /* Reset reversed flag */
- for (Vehicle *u = v; u != NULL; u = u->Next()) ClrBit(u->u.rail.flags, VRF_TOGGLE_REVERSE);
+ ClrBit(v->u.rail.flags, VRF_TOGGLE_REVERSE);
TrainConsistChanged(v);
break;
--- a/src/vehicle_base.h Mon Apr 14 16:24:00 2008 +0000
+++ b/src/vehicle_base.h Mon Apr 14 21:21:10 2008 +0000
@@ -139,7 +139,7 @@
/* used to mark that electric train engine is allowed to run on normal rail */
VRF_EL_ENGINE_ALLOWED_NORMAL_RAIL = 6,
- /* used for vehicle var 0xFE bit 8 (toggled each time the train is reversed) */
+ /* used for vehicle var 0xFE bit 8 (toggled each time the train is reversed, accurate for first vehicle only) */
VRF_TOGGLE_REVERSE = 7,
};
--- a/src/vehicle_gui.cpp Mon Apr 14 16:24:00 2008 +0000
+++ b/src/vehicle_gui.cpp Mon Apr 14 21:21:10 2008 +0000
@@ -1990,7 +1990,7 @@
case OT_LEAVESTATION:
if (v->type != VEH_AIRCRAFT) {
- str = STR_882F_LOADING_UNLOADING;
+ str = STR_LEAVING;
break;
}
/* fall-through if aircraft. Does this even happen? */
--- a/src/viewport.cpp Mon Apr 14 16:24:00 2008 +0000
+++ b/src/viewport.cpp Mon Apr 14 21:21:10 2008 +0000
@@ -27,7 +27,7 @@
#include "player_func.h"
#include "settings_type.h"
#include "station_func.h"
-#include "core/alloc_func.hpp"
+#include "core/alloc_type.hpp"
#include "table/sprites.h"
#include "table/strings.h"
--- a/src/widgets/dropdown.cpp Mon Apr 14 16:24:00 2008 +0000
+++ b/src/widgets/dropdown.cpp Mon Apr 14 21:21:10 2008 +0000
@@ -36,6 +36,11 @@
return this->string;
}
+void DropDownListItem::Draw(int x, int y, uint width, uint height, bool sel) const
+{
+ DrawStringTruncated(x + 2, y, this->String(), sel ? TC_WHITE : TC_BLACK, x + width);
+}
+
/**
* Delete all items of a drop down list and the list itself
* @param list List to delete.
@@ -122,7 +127,7 @@
if (item->String() != STR_NULL) {
if (sel == item->result) GfxFillRect(x + 1, y, x + width, y + item_height - 1, 0);
- DrawStringTruncated(x + 2, y, item->String(), sel == item->result ? TC_WHITE : TC_BLACK, x + width);
+ item->Draw(x, y, width, 10, sel == item->result);
if (item->masked) {
GfxFillRect(x, y, x + width, y + item_height - 1,
--- a/src/widgets/dropdown_type.h Mon Apr 14 16:24:00 2008 +0000
+++ b/src/widgets/dropdown_type.h Mon Apr 14 21:21:10 2008 +0000
@@ -19,6 +19,7 @@
virtual ~DropDownListItem() {}
virtual StringID String() const;
virtual uint Height(uint width) const;
+ virtual void Draw(int x, int y, uint width, uint height, bool sel) const;
};
/**
--- a/src/window.cpp Mon Apr 14 16:24:00 2008 +0000
+++ b/src/window.cpp Mon Apr 14 21:21:10 2008 +0000
@@ -22,17 +22,15 @@
#include "table/sprites.h"
-/** delta between mouse cursor and upper left corner of dragged window */
-static Point _drag_delta;
-
-static Window _windows[MAX_NUMBER_OF_WINDOWS];
+static Point _drag_delta; ///< delta between mouse cursor and upper left corner of dragged window
+static Window *_mouseover_last_w = NULL; ///< Window of the last MOUSEOVER event
/**
* List of windows opened at the screen.
* Uppermost window is at _z_windows[_last_z_window - 1],
* bottom window is at _z_windows[0]
*/
-Window *_z_windows[lengthof(_windows)];
+Window *_z_windows[MAX_NUMBER_OF_WINDOWS];
Window **_last_z_window; ///< always points to the next free space in the z-array
Point _cursorpos_drag_start;
@@ -250,33 +248,6 @@
}
}
-static void DrawOverlappedWindow(Window* const *wz, int left, int top, int right, int bottom);
-
-/**
- * From a rectangle that needs redrawing, find the windows that intersect with the rectangle.
- * These windows should be re-painted.
- * @param left Left edge of the rectangle that should be repainted
- * @param top Top edge of the rectangle that should be repainted
- * @param right Right edge of the rectangle that should be repainted
- * @param bottom Bottom edge of the rectangle that should be repainted
- */
-void DrawOverlappedWindowForAll(int left, int top, int right, int bottom)
-{
- Window* const *wz;
- DrawPixelInfo bk;
- _cur_dpi = &bk;
-
- FOR_ALL_WINDOWS(wz) {
- const Window *w = *wz;
- if (right > w->left &&
- bottom > w->top &&
- left < w->left + w->width &&
- top < w->top + w->height) {
- DrawOverlappedWindow(wz, left, top, right, bottom);
- }
- }
-}
-
/**
* Generate repaint events for the visible part of window *wz within the rectangle.
*
@@ -288,8 +259,6 @@
* @param top Top edge of the rectangle that should be repainted
* @param right Right edge of the rectangle that should be repainted
* @param bottom Bottom edge of the rectangle that should be repainted
- *
- * @todo Swap this function to above DrawOverlappedWindowForAll() to eliminate the forward declaration
*/
static void DrawOverlappedWindow(Window* const *wz, int left, int top, int right, int bottom)
{
@@ -333,16 +302,39 @@
}
}
- {
- DrawPixelInfo *dp = _cur_dpi;
- dp->width = right - left;
- dp->height = bottom - top;
- dp->left = left - (*wz)->left;
- dp->top = top - (*wz)->top;
- dp->pitch = _screen.pitch;
- dp->dst_ptr = BlitterFactoryBase::GetCurrentBlitter()->MoveTo(_screen.dst_ptr, left, top);
- dp->zoom = ZOOM_LVL_NORMAL;
- CallWindowEventNP(*wz, WE_PAINT);
+ DrawPixelInfo *dp = _cur_dpi;
+ dp->width = right - left;
+ dp->height = bottom - top;
+ dp->left = left - (*wz)->left;
+ dp->top = top - (*wz)->top;
+ dp->pitch = _screen.pitch;
+ dp->dst_ptr = BlitterFactoryBase::GetCurrentBlitter()->MoveTo(_screen.dst_ptr, left, top);
+ dp->zoom = ZOOM_LVL_NORMAL;
+ CallWindowEventNP(*wz, WE_PAINT);
+}
+
+/**
+ * From a rectangle that needs redrawing, find the windows that intersect with the rectangle.
+ * These windows should be re-painted.
+ * @param left Left edge of the rectangle that should be repainted
+ * @param top Top edge of the rectangle that should be repainted
+ * @param right Right edge of the rectangle that should be repainted
+ * @param bottom Bottom edge of the rectangle that should be repainted
+ */
+void DrawOverlappedWindowForAll(int left, int top, int right, int bottom)
+{
+ Window* const *wz;
+ DrawPixelInfo bk;
+ _cur_dpi = &bk;
+
+ FOR_ALL_WINDOWS(wz) {
+ const Window *w = *wz;
+ if (right > w->left &&
+ bottom > w->top &&
+ left < w->left + w->width &&
+ top < w->top + w->height) {
+ DrawOverlappedWindow(wz, left, top, right, bottom);
+ }
}
}
@@ -430,12 +422,17 @@
w->widget_count = 0;
w->parent = NULL;
+ /* Prevent Mouseover() from resetting mouse-over coordinates on a non-existing window */
+ if (_mouseover_last_w == w) _mouseover_last_w = NULL;
+
/* Find the window in the z-array, and effectively remove it
* by moving all windows after it one to the left */
Window **wz = FindWindowZPosition(w);
if (wz == NULL) return;
memmove(wz, wz + 1, (byte*)_last_z_window - (byte*)wz);
_last_z_window--;
+
+ delete w;
}
/**
@@ -658,28 +655,6 @@
}
}
-static Window *FindFreeWindow()
-{
- Window *w;
-
- for (w = _windows; w < endof(_windows); w++) {
- Window* const *wz;
- bool window_in_use = false;
-
- FOR_ALL_WINDOWS(wz) {
- if (*wz == w) {
- window_in_use = true;
- break;
- }
- }
-
- if (!window_in_use) return w;
- }
-
- assert(_last_z_window == endof(_z_windows));
- return NULL;
-}
-
/** Open a new window.
* This function is called from AllocateWindow() or AllocateWindowDesc()
* See descriptions for those functions for usage
@@ -700,17 +675,18 @@
static Window *LocalAllocateWindow(int x, int y, int min_width, int min_height, int def_width, int def_height,
WindowProc *proc, WindowClass cls, const Widget *widget, int window_number, void *data)
{
- Window *w = FindFreeWindow();
+ Window *w;
/* We have run out of windows, close one and use that as the place for our new one */
- if (w == NULL) {
+ if (_last_z_window == endof(_z_windows)) {
w = FindDeletableWindow();
if (w == NULL) w = ForceFindDeletableWindow();
DeleteWindow(w);
}
+ w = new Window;
+
/* Set up window properties */
- memset(w, 0, sizeof(*w));
w->window_class = cls;
w->flags4 = WF_WHITE_BORDER_MASK; // just opened windows have a white border
w->caption_color = 0xFF;
@@ -1053,16 +1029,21 @@
return NULL;
}
+/**
+ * (re)initialize the windowing system
+ */
void InitWindowSystem()
{
IConsoleClose();
- memset(&_windows, 0, sizeof(_windows));
_last_z_window = _z_windows;
InitViewports();
_no_scroll = 0;
}
+/**
+ * Close down the windowing system
+ */
void UnInitWindowSystem()
{
Window **wz;
@@ -1081,6 +1062,9 @@
assert(_last_z_window == _z_windows);
}
+/**
+ * Reset the windowing system, by means of shutting it down followed by re-initialization
+ */
void ResetWindowSystem()
{
UnInitWindowSystem();
@@ -1195,20 +1179,21 @@
static bool HandleMouseOver()
{
- Window *w;
WindowEvent e;
- static Window *last_w = NULL;
- w = FindWindowFromPt(_cursor.pos.x, _cursor.pos.y);
+ Window *w = FindWindowFromPt(_cursor.pos.x, _cursor.pos.y);
/* We changed window, put a MOUSEOVER event to the last window */
- if (last_w != NULL && last_w != w) {
+ if (_mouseover_last_w != NULL && _mouseover_last_w != w) {
+ /* Reset mouse-over coordinates of previous window */
e.event = WE_MOUSEOVER;
e.we.mouseover.pt.x = -1;
e.we.mouseover.pt.y = -1;
- if (last_w->wndproc) last_w->wndproc(last_w, &e);
+ if (_mouseover_last_w->wndproc != NULL) _mouseover_last_w->wndproc(_mouseover_last_w, &e);
}
- last_w = w;
+
+ /* _mouseover_last_w will get reset when the window is deleted, see DeleteWindow() */
+ _mouseover_last_w = w;
if (w != NULL) {
/* send an event in client coordinates. */
--- a/src/window_gui.h Mon Apr 14 16:24:00 2008 +0000
+++ b/src/window_gui.h Mon Apr 14 21:21:10 2008 +0000
@@ -10,6 +10,7 @@
#include "viewport_type.h"
#include "player_type.h"
#include "strings_type.h"
+#include "core/alloc_type.hpp"
/**
* The maximum number of windows that can be opened.
@@ -289,7 +290,7 @@
/**
* Data structure for an opened window
*/
-struct Window {
+struct Window : ZeroedMemoryAllocator {
uint16 flags4; ///< Window flags, @see WindowFlags
WindowClass window_class; ///< Window class
WindowNumber window_number; ///< Window number within the window class
@@ -307,7 +308,7 @@
byte caption_color; ///< Background color of the window caption, contains PlayerID
WindowProc *wndproc; ///< Event handler function for the window
- ViewPort *viewport; ///< Pointer to viewport, if present (structure is part of derived class)
+ ViewPort *viewport; ///< Pointer to viewport, if present
const Widget *original_widget; ///< Original widget layout, copied from WindowDesc
Widget *widget; ///< Widgets of the window
uint widget_count; ///< Number of widgets of the window
--- a/src/window_type.h Mon Apr 14 16:24:00 2008 +0000
+++ b/src/window_type.h Mon Apr 14 21:21:10 2008 +0000
@@ -7,6 +7,9 @@
#include "core/enum_type.hpp"
+/**
+ * Window classes
+ */
enum WindowClass {
WC_NONE,
WC_MAIN_WINDOW = WC_NONE,