/** Do a forced show of a specific message */ static void ShowNewsMessage(const NewsItem *ni) { assert(_total_news != 0); /* Delete the news window */ DeleteWindowById(WC_NEWS_WINDOW, 0); /* setup forced news item */ _forced_news = ni; if (_forced_news != NULL) { DeleteWindowById(WC_NEWS_WINDOW, 0); ShowNewspaper(ni); } }
/** * Handle an error coming from the client side. * @param res The "error" that happened. */ void ClientNetworkGameSocketHandler::ClientError(NetworkRecvStatus res) { /* First, send a CLIENT_ERROR to the server, so he knows we are * disconnection (and why!) */ NetworkErrorCode errorno; /* We just want to close the connection.. */ if (res == NETWORK_RECV_STATUS_CLOSE_QUERY) { this->NetworkSocketHandler::CloseConnection(); this->CloseConnection(res); _networking = false; DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0); return; } switch (res) { case NETWORK_RECV_STATUS_DESYNC: errorno = NETWORK_ERROR_DESYNC; break; case NETWORK_RECV_STATUS_SAVEGAME: errorno = NETWORK_ERROR_SAVEGAME_FAILED; break; case NETWORK_RECV_STATUS_NEWGRF_MISMATCH: errorno = NETWORK_ERROR_NEWGRF_MISMATCH; break; default: errorno = NETWORK_ERROR_GENERAL; break; } /* This means we f****d up and the server closed the connection */ if (res != NETWORK_RECV_STATUS_SERVER_ERROR && res != NETWORK_RECV_STATUS_SERVER_FULL && res != NETWORK_RECV_STATUS_SERVER_BANNED) { SendError(errorno); } _switch_mode = SM_MENU; this->CloseConnection(res); _networking = false; }
DEF_CONTENT_RECEIVE_COMMAND(Client, PACKET_CONTENT_SERVER_CONTENT) { if (this->curFile == NULL) { delete this->curInfo; /* When we haven't opened a file this must be our first packet with metadata. */ this->curInfo = new ContentInfo; this->curInfo->type = (ContentType)p->Recv_uint8(); this->curInfo->id = (ContentID)p->Recv_uint32(); this->curInfo->filesize = p->Recv_uint32(); p->Recv_string(this->curInfo->filename, lengthof(this->curInfo->filename)); if (!this->BeforeDownload()) { this->Close(); return false; } } else { /* We have a file opened, thus are downloading internal content */ size_t toRead = (size_t)(p->size - p->pos); if (fwrite(p->buffer + p->pos, 1, toRead, this->curFile) != toRead) { DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0); ShowErrorMessage(STR_CONTENT_ERROR_COULD_NOT_DOWNLOAD_FILE_NOT_WRITABLE, STR_CONTENT_ERROR_COULD_NOT_DOWNLOAD, WL_ERROR); this->Close(); fclose(this->curFile); this->curFile = NULL; return false; } this->OnDownloadProgress(this->curInfo, (uint)toRead); if (toRead == 0) this->AfterDownload(); } return true; }
/** Move to the next news item */ static void MoveToNextItem() { InvalidateWindowData(WC_STATUS_BAR, 0, SBI_NEWS_DELETED); // invalidate the statusbar DeleteWindowById(WC_NEWS_WINDOW, 0); // close the newspapers window if shown _forced_news = NULL; _statusbar_news_item = NULL; /* if we're not at the last item, then move on */ if (_current_news != _latest_news) { _current_news = (_current_news == NULL) ? _oldest_news : _current_news->next; const NewsItem *ni = _current_news; const NewsType type = ni->type; /* check the date, don't show too old items */ if (_date - _news_type_data[type].age > ni->date) return; switch (_news_type_data[type].GetDisplay()) { default: NOT_REACHED(); case ND_OFF: // Off - show nothing only a small reminder in the status bar InvalidateWindowData(WC_STATUS_BAR, 0, SBI_SHOW_REMINDER); break; case ND_SUMMARY: // Summary - show ticker ShowTicker(ni); break; case ND_FULL: // Full - show newspaper ShowNewspaper(ni); break; } } }
/** * Show the on-screen keyboard (osk) associated with a given textbox * @param parent pointer to the Window where this keyboard originated from * @param button widget number of parent's textbox */ void ShowOnScreenKeyboard(Window *parent, int button) { DeleteWindowById(WC_OSK, 0); GetKeyboardLayout(); new OskWindow(&_osk_desc, parent, button); }
/** * Show a drop down list. * @param w Parent window for the list. * @param list Prepopulated DropDownList. Will be deleted when the list is * closed. * @param selected The initially selected list item. * @param button The widget which is passed to Window::OnDropdownSelect and OnDropdownClose. * Unless you override those functions, this should be then widget index of the dropdown button. * @param wi_rect Coord of the parent drop down button, used to position the dropdown menu. * @param auto_width The width is determined by the widest item in the list, * in this case only one of \a left or \a right is used (depending on text direction). * @param instant_close Set to true if releasing mouse button should close the * list regardless of where the cursor is. */ void ShowDropDownListAt(Window *w, DropDownList *list, int selected, int button, Rect wi_rect, Colours wi_colour, bool auto_width, bool instant_close) { DeleteWindowById(WC_DROPDOWN_MENU, 0); /* The preferred position is just below the dropdown calling widget */ int top = w->top + wi_rect.bottom + 1; /* The preferred width equals the calling widget */ uint width = wi_rect.right - wi_rect.left + 1; uint max_item_width = 0; if (auto_width) { /* Find the longest item in the list */ for (DropDownList::const_iterator it = list->begin(); it != list->end(); ++it) { const DropDownListItem *item = *it; max_item_width = max(max_item_width, item->Width() + 5); } } /* Total length of list */ int list_height = 0; for (DropDownList::const_iterator it = list->begin(); it != list->end(); ++it) { DropDownListItem *item = *it; list_height += item->Height(width); } /* Height of window visible */ int height = list_height; /* Check if the status bar is visible, as we don't want to draw over it */ int screen_bottom = GetMainViewBottom(); bool scroll = false; /* Check if the dropdown will fully fit below the widget */ if (top + height + 4 >= screen_bottom) { /* If not, check if it will fit above the widget */ if (w->top + wi_rect.top - height > GetMainViewTop()) { top = w->top + wi_rect.top - height - 4; } else { /* ... and lastly if it won't, enable the scroll bar and fit the * list in below the widget */ int avg_height = list_height / (int)list->size(); int rows = (screen_bottom - 4 - top) / avg_height; height = rows * avg_height; scroll = true; /* Add space for the scroll bar if we automatically determined * the width of the list. */ max_item_width += NWidgetScrollbar::GetVerticalDimension().width; } } if (auto_width) width = max(width, max_item_width); Point dw_pos = { w->left + (_current_text_dir == TD_RTL ? wi_rect.right + 1 - width : wi_rect.left), top}; Dimension dw_size = {width, height}; new DropdownWindow(w, list, selected, button, instant_close, dw_pos, dw_size, wi_colour, scroll); }
BaseStation::~BaseStation() { free(this->name); free(this->speclist); if (CleaningPool()) return; Owner owner = this->owner; if (!Company::IsValidID(owner)) owner = _local_company; WindowNumber wno = (this->index << 16) | VLW_STATION_LIST | owner; DeleteWindowById(WC_TRAINS_LIST, wno | (VEH_TRAIN << 11)); DeleteWindowById(WC_ROADVEH_LIST, wno | (VEH_ROAD << 11)); DeleteWindowById(WC_SHIPS_LIST, wno | (VEH_SHIP << 11)); DeleteWindowById(WC_AIRCRAFT_LIST, wno | (VEH_AIRCRAFT << 11)); this->sign.MarkDirty(); }
DEF_GAME_RECEIVE_COMMAND(Client, PACKET_SERVER_BANNED) { /* We try to join a server where we are banned */ _switch_mode_errorstr = STR_NETWORK_ERROR_SERVER_BANNED; DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0); return NETWORK_RECV_STATUS_SERVER_BANNED; }
DEF_GAME_RECEIVE_COMMAND(Client, PACKET_SERVER_FULL) { /* We try to join a server which is full */ _switch_mode_errorstr = STR_NETWORK_ERROR_SERVER_FULL; DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0); return NETWORK_RECV_STATUS_SERVER_FULL; }
BaseStation::~BaseStation() { free(this->name); free(this->speclist); if (CleaningPool()) return; Owner owner = this->owner; if (!Company::IsValidID(owner)) owner = _local_company; if (!Company::IsValidID(owner)) return; // Spectators DeleteWindowById(WC_TRAINS_LIST, VehicleListIdentifier(VL_STATION_LIST, VEH_TRAIN, owner, this->index).Pack()); DeleteWindowById(WC_ROADVEH_LIST, VehicleListIdentifier(VL_STATION_LIST, VEH_ROAD, owner, this->index).Pack()); DeleteWindowById(WC_SHIPS_LIST, VehicleListIdentifier(VL_STATION_LIST, VEH_SHIP, owner, this->index).Pack()); DeleteWindowById(WC_AIRCRAFT_LIST, VehicleListIdentifier(VL_STATION_LIST, VEH_AIRCRAFT, owner, this->index).Pack()); this->sign.MarkDirty(); }
/** * Clean up a station by clearing vehicle orders and invalidating windows. * Aircraft-Hangar orders need special treatment here, as the hangars are * actually part of a station (tiletype is STATION), but the order type * is OT_GOTO_DEPOT. */ Station::~Station() { if (CleaningPool()) return; while (!this->loading_vehicles.empty()) { this->loading_vehicles.front()->LeaveStation(); } Aircraft *a; FOR_ALL_AIRCRAFT(a) { if (!a->IsNormalAircraft()) continue; if (a->targetairport == this->index) a->targetairport = INVALID_STATION; } Vehicle *v; FOR_ALL_VEHICLES(v) { /* Forget about this station if this station is removed */ if (v->last_station_visited == this->index) { v->last_station_visited = INVALID_STATION; } } this->sign.MarkDirty(); InvalidateWindowData(WC_STATION_LIST, this->owner, 0); DeleteWindowById(WC_STATION_VIEW, index); WindowNumber wno = (this->index << 16) | VLW_STATION_LIST | this->owner; DeleteWindowById(WC_TRAINS_LIST, wno | (VEH_TRAIN << 11)); DeleteWindowById(WC_ROADVEH_LIST, wno | (VEH_ROAD << 11)); DeleteWindowById(WC_SHIPS_LIST, wno | (VEH_SHIP << 11)); DeleteWindowById(WC_AIRCRAFT_LIST, wno | (VEH_AIRCRAFT << 11)); /* Now delete all orders that go to the station */ RemoveOrderFromAllVehicles(OT_GOTO_STATION, this->index); /* Remove all news items */ DeleteStationNews(this->index); for (CargoID c = 0; c < NUM_CARGO; c++) { this->goods[c].cargo.Truncate(0); } CargoPacket::InvalidateAllFrom(this->index); }
DEF_GAME_RECEIVE_COMMAND(Client, PACKET_SERVER_MAP_DONE) { if (this->status != STATUS_MAP) return NETWORK_RECV_STATUS_MALFORMED_PACKET; if (this->savegame == NULL) return NETWORK_RECV_STATUS_MALFORMED_PACKET; _network_join_status = NETWORK_JOIN_STATUS_PROCESSING; SetWindowDirty(WC_NETWORK_STATUS_WINDOW, 0); /* * Make sure everything is set for reading. * * We need the local copy and reset this->savegame because when * loading fails the network gets reset upon loading the intro * game, which would cause us to free this->savegame twice. */ LoadFilter *lf = this->savegame; this->savegame = NULL; lf->Reset(); /* The map is done downloading, load it */ bool load_success = SafeLoad(NULL, SL_LOAD, GM_NORMAL, NO_DIRECTORY, lf); /* Long savegame loads shouldn't affect the lag calculation! */ this->last_packet = _realtime_tick; if (!load_success) { DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0); _switch_mode_errorstr = STR_NETWORK_ERROR_SAVEGAMEERROR; return NETWORK_RECV_STATUS_SAVEGAME; } /* If the savegame has successfully loaded, ALL windows have been removed, * only toolbar/statusbar and gamefield are visible */ /* Say we received the map and loaded it correctly! */ SendMapOk(); /* New company/spectator (invalid company) or company we want to join is not active * Switch local company to spectator and await the server's judgement */ if (_network_join_as == COMPANY_NEW_COMPANY || !Company::IsValidID(_network_join_as)) { SetLocalCompany(COMPANY_SPECTATOR); if (_network_join_as != COMPANY_SPECTATOR) { /* We have arrived and ready to start playing; send a command to make a new company; * the server will give us a client-id and let us in */ _network_join_status = NETWORK_JOIN_STATUS_REGISTERING; ShowJoinStatusWindow(); NetworkSendCommand(0, 0, 0, CMD_COMPANY_CTRL, NULL, NULL, _local_company); } } else { /* take control over an existing company */ SetLocalCompany(_network_join_as); } return NETWORK_RECV_STATUS_OKAY; }
/* static */ void ScriptWindow::Close(WindowClass window, uint32 number) { if (ScriptGame::IsMultiplayer()) return; if (number == NUMBER_ALL) { DeleteWindowByClass((::WindowClass)window); return; } DeleteWindowById((::WindowClass)window, number); }
virtual void OnClick(Point pt, int widget, int click_count) { if (widget == WID_NCDS_CANCELOK) { if (this->downloaded_bytes != this->total_bytes) { _network_content_client.Close(); delete this; } else { /* If downloading succeeded, close the online content window. This will close * the current window as well. */ DeleteWindowById(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_CONTENT_LIST); } } }
/** * Clean up a station by clearing vehicle orders, invalidating windows and * removing link stats. * Aircraft-Hangar orders need special treatment here, as the hangars are * actually part of a station (tiletype is STATION), but the order type * is OT_GOTO_DEPOT. */ Station::~Station() { if (CleaningPool()) return; while (!this->loading_vehicles.empty()) { this->loading_vehicles.front()->LeaveStation(); } Aircraft *a; FOR_ALL_AIRCRAFT(a) { if (!a->IsNormalAircraft()) continue; if (a->targetairport == this->index) a->targetairport = INVALID_STATION; } Station *st; FOR_ALL_STATIONS(st) { for (CargoID c = 0; c < NUM_CARGO; ++c) { GoodsEntry &ge = st->goods[c]; ge.link_stats.erase(this->index); DeleteStaleFlows(st->index, c, this->index); ge.cargo.RerouteStalePackets(this->index); } } Vehicle *v; FOR_ALL_VEHICLES(v) { /* Forget about this station if this station is removed */ if (v->last_station_visited == this->index) { v->last_station_visited = INVALID_STATION; } if (v->last_loading_station == this->index) { v->last_loading_station = INVALID_STATION; } } InvalidateWindowData(WC_STATION_LIST, this->owner, 0); DeleteWindowById(WC_STATION_VIEW, index); /* Now delete all orders that go to the station */ RemoveOrderFromAllVehicles(OT_GOTO_STATION, this->index); /* Remove all news items */ DeleteStationNews(this->index); for (CargoID c = 0; c < NUM_CARGO; c++) { this->goods[c].cargo.Truncate(0); } CargoPacket::InvalidateAllFrom(this->index); }
/** * Clean up a station by clearing vehicle orders and invalidating windows. * Aircraft-Hangar orders need special treatment here, as the hangars are * actually part of a station (tiletype is STATION), but the order type * is OT_GOTO_DEPOT. */ Station::~Station() { if (CleaningPool()) { for (CargoID c = 0; c < NUM_CARGO; c++) { this->goods[c].cargo.OnCleanPool(); } return; } while (!this->loading_vehicles.empty()) { this->loading_vehicles.front()->LeaveStation(); } Aircraft *a; FOR_ALL_AIRCRAFT(a) { if (!a->IsNormalAircraft()) continue; if (a->targetairport == this->index) a->targetairport = INVALID_STATION; } Vehicle *v; FOR_ALL_VEHICLES(v) { /* Forget about this station if this station is removed */ if (v->last_station_visited == this->index) { v->last_station_visited = INVALID_STATION; } } /* Clear the persistent storage. */ delete this->airport.psa; if (this->owner == OWNER_NONE) { /* Invalidate all in case of oil rigs. */ InvalidateWindowClassesData(WC_STATION_LIST, 0); } else { InvalidateWindowData(WC_STATION_LIST, this->owner, 0); } DeleteWindowById(WC_STATION_VIEW, index); /* Now delete all orders that go to the station */ RemoveOrderFromAllVehicles(OT_GOTO_STATION, this->index); /* Remove all news items */ DeleteStationNews(this->index); for (CargoID c = 0; c < NUM_CARGO; c++) { this->goods[c].cargo.Truncate(0); } CargoPacket::InvalidateAllFrom(this->index); }
/** * Reply to a goal question. * @param tile unused. * @param flags type of operation * @param p1 Unique ID to use for this question. * @param p2 Button the company pressed * @param text Text of the question. * @return the cost of this operation or an error */ CommandCost CmdGoalQuestionAnswer(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { if (p1 > UINT16_MAX) return CMD_ERROR; if (p2 >= GOAL_QUESTION_BUTTON_COUNT) return CMD_ERROR; if (_current_company == OWNER_DEITY) { /* It has been requested to close this specific question on all clients */ if (flags & DC_EXEC) DeleteWindowById(WC_GOAL_QUESTION, p1); return CommandCost(); } if (_networking && _local_company == _current_company) { /* Somebody in the same company answered the question. Close the window */ if (flags & DC_EXEC) DeleteWindowById(WC_GOAL_QUESTION, p1); if (!_network_server) return CommandCost(); } if (flags & DC_EXEC) { Game::NewEvent(new ScriptEventGoalQuestionAnswer(p1, (ScriptCompany::CompanyID)(byte)_current_company, (ScriptGoal::QuestionButton)(1 << p2))); } return CommandCost(); }
/** Toggle in-game console between opened and closed. */ void IConsoleSwitch() { switch (_iconsole_mode) { case ICONSOLE_CLOSED: new IConsoleWindow(); break; case ICONSOLE_OPENED: case ICONSOLE_FULL: DeleteWindowById(WC_CONSOLE, 0); break; } MarkWholeScreenDirty(); }
/* static */ void AI::Stop(CompanyID company) { if (_networking && !_network_server) return; Backup<CompanyByte> cur_company(_current_company, company, FILE_LINE); Company *c = Company::Get(company); delete c->ai_instance; c->ai_instance = NULL; cur_company.Restore(); InvalidateWindowData(WC_AI_DEBUG, 0, -1); DeleteWindowById(WC_AI_SETTINGS, company); }
/** * Clean up the 'mess' of generation. That is, show windows again, reset * thread variables, and delete the progress window. */ static void CleanupGeneration() { _generating_world = false; if (_cursor.sprite == SPR_CURSOR_ZZZ) SetMouseCursor(SPR_CURSOR_MOUSE, PAL_NONE); /* Show all vital windows again, because we have hidden them */ if (_gw.threaded && _game_mode != GM_MENU) ShowVitalWindows(); _gw.active = false; _gw.proc = NULL; _gw.abortp = NULL; _gw.threaded = false; DeleteWindowById(WC_GENERATE_PROGRESS_WINDOW, 0); MarkWholeScreenDirty(); }
/** * Launch save/load dialog in the given mode. * @param abstract_filetype Kind of file to handle. * @param fop File operation to perform (load or save). */ void ShowSaveLoadDialog(AbstractFileType abstract_filetype, SaveLoadOperation fop) { DeleteWindowById(WC_SAVELOAD, 0); WindowDesc *sld; if (fop == SLO_SAVE) { sld = &_save_dialog_desc; } else { /* Dialogue for loading a file. */ sld = (abstract_filetype == FT_HEIGHTMAP) ? &_load_heightmap_dialog_desc : &_load_dialog_desc; } _file_to_saveload.abstract_ftype = abstract_filetype; new SaveLoadWindow(sld, abstract_filetype, fop); }
/* static */ void AI::Stop(CompanyID company) { if (_networking && !_network_server) return; CompanyID old_company = _current_company; _current_company = company; Company *c = Company::Get(company); delete c->ai_instance; c->ai_instance = NULL; _current_company = old_company; InvalidateWindowData(WC_AI_DEBUG, 0, -1); DeleteWindowById(WC_AI_SETTINGS, company); }
/** * Show the content list window with a given set of content * @param cv the content to show, or NULL when it has to search for itself * @param type the type to (only) show */ void ShowNetworkContentListWindow(ContentVector *cv, ContentType type) { #if defined(WITH_ZLIB) _network_content_client.Clear(); if (cv == NULL) { _network_content_client.RequestContentList(type); } else { _network_content_client.RequestContentList(cv, true); } DeleteWindowById(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_CONTENT_LIST); new NetworkContentListWindow(&_network_content_list_desc, cv != NULL); #else ShowErrorMessage(STR_CONTENT_NO_ZLIB, STR_CONTENT_NO_ZLIB_SUB, WL_ERROR); /* Connection failed... clean up the mess */ if (cv != NULL) { for (ContentIterator iter = cv->Begin(); iter != cv->End(); iter++) delete *iter; } #endif /* WITH_ZLIB */ }
/** * Handle the opening of the file before downloading. * @return false on any error. */ bool ClientNetworkContentSocketHandler::BeforeDownload() { if (!this->curInfo->IsValid()) { delete this->curInfo; this->curInfo = NULL; return false; } if (this->curInfo->filesize != 0) { /* The filesize is > 0, so we are going to download it */ const char *filename = GetFullFilename(this->curInfo, true); if (filename == NULL || (this->curFile = fopen(filename, "wb")) == NULL) { /* Unless that fails ofcourse... */ DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0); ShowErrorMessage(STR_CONTENT_ERROR_COULD_NOT_DOWNLOAD, STR_CONTENT_ERROR_COULD_NOT_DOWNLOAD_FILE_NOT_WRITABLE, WL_ERROR); return false; } } return true; }
/** * Launch save/load dialog in the given mode. * @param mode Save/load mode. */ void ShowSaveLoadDialog(SaveLoadDialogMode mode) { DeleteWindowById(WC_SAVELOAD, 0); const WindowDesc *sld; switch (mode) { case SLD_SAVE_GAME: case SLD_SAVE_SCENARIO: case SLD_SAVE_HEIGHTMAP: sld = &_save_dialog_desc; break; case SLD_LOAD_HEIGHTMAP: sld = &_load_heightmap_dialog_desc; break; default: sld = &_load_dialog_desc; break; } _saveload_mode = mode; _file_to_saveload.filetype = _file_modetotype[mode]; new SaveLoadWindow(sld, mode); }
DEF_GAME_RECEIVE_COMMAND(Client, PACKET_SERVER_ERROR) { NetworkErrorCode error = (NetworkErrorCode)p->Recv_uint8(); switch (error) { /* We made an error in the protocol, and our connection is closed.... */ case NETWORK_ERROR_NOT_AUTHORIZED: case NETWORK_ERROR_NOT_EXPECTED: case NETWORK_ERROR_COMPANY_MISMATCH: _switch_mode_errorstr = STR_NETWORK_ERROR_SERVER_ERROR; break; case NETWORK_ERROR_FULL: _switch_mode_errorstr = STR_NETWORK_ERROR_SERVER_FULL; break; case NETWORK_ERROR_WRONG_REVISION: _switch_mode_errorstr = STR_NETWORK_ERROR_WRONG_REVISION; break; case NETWORK_ERROR_WRONG_PASSWORD: _switch_mode_errorstr = STR_NETWORK_ERROR_WRONG_PASSWORD; break; case NETWORK_ERROR_KICKED: _switch_mode_errorstr = STR_NETWORK_ERROR_KICKED; break; case NETWORK_ERROR_CHEATER: _switch_mode_errorstr = STR_NETWORK_ERROR_CHEATER; break; case NETWORK_ERROR_TOO_MANY_COMMANDS: _switch_mode_errorstr = STR_NETWORK_ERROR_TOO_MANY_COMMANDS; break; default: _switch_mode_errorstr = STR_NETWORK_ERROR_LOSTCONNECTION; } DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0); return NETWORK_RECV_STATUS_SERVER_ERROR; }
/** * Show the timetable for a given vehicle. * @param v The vehicle to show the timetable for. */ void ShowTimetableWindow(const Vehicle *v) { DeleteWindowById(WC_VEHICLE_DETAILS, v->index, false); DeleteWindowById(WC_VEHICLE_ORDERS, v->index, false); AllocateWindowDescFront<TimetableWindow>(&_timetable_desc, v->index); }
/** * Show land information window. * @param tile The tile to show information about. */ void ShowLandInfo(TileIndex tile) { DeleteWindowById(WC_LAND_INFO, 0); new LandInfoWindow(tile); }
/** Open the AI config window. */ void ShowAIConfigWindow() { DeleteWindowById(WC_GAME_OPTIONS, 0); new AIConfigWindow(); }
virtual ~BuildDocksStationWindow() { DeleteWindowById(WC_SELECT_STATION, 0); }