mirror of https://github.com/OpenTTD/OpenTTD.git
(svn r9849) [0.5] -Backport from trunk (r9693, r9694, r9697, r9718, r9719, r9725 and 9726):
- Fix: Crash when destroying bridge with train partially on it [FS#738] (r9726) - Fix: Planes made a 270 degree turn instead of a 90 degree turn on the southern runway of the intercontinental airport [FS#743] (r9725) - Fix: In-game private messages did not work for clients with high ClientIDs (r9719) - Fix: Do not allow building of rail vehicles whose railtype is not available (r9718) - Fix: [YAPF] The guessed path was ignored for ships [FS#736] (r9694)
This commit is contained in:
parent
ac66e29910
commit
c9c087e858
|
@ -261,7 +261,7 @@ static const AirportMovingData _airport_moving_data_intercontinental[77] = {
|
|||
{ 136, 96, AMED_HELI_LOWER, 0 }, // 56 Land in front of hangar2
|
||||
{ 126, 104, 0, 3 }, // 57 Outway 2
|
||||
{ 136, 136, 0, 1 }, // 58 Airport OUTWAY 2
|
||||
{ 136, 152, AMED_EXACTPOS, 5 }, // 59 Accelerate to end of runway2
|
||||
{ 136, 152, AMED_EXACTPOS, 1 }, // 59 Accelerate to end of runway2
|
||||
{ 16, 152, AMED_NOSPDCLAMP, 0 }, // 60 Release control of runway2, for smoother movement
|
||||
{ 20, 152, AMED_NOSPDCLAMP, 0 }, // 61 End of runway2
|
||||
{ -56, 152, AMED_NOSPDCLAMP | AMED_TAKEOFF, 0 }, // 62 Take off2
|
||||
|
|
6
engine.c
6
engine.c
|
@ -414,6 +414,12 @@ bool IsEngineBuildable(EngineID engine, byte type, PlayerID player)
|
|||
// check if it's available
|
||||
if (!HASBIT(e->player_avail, player)) return false;
|
||||
|
||||
if (type == VEH_Train) {
|
||||
/* Check if the rail type is available to this player */
|
||||
const Player *p = GetPlayer(player);
|
||||
if (!HASBIT(p->avail_railtypes, EngInfo(engine)->railtype)) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -183,7 +183,7 @@ DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_CHAT)(NetworkAction action, DestType
|
|||
// Data:
|
||||
// uint8: ActionID (see network_data.h, NetworkAction)
|
||||
// uint8: Destination Type (see network_data.h, DestType);
|
||||
// uint8: Destination Player (1..MAX_PLAYERS)
|
||||
// uint16: Destination Player
|
||||
// String: Message (max MAX_TEXT_MSG_LEN)
|
||||
//
|
||||
|
||||
|
@ -191,7 +191,7 @@ DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_CHAT)(NetworkAction action, DestType
|
|||
|
||||
NetworkSend_uint8(p, action);
|
||||
NetworkSend_uint8(p, type);
|
||||
NetworkSend_uint8(p, dest);
|
||||
NetworkSend_uint16(p, dest);
|
||||
NetworkSend_string(p, msg);
|
||||
NetworkSend_Packet(p, MY_CLIENT);
|
||||
}
|
||||
|
|
|
@ -1479,7 +1479,7 @@ void ShowJoinStatusWindowAfterJoin(void)
|
|||
AllocateWindowDesc(&_network_join_status_window_desc);
|
||||
}
|
||||
|
||||
static void SendChat(const char *buf, DestType type, byte dest)
|
||||
static void SendChat(const char *buf, DestType type, int dest)
|
||||
{
|
||||
if (buf[0] == '\0') return;
|
||||
if (!_network_server) {
|
||||
|
@ -1543,7 +1543,7 @@ static char *ChatTabCompletionFindText(char *buf)
|
|||
static void ChatTabCompletion(Window *w)
|
||||
{
|
||||
static char _chat_tab_completion_buf[lengthof(_edit_str_buf)];
|
||||
Textbuf *tb = &WP(w, querystr_d).text;
|
||||
Textbuf *tb = &WP(w, chatquerystr_d).text;
|
||||
uint len, tb_len;
|
||||
uint item;
|
||||
char *tb_buf, *pre_buf;
|
||||
|
@ -1601,7 +1601,7 @@ static void ChatTabCompletion(Window *w)
|
|||
}
|
||||
|
||||
/* Update the textbuffer */
|
||||
UpdateTextBufferSize(&WP(w, querystr_d).text);
|
||||
UpdateTextBufferSize(&WP(w, chatquerystr_d).text);
|
||||
|
||||
SetWindowDirty(w);
|
||||
free(pre_buf);
|
||||
|
@ -1615,17 +1615,17 @@ static void ChatTabCompletion(Window *w)
|
|||
_chat_tab_completion_active = false;
|
||||
|
||||
/* Update the textbuffer */
|
||||
UpdateTextBufferSize(&WP(w, querystr_d).text);
|
||||
UpdateTextBufferSize(&WP(w, chatquerystr_d).text);
|
||||
|
||||
SetWindowDirty(w);
|
||||
}
|
||||
free(pre_buf);
|
||||
}
|
||||
|
||||
/* uses querystr_d WP macro
|
||||
* uses querystr_d->caption to store
|
||||
* - type of chat message (Private/Team/All) in bytes 0-7
|
||||
* - destination of chat message in the case of Team/Private in bytes 8-15 */
|
||||
/*
|
||||
* uses chatquerystr_d WP macro
|
||||
* uses chatquerystr_d->caption to store type of chat message (Private/Team/All)
|
||||
*/
|
||||
static void ChatWindowWndProc(Window *w, WindowEvent *e)
|
||||
{
|
||||
switch (e->event) {
|
||||
|
@ -1644,25 +1644,25 @@ static void ChatWindowWndProc(Window *w, WindowEvent *e)
|
|||
|
||||
DrawWindowWidgets(w);
|
||||
|
||||
assert(GB(WP(w, querystr_d).caption, 0, 8) < lengthof(chat_captions));
|
||||
msg = chat_captions[GB(WP(w, querystr_d).caption, 0, 8)];
|
||||
assert(WP(w, chatquerystr_d).caption < lengthof(chat_captions));
|
||||
msg = chat_captions[WP(w, chatquerystr_d).caption];
|
||||
DrawStringRightAligned(w->widget[2].left - 2, w->widget[2].top + 1, msg, 16);
|
||||
DrawEditBox(w, &WP(w, querystr_d), 2);
|
||||
DrawEditBox(w, &WP(w, chatquerystr_d), 2);
|
||||
} break;
|
||||
|
||||
case WE_CLICK:
|
||||
switch (e->we.click.widget) {
|
||||
case 3: { /* Send */
|
||||
DestType type = GB(WP(w, querystr_d).caption, 0, 8);
|
||||
byte dest = GB(WP(w, querystr_d).caption, 8, 8);
|
||||
SendChat(WP(w, querystr_d).text.buf, type, dest);
|
||||
DestType type = (DestType)WP(w, chatquerystr_d).caption;
|
||||
int dest = WP(w, chatquerystr_d).dest;
|
||||
SendChat(WP(w, chatquerystr_d).text.buf, type, dest);
|
||||
} /* FALLTHROUGH */
|
||||
case 0: /* Cancel */ DeleteWindow(w); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case WE_MOUSELOOP:
|
||||
HandleEditBox(w, &WP(w, querystr_d), 2);
|
||||
HandleEditBox(w, &WP(w, chatquerystr_d), 2);
|
||||
break;
|
||||
|
||||
case WE_KEYPRESS:
|
||||
|
@ -1670,11 +1670,11 @@ static void ChatWindowWndProc(Window *w, WindowEvent *e)
|
|||
ChatTabCompletion(w);
|
||||
} else {
|
||||
_chat_tab_completion_active = false;
|
||||
switch (HandleEditBoxKey(w, &WP(w, querystr_d), 2, e)) {
|
||||
switch (HandleEditBoxKey(w, &WP(w, chatquerystr_d), 2, e)) {
|
||||
case 1: { /* Return */
|
||||
DestType type = GB(WP(w, querystr_d).caption, 0, 8);
|
||||
byte dest = GB(WP(w, querystr_d).caption, 8, 8);
|
||||
SendChat(WP(w, querystr_d).text.buf, type, dest);
|
||||
DestType type = (DestType)WP(w, chatquerystr_d).caption;
|
||||
int dest = WP(w, chatquerystr_d).dest;
|
||||
SendChat(WP(w, chatquerystr_d).text.buf, type, dest);
|
||||
} /* FALLTHROUGH */
|
||||
case 2: /* Escape */ DeleteWindow(w); break;
|
||||
}
|
||||
|
@ -1704,7 +1704,7 @@ static const WindowDesc _chat_window_desc = {
|
|||
ChatWindowWndProc
|
||||
};
|
||||
|
||||
void ShowNetworkChatQueryWindow(DestType type, byte dest)
|
||||
void ShowNetworkChatQueryWindow(DestType type, int dest)
|
||||
{
|
||||
Window *w;
|
||||
|
||||
|
@ -1716,11 +1716,12 @@ void ShowNetworkChatQueryWindow(DestType type, byte dest)
|
|||
w = AllocateWindowDesc(&_chat_window_desc);
|
||||
|
||||
LowerWindowWidget(w, 2);
|
||||
WP(w,querystr_d).caption = GB(type, 0, 8) | (dest << 8); // Misuse of caption
|
||||
WP(w,querystr_d).wnd_class = WC_MAIN_TOOLBAR;
|
||||
WP(w,querystr_d).wnd_num = 0;
|
||||
WP(w,querystr_d).afilter = CS_ALPHANUMERAL;
|
||||
InitializeTextBuffer(&WP(w, querystr_d).text, _edit_str_buf, lengthof(_edit_str_buf), 0);
|
||||
WP(w, chatquerystr_d).caption = type; // Misuse of caption
|
||||
WP(w, chatquerystr_d).dest = dest;
|
||||
WP(w, chatquerystr_d).afilter = CS_ALPHANUMERAL;
|
||||
WP(w, chatquerystr_d).wnd_class = WC_MAIN_TOOLBAR;
|
||||
WP(w, chatquerystr_d).wnd_num = 0;
|
||||
InitializeTextBuffer(&WP(w, chatquerystr_d).text, _edit_str_buf, lengthof(_edit_str_buf), 0);
|
||||
}
|
||||
|
||||
#endif /* ENABLE_NETWORK */
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
void ShowNetworkNeedPassword(NetworkPasswordType npt);
|
||||
void ShowNetworkGiveMoneyWindow(byte player); // PlayerID
|
||||
void ShowNetworkChatQueryWindow(DestType type, byte dest);
|
||||
void ShowNetworkChatQueryWindow(DestType type, int dest);
|
||||
void ShowJoinStatusWindowAfterJoin(void);
|
||||
void ShowNetworkGameWindow(void);
|
||||
void ShowClientList(void);
|
||||
|
@ -17,7 +17,7 @@ void ShowClientList(void);
|
|||
#else /* ENABLE_NETWORK */
|
||||
/* Network function stubs when networking is disabled */
|
||||
|
||||
static inline void ShowNetworkChatQueryWindow(byte desttype, byte dest) {}
|
||||
static inline void ShowNetworkChatQueryWindow(byte desttype, int dest) {}
|
||||
static inline void ShowClientList(void) {}
|
||||
static inline void ShowJoinStatusWindowAfterJoin(void) {}
|
||||
static inline void ShowNetworkGameWindow(void) {}
|
||||
|
|
|
@ -1119,7 +1119,7 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_CHAT)
|
|||
{
|
||||
NetworkAction action = NetworkRecv_uint8(cs, p);
|
||||
DestType desttype = NetworkRecv_uint8(cs, p);
|
||||
int dest = NetworkRecv_uint8(cs, p);
|
||||
int dest = NetworkRecv_uint16(cs, p);
|
||||
char msg[MAX_TEXT_MSG_LEN];
|
||||
|
||||
NetworkRecv_string(cs, p, msg, MAX_TEXT_MSG_LEN);
|
||||
|
|
|
@ -675,7 +675,7 @@ static int32 DoClearBridge(TileIndex tile, uint32 flags)
|
|||
|
||||
endtile = GetOtherBridgeEnd(tile);
|
||||
|
||||
if (!EnsureNoVehicleOnGround(tile) || !EnsureNoVehicleOnGround(endtile)) return CMD_ERROR;
|
||||
if (!EnsureNoVehicle(tile) || !EnsureNoVehicle(endtile)) return CMD_ERROR;
|
||||
|
||||
direction = GetBridgeRampDirection(tile);
|
||||
delta = TileOffsByDiagDir(direction);
|
||||
|
@ -828,8 +828,8 @@ int32 DoConvertTunnelBridgeRail(TileIndex tile, RailType totype, bool exec)
|
|||
|
||||
endtile = GetOtherBridgeEnd(tile);
|
||||
|
||||
if (!EnsureNoVehicleOnGround(tile) ||
|
||||
!EnsureNoVehicleOnGround(endtile) ||
|
||||
if (!EnsureNoVehicle(tile) ||
|
||||
!EnsureNoVehicle(endtile) ||
|
||||
FindVehicleBetween(tile, endtile, GetBridgeHeightRamp(tile), false) != NULL) {
|
||||
return_cmd_error(STR_8803_TRAIN_IN_THE_WAY);
|
||||
}
|
||||
|
|
11
window.h
11
window.h
|
@ -348,6 +348,17 @@ typedef struct querystr_d {
|
|||
} querystr_d;
|
||||
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(querystr_d));
|
||||
|
||||
typedef struct chatquerystr_d {
|
||||
StringID caption;
|
||||
WindowClass wnd_class;
|
||||
WindowNumber wnd_num;
|
||||
Textbuf text;
|
||||
const char *orig;
|
||||
CharSetFilter afilter;
|
||||
int dest;
|
||||
} chatquerystr_d;
|
||||
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(chatquerystr_d));
|
||||
|
||||
typedef struct query_d {
|
||||
StringID caption;
|
||||
StringID message;
|
||||
|
|
|
@ -117,7 +117,8 @@ public:
|
|||
while (true) {
|
||||
m_num_steps++;
|
||||
Node *n = m_nodes.GetBestOpenNode();
|
||||
if (n == NULL) break;
|
||||
if (n == NULL)
|
||||
break;
|
||||
|
||||
// if the best open node was worse than the best path found, we can finish
|
||||
if (m_pBestDestNode != NULL && m_pBestDestNode->GetCost() < n->GetCostEstimate())
|
||||
|
@ -159,9 +160,9 @@ public:
|
|||
/** If path was found return the best node that has reached the destination. Otherwise
|
||||
* return the best visited node (which was nearest to the destination).
|
||||
*/
|
||||
FORCEINLINE Node& GetBestNode()
|
||||
FORCEINLINE Node* GetBestNode()
|
||||
{
|
||||
return (m_pBestDestNode != NULL) ? *m_pBestDestNode : *m_pBestIntermediateNode;
|
||||
return (m_pBestDestNode != NULL) ? m_pBestDestNode : m_pBestIntermediateNode;
|
||||
}
|
||||
|
||||
/** Calls NodeList::CreateNewNode() - allocates new node that can be filled and used
|
||||
|
|
|
@ -59,11 +59,11 @@ public:
|
|||
|
||||
// some path found
|
||||
// get found depot tile
|
||||
Node& n = Yapf().GetBestNode();
|
||||
*depot_tile = n.GetLastTile();
|
||||
Node *n = Yapf().GetBestNode();
|
||||
*depot_tile = n->GetLastTile();
|
||||
|
||||
// walk through the path back to the origin
|
||||
Node* pNode = &n;
|
||||
Node *pNode = n;
|
||||
while (pNode->m_parent != NULL) {
|
||||
pNode = pNode->m_parent;
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ public:
|
|||
|
||||
// if path not found - return INVALID_TRACKDIR
|
||||
Trackdir next_trackdir = INVALID_TRACKDIR;
|
||||
Node* pNode = &Yapf().GetBestNode();
|
||||
Node *pNode = Yapf().GetBestNode();
|
||||
if (pNode != NULL) {
|
||||
// path was found or at least suggested
|
||||
// walk through the path back to the origin
|
||||
|
@ -163,7 +163,7 @@ public:
|
|||
|
||||
// path was found
|
||||
// walk through the path back to the origin
|
||||
Node* pNode = &Yapf().GetBestNode();
|
||||
Node *pNode = Yapf().GetBestNode();
|
||||
while (pNode->m_parent != NULL) {
|
||||
pNode = pNode->m_parent;
|
||||
}
|
||||
|
|
|
@ -278,7 +278,7 @@ public:
|
|||
|
||||
// if path not found - return INVALID_TRACKDIR
|
||||
Trackdir next_trackdir = INVALID_TRACKDIR;
|
||||
Node* pNode = &Yapf().GetBestNode();
|
||||
Node *pNode = Yapf().GetBestNode();
|
||||
if (pNode != NULL) {
|
||||
// path was found or at least suggested
|
||||
// walk through the path back to its origin
|
||||
|
@ -320,7 +320,7 @@ public:
|
|||
|
||||
// if path not found - return distance = UINT_MAX
|
||||
uint dist = UINT_MAX;
|
||||
Node* pNode = &Yapf().GetBestNode();
|
||||
Node *pNode = Yapf().GetBestNode();
|
||||
if (pNode != NULL) {
|
||||
// path was found or at least suggested
|
||||
// get the path cost estimate
|
||||
|
@ -362,8 +362,8 @@ public:
|
|||
|
||||
// some path found
|
||||
// get found depot tile
|
||||
Node& n = Yapf().GetBestNode();
|
||||
TileIndex depot_tile = n.m_segment_last_tile;
|
||||
Node *n = Yapf().GetBestNode();
|
||||
TileIndex depot_tile = n->m_segment_last_tile;
|
||||
assert(IsTileDepotType(depot_tile, TRANSPORT_ROAD));
|
||||
Depot* ret = GetDepotByTile(depot_tile);
|
||||
return ret;
|
||||
|
|
|
@ -59,13 +59,13 @@ public:
|
|||
pf.SetOrigin(src_tile, trackdirs);
|
||||
pf.SetDestination(v->dest_tile, dest_trackdirs);
|
||||
// find best path
|
||||
bool bFound = pf.FindPath(v);
|
||||
pf.FindPath(v);
|
||||
|
||||
Trackdir next_trackdir = INVALID_TRACKDIR; // this would mean "path not found"
|
||||
if (bFound) {
|
||||
// path was found
|
||||
|
||||
Node* pNode = pf.GetBestNode();
|
||||
if (pNode != NULL) {
|
||||
// walk through the path back to the origin
|
||||
Node* pNode = &pf.GetBestNode();
|
||||
Node* pPrevNode = NULL;
|
||||
while (pNode->m_parent != NULL) {
|
||||
pPrevNode = pNode;
|
||||
|
|
Loading…
Reference in New Issue