Files @ r23483:3733e6b8ff17
Branch filter:

Location: cpp/openttd-patchpack/source/src/highscore_gui.cpp - annotation

Patric Stout
Remove: ENABLE_NETWORK switch

This switch has been a pain for years. Often disabling broke
compilation, as no developer compiles OpenTTD without, neither do
any of our official binaries.

Additionaly, it has grown so hugely in our codebase, that it
clearly shows that the current solution was a poor one. 350+
instances of "#ifdef ENABLE_NETWORK" were in the code, of which
only ~30 in the networking code itself. The rest were all around
the code to do the right thing, from GUI to NewGRF.

A more proper solution would be to stub all the functions, and
make sure the rest of the code can simply assume network is
available. This was also partially done, and most variables were
correct if networking was disabled. Despite that, often the #ifdefs
were still used.

With the recent removal of DOS, there is also no platform anymore
which we support where networking isn't working out-of-the-box.

All in all, it is time to remove the ENABLE_NETWORK switch. No
replacement is planned, but if you feel we really need this option,
we welcome any Pull Request which implements this in a way that
doesn't crawl through the code like this diff shows we used to.
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r14248:a9050881acd7
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r15421:b59b62f76cdb
r10558:0f415a8b2b9f
r18670:f122c356353c
r13272:0739fb55be40
r21383:942c32fb8b0e
r21383:942c32fb8b0e
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r20280:ca1fc41725ff
r10558:0f415a8b2b9f
r20280:ca1fc41725ff
r18667:3b72643a9c00
r13272:0739fb55be40
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r13272:0739fb55be40
r13272:0739fb55be40
r10558:0f415a8b2b9f
r13272:0739fb55be40
r13272:0739fb55be40
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r21728:6310f7085068
r21728:6310f7085068
r21728:6310f7085068
r21728:6310f7085068
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r21728:6310f7085068
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r13272:0739fb55be40
r21728:6310f7085068
r13272:0739fb55be40
r21728:6310f7085068
r13272:0739fb55be40
r13272:0739fb55be40
r13272:0739fb55be40
r14399:3f819c0da60a
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r14133:68a81a1cb372
r20630:ef21f6deaa7e
r14133:68a81a1cb372
r15421:b59b62f76cdb
r15421:b59b62f76cdb
r15421:b59b62f76cdb
r15421:b59b62f76cdb
r15421:b59b62f76cdb
r14133:68a81a1cb372
r14133:68a81a1cb372
r14133:68a81a1cb372
r14133:68a81a1cb372
r14133:68a81a1cb372
r14133:68a81a1cb372
r14133:68a81a1cb372
r14133:68a81a1cb372
r14133:68a81a1cb372
r14133:68a81a1cb372
r14133:68a81a1cb372
r14133:68a81a1cb372
r14133:68a81a1cb372
r14133:68a81a1cb372
r14133:68a81a1cb372
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r20280:ca1fc41725ff
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r11847:235c011992a8
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r11917:612c11f7ab47
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r19831:07fe1952f9c0
r19831:07fe1952f9c0
r10558:0f415a8b2b9f
r19831:07fe1952f9c0
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r11917:612c11f7ab47
r19835:9f41fb5b6fd7
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r11847:235c011992a8
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r13272:0739fb55be40
r21728:6310f7085068
r10558:0f415a8b2b9f
r11944:3b8f9f948e8d
r11944:3b8f9f948e8d
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r13719:993d522a3e5b
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r13719:993d522a3e5b
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r19942:03f7761b717f
r19942:03f7761b717f
r20280:ca1fc41725ff
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r19942:03f7761b717f
r19942:03f7761b717f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r19942:03f7761b717f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r13272:0739fb55be40
r21728:6310f7085068
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r13272:0739fb55be40
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r13272:0739fb55be40
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r20492:cef2e626fdc1
r20492:cef2e626fdc1
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r13719:993d522a3e5b
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r11646:66d8b9c62ebc
r19959:9e9a0d36d946
r11646:66d8b9c62ebc
r11646:66d8b9c62ebc
r20280:ca1fc41725ff
r20283:2a199c78224c
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r13554:d1964ead02ee
r11368:058349c3a02c
r10558:0f415a8b2b9f
r20280:ca1fc41725ff
r20283:2a199c78224c
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r13554:d1964ead02ee
r11368:058349c3a02c
r10558:0f415a8b2b9f
r15610:623a23fb6560
r15610:623a23fb6560
r10558:0f415a8b2b9f
r15613:193c12018337
r15613:193c12018337
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r15610:623a23fb6560
r15610:623a23fb6560
r15613:193c12018337
r15613:193c12018337
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r11201:1d8e7232ae73
r11919:363b629324b9
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
r10558:0f415a8b2b9f
/* $Id$ */

/*
 * This file is part of OpenTTD.
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 */

/** @file highscore_gui.cpp Definition of the HighScore and EndGame windows */

