(svn r12742) [NewGRF_ports] -Sync: with trunk r12673:12705.
--- a/source.list Wed Apr 16 00:07:47 2008 +0000
+++ b/source.list Wed Apr 16 22:16:04 2008 +0000
@@ -107,6 +107,7 @@
aircraft.h
airport.h
core/alloc_func.hpp
+core/alloc_type.hpp
articulated_vehicles.h
autoreplace_base.h
autoreplace_func.h
--- a/src/core/alloc_func.hpp Wed Apr 16 00:07:47 2008 +0000
+++ b/src/core/alloc_func.hpp Wed Apr 16 22:16:04 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 Wed Apr 16 22:16:04 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 Wed Apr 16 00:07:47 2008 +0000
+++ b/src/debug.h Wed Apr 16 22:16:04 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 Wed Apr 16 00:07:47 2008 +0000
+++ b/src/lang/english.txt Wed Apr 16 22:16:04 2008 +0000
@@ -2723,7 +2723,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}
@@ -2780,6 +2779,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 Wed Apr 16 00:07:47 2008 +0000
+++ b/src/misc.cpp Wed Apr 16 22:16:04 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 "table/strings.h"
#include "table/sprites.h"
--- a/src/misc_gui.cpp Wed Apr 16 00:07:47 2008 +0000
+++ b/src/misc_gui.cpp Wed Apr 16 22:16:04 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_gui.cpp Wed Apr 16 00:07:47 2008 +0000
+++ b/src/network/network_gui.cpp Wed Apr 16 22:16:04 2008 +0000
@@ -218,22 +218,27 @@
/** 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_DETAILS, ///< Panel with game details
+ NGWW_JOIN, ///< 'Join game' button
+ NGWW_REFRESH, ///< 'Refresh server' button
+ NGWW_NEWGRF, ///< 'NewGRF Settings' button
- NGWW_FIND = 15, ///< 'Find server' button
+ NGWW_FIND, ///< 'Find server' button
NGWW_ADD, ///< 'Add server' button
NGWW_START, ///< 'Start server' button
NGWW_CANCEL, ///< 'Cancel' button
@@ -579,10 +584,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 +597,8 @@
{ 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, 236, (11 << 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}, // NGWW_SCROLLBAR
/* RIGHT SIDE */
{ WWT_PANEL, RESIZE_LRB, BGC, 210, 440, 42, 236, 0x0, STR_NULL}, // NGWW_DETAILS
--- a/src/newgrf_station.cpp Wed Apr 16 00:07:47 2008 +0000
+++ b/src/newgrf_station.cpp Wed Apr 16 22:16:04 2008 +0000
@@ -755,7 +755,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);
@@ -793,6 +793,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 Wed Apr 16 00:07:47 2008 +0000
+++ b/src/news_gui.cpp Wed Apr 16 22:16:04 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 Wed Apr 16 00:07:47 2008 +0000
+++ b/src/news_type.h Wed Apr 16 22:16:04 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 Wed Apr 16 00:07:47 2008 +0000
+++ b/src/openttd.cpp Wed Apr 16 22:16:04 2008 +0000
@@ -2350,6 +2350,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;
@@ -2494,32 +2528,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 Wed Apr 16 00:07:47 2008 +0000
+++ b/src/order_cmd.cpp Wed Apr 16 22:16:04 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 Wed Apr 16 00:07:47 2008 +0000
+++ b/src/order_func.h Wed Apr 16 22:16:04 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 Wed Apr 16 00:07:47 2008 +0000
+++ b/src/order_gui.cpp Wed Apr 16 22:16:04 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 Wed Apr 16 00:07:47 2008 +0000
+++ b/src/pathfind.cpp Wed Apr 16 22:16:04 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 Wed Apr 16 00:07:47 2008 +0000
+++ b/src/player_gui.cpp Wed Apr 16 22:16:04 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 Wed Apr 16 00:07:47 2008 +0000
+++ b/src/road_cmd.cpp Wed Apr 16 22:16:04 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 Wed Apr 16 00:07:47 2008 +0000
+++ b/src/roadveh_cmd.cpp Wed Apr 16 22:16:04 2008 +0000
@@ -1708,7 +1708,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))) {
@@ -1718,8 +1718,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)) {
@@ -1747,10 +1746,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;
}
@@ -1806,6 +1810,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/ship_cmd.cpp Wed Apr 16 00:07:47 2008 +0000
+++ b/src/ship_cmd.cpp Wed Apr 16 22:16:04 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 Wed Apr 16 00:07:47 2008 +0000
+++ b/src/signs_gui.cpp Wed Apr 16 22:16:04 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/station_cmd.cpp Wed Apr 16 00:07:47 2008 +0000
+++ b/src/station_cmd.cpp Wed Apr 16 22:16:04 2008 +0000
@@ -2312,10 +2312,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) {
@@ -2517,9 +2521,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);
@@ -2547,6 +2551,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 Wed Apr 16 00:07:47 2008 +0000
+++ b/src/tgp.cpp Wed Apr 16 22:16:04 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 Wed Apr 16 00:07:47 2008 +0000
+++ b/src/timetable.h Wed Apr 16 22:16:04 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 Wed Apr 16 00:07:47 2008 +0000
+++ b/src/timetable_gui.cpp Wed Apr 16 22:16:04 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 Wed Apr 16 00:07:47 2008 +0000
+++ b/src/town_gui.cpp Wed Apr 16 22:16:04 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 Wed Apr 16 00:07:47 2008 +0000
+++ b/src/train_cmd.cpp Wed Apr 16 22:16:04 2008 +0000
@@ -2563,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 Wed Apr 16 00:07:47 2008 +0000
+++ b/src/vehicle.cpp Wed Apr 16 22:16:04 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();
}
--- a/src/vehicle_gui.cpp Wed Apr 16 00:07:47 2008 +0000
+++ b/src/vehicle_gui.cpp Wed Apr 16 22:16:04 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 Wed Apr 16 00:07:47 2008 +0000
+++ b/src/viewport.cpp Wed Apr 16 22:16:04 2008 +0000
@@ -28,7 +28,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 Wed Apr 16 00:07:47 2008 +0000
+++ b/src/widgets/dropdown.cpp Wed Apr 16 22:16:04 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 Wed Apr 16 00:07:47 2008 +0000
+++ b/src/widgets/dropdown_type.h Wed Apr 16 22:16:04 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 Wed Apr 16 00:07:47 2008 +0000
+++ b/src/window.cpp Wed Apr 16 22:16:04 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 Wed Apr 16 00:07:47 2008 +0000
+++ b/src/window_gui.h Wed Apr 16 22:16:04 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 Wed Apr 16 00:07:47 2008 +0000
+++ b/src/window_type.h Wed Apr 16 22:16:04 2008 +0000
@@ -7,6 +7,9 @@
#include "core/enum_type.hpp"
+/**
+ * Window classes
+ */
enum WindowClass {
WC_NONE,
WC_MAIN_WINDOW = WC_NONE,