#include "stdafx.h"
#include "highscore.h"
#include "table/strings.h"
#include "gfx_func.h"
#include "table/sprites.h"
#include "window_gui.h"
#include "window_func.h"
#include "network/network.h"
#include "command_func.h"
#include "company_func.h"
#include "company_base.h"
#include "strings_func.h"
#include "hotkeys.h"

#include "widgets/highscore_widget.h"

#include "safeguards.h"

struct EndGameHighScoreBaseWindow : Window {
	uint32 background_img;
	int8 rank;

	EndGameHighScoreBaseWindow(WindowDesc *desc) : Window(desc)
	{
		this->InitNested();
		CLRBITS(this->flags, WF_WHITE_BORDER);
		ResizeWindow(this, _screen.width - this->width, _screen.height - this->height);
	}

	/* Always draw a maximized window and within it the centered background */
	void SetupHighScoreEndWindow()
	{
		/* Resize window to "full-screen". */
		if (this->width != _screen.width || this->height != _screen.height) ResizeWindow(this, _screen.width - this->width, _screen.height - this->height);

		this->DrawWidgets();

		/* Standard background slices are 50 pixels high, but it's designed
		 * for 480 pixels total. 96% of 500 is 480. */
		Dimension dim = GetSpriteSize(this->background_img);
		Point pt = this->GetTopLeft(dim.width, dim.height * 96 / 10);
		/* Center Highscore/Endscreen background */
		for (uint i = 0; i < 10; i++) { // the image is split into 10 50px high parts
			DrawSprite(this->background_img + i, PAL_NONE, pt.x, pt.y + (i * dim.height));
		}
	}

	/** Return the coordinate of the screen such that a window of 640x480 is centered at the screen. */
	Point GetTopLeft(int x, int y)
	{
		Point pt = {max(0, (_screen.width / 2) - (x / 2)), max(0, (_screen.height / 2) - (y / 2))};
		return pt;
	}

	virtual void OnClick(Point pt, int widget, int click_count)
	{
		delete this;
	}

	virtual EventState OnKeyPress(WChar key, uint16 keycode)
	{
		/* All keys are 'handled' by this window but we want to make
		 * sure that 'quit' still works correctly. Not handling the
		 * quit key is enough so the main toolbar can handle it. */
		if (IsQuitKey(keycode)) return ES_NOT_HANDLED;

		switch (keycode) {
			/* Keys for telling we want to go on */
			case WKC_RETURN:
			case WKC_ESC:
			case WKC_SPACE:
				delete this;
				return ES_HANDLED;

			default:
				/* We want to handle all keys; we don't want windows in
				 * the background to open. Especially the ones that do
				 * locate themselves based on the status-/toolbars. */
				return ES_HANDLED;
		}
	}
};

/** End game window shown at the end of the game */
struct EndGameWindow : EndGameHighScoreBaseWindow {
	EndGameWindow(WindowDesc *desc) : EndGameHighScoreBaseWindow(desc)
	{
		/* Pause in single-player to have a look at the highscore at your own leisure */
		if (!_networking) DoCommandP(0, PM_PAUSED_NORMAL, 1, CMD_PAUSE);

		this->background_img = SPR_TYCOON_IMG1_BEGIN;

		if (_local_company != COMPANY_SPECTATOR) {
			const Company *c = Company::Get(_local_company);
			if (c->old_economy[0].performance_history == SCORE_MAX) {
				this->background_img = SPR_TYCOON_IMG2_BEGIN;
			}
		}

		/* In a network game show the endscores of the custom difficulty 'network' which is
		 * a TOP5 of that game, and not an all-time TOP5. */
		if (_networking) {
			this->window_number = SP_MULTIPLAYER;
			this->rank = SaveHighScoreValueNetwork();
		} else {
			/* in single player _local company is always valid */
			const Company *c = Company::Get(_local_company);
			this->window_number = SP_CUSTOM;
			this->rank = SaveHighScoreValue(c);
		}

		MarkWholeScreenDirty();
	}

	~EndGameWindow()
	{
		if (!_networking) DoCommandP(0, PM_PAUSED_NORMAL, 0, CMD_PAUSE); // unpause
		ShowHighscoreTable(this->window_number, this->rank);
	}

	virtual void OnPaint()
	{
		this->SetupHighScoreEndWindow();
		Point pt = this->GetTopLeft(640, 480);

		const Company *c = Company::GetIfValid(_local_company);
		if (c == NULL) return;

		/* We need to get performance from last year because the image is shown
		 * at the start of the new year when these things have already been copied */
		if (this->background_img == SPR_TYCOON_IMG2_BEGIN) { // Tycoon of the century \o/
			SetDParam(0, c->index);
			SetDParam(1, c->index);
			SetDParam(2, EndGameGetPerformanceTitleFromValue(c->old_economy[0].performance_history));
			DrawStringMultiLine(pt.x + 15, pt.x + 640 - 25, pt.y + 90, pt.y + 160, STR_HIGHSCORE_PRESIDENT_OF_COMPANY_ACHIEVES_STATUS, TC_FROMSTRING, SA_CENTER);
		} else {
			SetDParam(0, c->index);
			SetDParam(1, EndGameGetPerformanceTitleFromValue(c->old_economy[0].performance_history));
			DrawStringMultiLine(pt.x + 36, pt.x + 640, pt.y + 140, pt.y + 206, STR_HIGHSCORE_COMPANY_ACHIEVES_STATUS, TC_FROMSTRING, SA_CENTER);
		}
	}
};

struct HighScoreWindow : EndGameHighScoreBaseWindow {
	bool game_paused_by_player; ///< True if the game was paused by the player when the highscore window was opened.

	HighScoreWindow(WindowDesc *desc, int difficulty, int8 ranking) : EndGameHighScoreBaseWindow(desc)
	{
		/* pause game to show the chart */
		this->game_paused_by_player = _pause_mode == PM_PAUSED_NORMAL;
		if (!_networking && !this->game_paused_by_player) DoCommandP(0, PM_PAUSED_NORMAL, 1, CMD_PAUSE);

		/* Close all always on-top windows to get a clean screen */
		if (_game_mode != GM_MENU) HideVitalWindows();

		MarkWholeScreenDirty();
		this->window_number = difficulty; // show highscore chart for difficulty...
		this->background_img = SPR_HIGHSCORE_CHART_BEGIN; // which background to show
		this->rank = ranking;
	}

	~HighScoreWindow()
	{
		if (_game_mode != GM_MENU) ShowVitalWindows();

		if (!_networking && !this->game_paused_by_player) DoCommandP(0, PM_PAUSED_NORMAL, 0, CMD_PAUSE); // unpause
	}

	virtual void OnPaint()
	{
		const HighScore *hs = _highscore_table[this->window_number];

		this->SetupHighScoreEndWindow();
		Point pt = this->GetTopLeft(640, 480);

		SetDParam(0, ORIGINAL_END_YEAR);
		DrawStringMultiLine(pt.x + 70, pt.x + 570, pt.y, pt.y + 140, !_networking ? STR_HIGHSCORE_TOP_COMPANIES_WHO_REACHED : STR_HIGHSCORE_TOP_COMPANIES_NETWORK_GAME, TC_FROMSTRING, SA_CENTER);

		/* Draw Highscore peepz */
		for (uint8 i = 0; i < lengthof(_highscore_table[0]); i++) {
			SetDParam(0, i + 1);
			DrawString(pt.x + 40, pt.x + 600, pt.y + 140 + (i * 55), STR_HIGHSCORE_POSITION);

			if (hs[i].company[0] != '\0') {
				TextColour colour = (this->rank == i) ? TC_RED : TC_BLACK; // draw new highscore in red

				SetDParamStr(0, hs[i].company);
				DrawString(pt.x + 71, pt.x + 569, pt.y + 140 + (i * 55), STR_JUST_BIG_RAW_STRING, colour);
				SetDParam(0, hs[i].title);
				SetDParam(1, hs[i].score);
				DrawString(pt.x + 71, pt.x + 569, pt.y + 140 + FONT_HEIGHT_LARGE + (i * 55), STR_HIGHSCORE_STATS, colour);
			}
		}
	}
};

static const NWidgetPart _nested_highscore_widgets[] = {
	NWidget(WWT_PANEL, COLOUR_BROWN, WID_H_BACKGROUND), SetMinimalSize(641, 481), SetResize(1, 1), EndContainer(),
};

static WindowDesc _highscore_desc(
	WDP_MANUAL, NULL, 0, 0,
	WC_HIGHSCORE, WC_NONE,
	0,
	_nested_highscore_widgets, lengthof(_nested_highscore_widgets)
);

static WindowDesc _endgame_desc(
	WDP_MANUAL, NULL, 0, 0,
	WC_ENDSCREEN, WC_NONE,
	0,
	_nested_highscore_widgets, lengthof(_nested_highscore_widgets)
);

/**
 * Show the highscore table for a given difficulty. When called from
 * endgame ranking is set to the top5 element that was newly added
 * and is thus highlighted
 */
void ShowHighscoreTable(int difficulty, int8 ranking)
{
	DeleteWindowByClass(WC_HIGHSCORE);
	new HighScoreWindow(&_highscore_desc, difficulty, ranking);
}

/**
 * Show the endgame victory screen in 2050. Update the new highscore
 * if it was high enough
 */
void ShowEndGameChart()
{
	/* Dedicated server doesn't need the highscore window and neither does -v null. */
	if (_network_dedicated || (!_networking && !Company::IsValidID(_local_company))) return;

	HideVitalWindows();
	DeleteWindowByClass(WC_ENDSCREEN);
	new EndGameWindow(&_endgame_desc);
}