changeset 18782:d14680ee0033 draft

(svn r23630) -Add: a Goal GUI to show your current goals
author truebrain <truebrain@openttd.org>
date Mon, 19 Dec 2011 21:03:17 +0000
parents ee6ce5148ede
children d51770d2b734
files projects/openttd_vs100.vcxproj projects/openttd_vs100.vcxproj.filters projects/openttd_vs80.vcproj projects/openttd_vs90.vcproj source.list src/command.cpp src/command_type.h src/game/game_instance.cpp src/goal.cpp src/goal_base.h src/goal_gui.cpp src/goal_type.h src/gui.h src/lang/english.txt src/saveload/goal_sl.cpp src/saveload/saveload.cpp src/script/api/game/game_goal.hpp.sq src/script/api/script_goal.cpp src/script/api/script_goal.hpp src/script/api/script_object.cpp src/script/api/script_object.hpp src/script/api/script_types.hpp src/script/api/template/template_goal.hpp.sq src/script/script_instance.cpp src/script/script_instance.hpp src/script/script_storage.hpp src/toolbar_gui.cpp src/widgets/goal_widget.h src/window_type.h
diffstat 29 files changed, 879 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/projects/openttd_vs100.vcxproj
+++ b/projects/openttd_vs100.vcxproj
@@ -320,6 +320,7 @@
     <ClCompile Include="..\src\genworld.cpp" />
     <ClCompile Include="..\src\gfx.cpp" />
     <ClCompile Include="..\src\gfxinit.cpp" />
+    <ClCompile Include="..\src\goal.cpp" />
     <ClCompile Include="..\src\ground_vehicle.cpp" />
     <ClCompile Include="..\src\heightmap.cpp" />
     <ClCompile Include="..\src\highscore.cpp" />
@@ -439,6 +440,8 @@
     <ClInclude Include="..\src\gfx_func.h" />
     <ClInclude Include="..\src\gfx_type.h" />
     <ClInclude Include="..\src\gfxinit.h" />
+    <ClInclude Include="..\src\goal_base.h" />
+    <ClInclude Include="..\src\goal_type.h" />
     <ClInclude Include="..\src\graph_gui.h" />
     <ClInclude Include="..\src\ground_vehicle.hpp" />
     <ClInclude Include="..\src\group.h" />
@@ -650,6 +653,7 @@
     <ClCompile Include="..\src\error_gui.cpp" />
     <ClCompile Include="..\src\fios_gui.cpp" />
     <ClCompile Include="..\src\genworld_gui.cpp" />
+    <ClCompile Include="..\src\goal_gui.cpp" />
     <ClCompile Include="..\src\graph_gui.cpp" />
     <ClCompile Include="..\src\group_gui.cpp" />
     <ClCompile Include="..\src\highscore_gui.cpp" />
@@ -707,6 +711,7 @@
     <ClInclude Include="..\src\widgets\error_widget.h" />
     <ClInclude Include="..\src\widgets\fios_widget.h" />
     <ClInclude Include="..\src\widgets\genworld_widget.h" />
+    <ClInclude Include="..\src\widgets\goal_widget.h" />
     <ClInclude Include="..\src\widgets\graph_widget.h" />
     <ClInclude Include="..\src\widgets\group_widget.h" />
     <ClInclude Include="..\src\widgets\highscore_widget.h" />
@@ -781,6 +786,7 @@
     <ClCompile Include="..\src\saveload\engine_sl.cpp" />
     <ClCompile Include="..\src\saveload\game_sl.cpp" />
     <ClCompile Include="..\src\saveload\gamelog_sl.cpp" />
+    <ClCompile Include="..\src\saveload\goal_sl.cpp" />
     <ClCompile Include="..\src\saveload\group_sl.cpp" />
     <ClCompile Include="..\src\saveload\industry_sl.cpp" />
     <ClCompile Include="..\src\saveload\labelmaps_sl.cpp" />
@@ -946,6 +952,7 @@
     <ClInclude Include="..\src\script\api\script_execmode.hpp" />
     <ClInclude Include="..\src\script\api\script_game.hpp" />
     <ClInclude Include="..\src\script\api\script_gamesettings.hpp" />
+    <ClInclude Include="..\src\script\api\script_goal.hpp" />
     <ClInclude Include="..\src\script\api\script_group.hpp" />
     <ClInclude Include="..\src\script\api\script_grouplist.hpp" />
     <ClInclude Include="..\src\script\api\script_industry.hpp" />
@@ -1003,6 +1010,7 @@
     <ClCompile Include="..\src\script\api\script_execmode.cpp" />
     <ClCompile Include="..\src\script\api\script_game.cpp" />
     <ClCompile Include="..\src\script\api\script_gamesettings.cpp" />
+    <ClCompile Include="..\src\script\api\script_goal.cpp" />
     <ClCompile Include="..\src\script\api\script_group.cpp" />
     <ClCompile Include="..\src\script\api\script_grouplist.cpp" />
     <ClCompile Include="..\src\script\api\script_industry.cpp" />
--- a/projects/openttd_vs100.vcxproj.filters
+++ b/projects/openttd_vs100.vcxproj.filters
@@ -189,6 +189,9 @@
     <ClCompile Include="..\src\gfxinit.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\src\goal.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
     <ClCompile Include="..\src\ground_vehicle.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
@@ -546,6 +549,12 @@
     <ClInclude Include="..\src\gfxinit.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="..\src\goal_base.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\src\goal_type.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
     <ClInclude Include="..\src\graph_gui.h">
       <Filter>Header Files</Filter>
     </ClInclude>
@@ -1179,6 +1188,9 @@
     <ClCompile Include="..\src\genworld_gui.cpp">
       <Filter>GUI Source Code</Filter>
     </ClCompile>
+    <ClCompile Include="..\src\goal_gui.cpp">
+      <Filter>GUI Source Code</Filter>
+    </ClCompile>
     <ClCompile Include="..\src\graph_gui.cpp">
       <Filter>GUI Source Code</Filter>
     </ClCompile>
@@ -1350,6 +1362,9 @@
     <ClInclude Include="..\src\widgets\genworld_widget.h">
       <Filter>Widgets</Filter>
     </ClInclude>
+    <ClInclude Include="..\src\widgets\goal_widget.h">
+      <Filter>Widgets</Filter>
+    </ClInclude>
     <ClInclude Include="..\src\widgets\graph_widget.h">
       <Filter>Widgets</Filter>
     </ClInclude>
@@ -1572,6 +1587,9 @@
     <ClCompile Include="..\src\saveload\gamelog_sl.cpp">
       <Filter>Save/Load handlers</Filter>
     </ClCompile>
+    <ClCompile Include="..\src\saveload\goal_sl.cpp">
+      <Filter>Save/Load handlers</Filter>
+    </ClCompile>
     <ClCompile Include="..\src\saveload\group_sl.cpp">
       <Filter>Save/Load handlers</Filter>
     </ClCompile>
@@ -2067,6 +2085,9 @@
     <ClInclude Include="..\src\script\api\script_gamesettings.hpp">
       <Filter>Script API</Filter>
     </ClInclude>
+    <ClInclude Include="..\src\script\api\script_goal.hpp">
+      <Filter>Script API</Filter>
+    </ClInclude>
     <ClInclude Include="..\src\script\api\script_group.hpp">
       <Filter>Script API</Filter>
     </ClInclude>
@@ -2238,6 +2259,9 @@
     <ClCompile Include="..\src\script\api\script_gamesettings.cpp">
       <Filter>Script API Implementation</Filter>
     </ClCompile>
+    <ClCompile Include="..\src\script\api\script_goal.cpp">
+      <Filter>Script API Implementation</Filter>
+    </ClCompile>
     <ClCompile Include="..\src\script\api\script_group.cpp">
       <Filter>Script API Implementation</Filter>
     </ClCompile>
--- a/projects/openttd_vs80.vcproj
+++ b/projects/openttd_vs80.vcproj
@@ -551,6 +551,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\goal.cpp"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\ground_vehicle.cpp"
 				>
 			</File>
@@ -1031,6 +1035,14 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\goal_base.h"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\goal_type.h"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\graph_gui.h"
 				>
 			</File>
@@ -1883,6 +1895,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\goal_gui.cpp"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\graph_gui.cpp"
 				>
 			</File>
@@ -2115,6 +2131,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\widgets\goal_widget.h"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\widgets\graph_widget.h"
 				>
 			</File>
@@ -2419,6 +2439,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\saveload\goal_sl.cpp"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\saveload\group_sl.cpp"
 				>
 			</File>
@@ -3119,6 +3143,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\script\api\script_goal.hpp"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\script\api\script_group.hpp"
 				>
 			</File>
@@ -3351,6 +3379,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\script\api\script_goal.cpp"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\script\api\script_group.cpp"
 				>
 			</File>
--- a/projects/openttd_vs90.vcproj
+++ b/projects/openttd_vs90.vcproj
@@ -548,6 +548,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\goal.cpp"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\ground_vehicle.cpp"
 				>
 			</File>
@@ -1028,6 +1032,14 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\goal_base.h"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\goal_type.h"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\graph_gui.h"
 				>
 			</File>
@@ -1880,6 +1892,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\goal_gui.cpp"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\graph_gui.cpp"
 				>
 			</File>
@@ -2112,6 +2128,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\widgets\goal_widget.h"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\widgets\graph_widget.h"
 				>
 			</File>
@@ -2416,6 +2436,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\saveload\goal_sl.cpp"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\saveload\group_sl.cpp"
 				>
 			</File>
@@ -3116,6 +3140,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\script\api\script_goal.hpp"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\script\api\script_group.hpp"
 				>
 			</File>
@@ -3348,6 +3376,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\script\api\script_goal.cpp"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\script\api\script_group.cpp"
 				>
 			</File>
--- a/source.list
+++ b/source.list
@@ -28,6 +28,7 @@
 genworld.cpp
 gfx.cpp
 gfxinit.cpp
+goal.cpp
 ground_vehicle.cpp
 heightmap.cpp
 highscore.cpp
@@ -172,6 +173,8 @@
 gfx_func.h
 gfx_type.h
 gfxinit.h
+goal_base.h
+goal_type.h
 graph_gui.h
 ground_vehicle.hpp
 group.h
@@ -402,6 +405,7 @@
 error_gui.cpp
 fios_gui.cpp
 genworld_gui.cpp
+goal_gui.cpp
 graph_gui.cpp
 group_gui.cpp
 highscore_gui.cpp
@@ -461,6 +465,7 @@
 widgets/error_widget.h
 widgets/fios_widget.h
 widgets/genworld_widget.h
+widgets/goal_widget.h
 widgets/graph_widget.h
 widgets/group_widget.h
 widgets/highscore_widget.h
@@ -539,6 +544,7 @@
 saveload/engine_sl.cpp
 saveload/game_sl.cpp
 saveload/gamelog_sl.cpp
+saveload/goal_sl.cpp
 saveload/group_sl.cpp
 saveload/industry_sl.cpp
 saveload/labelmaps_sl.cpp
@@ -724,6 +730,7 @@
 script/api/script_execmode.hpp
 script/api/script_game.hpp
 script/api/script_gamesettings.hpp
+script/api/script_goal.hpp
 script/api/script_group.hpp
 script/api/script_grouplist.hpp
 script/api/script_industry.hpp
@@ -783,6 +790,7 @@
 script/api/script_execmode.cpp
 script/api/script_game.cpp
 script/api/script_gamesettings.cpp
+script/api/script_goal.cpp
 script/api/script_group.cpp
 script/api/script_grouplist.cpp
 script/api/script_industry.cpp
--- a/src/command.cpp
+++ b/src/command.cpp
@@ -150,6 +150,8 @@
 CommandProc CmdCreateSubsidy;
 CommandProc CmdCompanyCtrl;
 CommandProc CmdCustomNewsItem;
+CommandProc CmdCreateGoal;
+CommandProc CmdRemoveGoal;
 
 CommandProc CmdLevelLand;
 
@@ -286,6 +288,8 @@
 	DEF_CMD(CmdCreateSubsidy,                          CMD_DEITY, CMDT_OTHER_MANAGEMENT      ), // CMD_CREATE_SUBSIDY
 	DEF_CMD(CmdCompanyCtrl,        CMD_SPECTATOR | CMD_CLIENT_ID, CMDT_SERVER_SETTING        ), // CMD_COMPANY_CTRL
 	DEF_CMD(CmdCustomNewsItem,                         CMD_DEITY, CMDT_OTHER_MANAGEMENT      ), // CMD_CUSTOM_NEWS_ITEM
+	DEF_CMD(CmdCreateGoal,                             CMD_DEITY, CMDT_OTHER_MANAGEMENT      ), // CMD_CREATE_GOAL
+	DEF_CMD(CmdRemoveGoal,                             CMD_DEITY, CMDT_OTHER_MANAGEMENT      ), // CMD_REMOVE_GOAL
 
 	DEF_CMD(CmdLevelLand, CMD_ALL_TILES | CMD_NO_TEST | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_LEVEL_LAND; test run might clear tiles multiple times, in execution that only happens once
 
--- a/src/command_type.h
+++ b/src/command_type.h
@@ -264,6 +264,8 @@
 	CMD_CREATE_SUBSIDY,               ///< create a new subsidy
 	CMD_COMPANY_CTRL,                 ///< used in multiplayer to create a new companies etc.
 	CMD_CUSTOM_NEWS_ITEM,             ///< create a custom news message
+	CMD_CREATE_GOAL,                  ///< create a new goal
+	CMD_REMOVE_GOAL,                  ///< remove a goal
 	CMD_LEVEL_LAND,                   ///< level land
 
 	CMD_BUILD_LOCK,                   ///< build a lock
--- a/src/game/game_instance.cpp
+++ b/src/game/game_instance.cpp
@@ -44,6 +44,7 @@
 #include "../script/api/game/game_execmode.hpp.sq"
 #include "../script/api/game/game_game.hpp.sq"
 #include "../script/api/game/game_gamesettings.hpp.sq"
+#include "../script/api/game/game_goal.hpp.sq"
 #include "../script/api/game/game_industry.hpp.sq"
 #include "../script/api/game/game_industrylist.hpp.sq"
 #include "../script/api/game/game_industrytype.hpp.sq"
@@ -132,6 +133,7 @@
 	SQGSExecMode_Register(this->engine);
 	SQGSGame_Register(this->engine);
 	SQGSGameSettings_Register(this->engine);
+	SQGSGoal_Register(this->engine);
 	SQGSIndustry_Register(this->engine);
 	SQGSIndustryList_Register(this->engine);
 	SQGSIndustryList_CargoAccepting_Register(this->engine);
new file mode 100644
--- /dev/null
+++ b/src/goal.cpp
@@ -0,0 +1,120 @@
+/* $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 goal.cpp Handling of goals. */
+
+#include "stdafx.h"
+#include "company_func.h"
+#include "industry.h"
+#include "town.h"
+#include "news_func.h"
+#include "ai/ai.hpp"
+#include "station_base.h"
+#include "cargotype.h"
+#include "strings_func.h"
+#include "window_func.h"
+#include "goal_base.h"
+#include "core/pool_func.hpp"
+#include "core/random_func.hpp"
+#include "game/game.hpp"
+#include "command_func.h"
+#include "company_base.h"
+#include "string_func.h"
+
+#include "table/strings.h"
+
+GoalID _new_goal_id;
+
+GoalPool _goal_pool("Goal");
+INSTANTIATE_POOL_METHODS(Goal)
+
+/**
+ * Create a new goal.
+ * @param tile unused.
+ * @param flags type of operation
+ * @param p1 various bitstuffed elements
+ * - p1 = (bit  0 -  7) - GoalType of destination.
+ * - p1 = (bit  8 - 15) - Company for which this goal is.
+ * @param p2 GoalTypeID of destination.
+ * @param text Text of the goal.
+ * @return the cost of this operation or an error
+ */
+CommandCost CmdCreateGoal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
+{
+	if (!Goal::CanAllocateItem()) return CMD_ERROR;
+
+	GoalType type = (GoalType)GB(p1, 0, 8);
+	CompanyID company = (CompanyID)GB(p1, 8, 8);
+
+	if (_current_company != OWNER_DEITY) return CMD_ERROR;
+	if (StrEmpty(text)) return CMD_ERROR;
+	if (company != INVALID_COMPANY && !Company::IsValidID(company)) return CMD_ERROR;
+
+	switch (type) {
+		case GT_NONE:
+			if (p2 != 0) return CMD_ERROR;
+			break;
+
+		case GT_TILE:
+			if (!IsValidTile(p2)) return CMD_ERROR;
+			break;
+
+		case GT_INDUSTRY:
+			if (!Industry::IsValidID(p2)) return CMD_ERROR;
+			break;
+
+		case GT_TOWN:
+			if (!Town::IsValidID(p2)) return CMD_ERROR;
+			break;
+
+		case GT_COMPANY:
+			if (!Company::IsValidID(p2)) return CMD_ERROR;
+			break;
+
+		default: return CMD_ERROR;
+	}
+
+	if (flags & DC_EXEC) {
+		Goal *g = new Goal();
+		g->type = type;
+		g->dst = p2;
+		g->company = company;
+		g->text = strdup(text);
+
+		InvalidateWindowData(WC_GOALS_LIST, 0);
+
+		_new_goal_id = g->index;
+	}
+
+	return CommandCost();
+}
+
+/**
+ * Remove a goal.
+ * @param tile unused.
+ * @param flags type of operation
+ * @param p1 GoalID to remove.
+ * @param p2 unused.
+ * @param text unused.
+ * @return the cost of this operation or an error
+ */
+CommandCost CmdRemoveGoal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
+{
+	if (_current_company != OWNER_DEITY) return CMD_ERROR;
+	if (!Goal::IsValidID(p1)) return CMD_ERROR;
+
+	if (flags & DC_EXEC) {
+		Goal *g = Goal::Get(p1);
+		delete g;
+
+		InvalidateWindowData(WC_GOALS_LIST, 0);
+	}
+
+	return CommandCost();
+}
new file mode 100644
--- /dev/null
+++ b/src/goal_base.h
@@ -0,0 +1,44 @@
+/* $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 goal_base.h Goal base class. */
+
+#ifndef GOAL_BASE_H
+#define GOAL_BASE_H
+
+#include "cargo_type.h"
+#include "company_type.h"
+#include "goal_type.h"
+#include "core/pool_type.hpp"
+
+typedef Pool<Goal, GoalID, 1, MAX_COMPANIES> GoalPool;
+extern GoalPool _goal_pool;
+
+/** Struct about subsidies, offered and awarded */
+struct Goal : GoalPool::PoolItem<&_goal_pool> {
+	CompanyByte company; ///< Goal is for a specific company; INVALID_COMPANY if it is global
+	GoalTypeByte type;   ///< Type of the goal
+	GoalTypeID dst;      ///< Index of type
+	char *text;          ///< Text of the goal.
+
+	/**
+	 * We need an (empty) constructor so struct isn't zeroed (as C++ standard states)
+	 */
+	FORCEINLINE Goal() { }
+
+	/**
+	 * (Empty) destructor has to be defined else operator delete might be called with NULL parameter
+	 */
+	FORCEINLINE ~Goal() { free(this->text); }
+};
+
+#define FOR_ALL_GOALS_FROM(var, start) FOR_ALL_ITEMS_FROM(Goal, goal_index, var, start)
+#define FOR_ALL_GOALS(var) FOR_ALL_GOALS_FROM(var, 0)
+
+#endif /* GOAL_BASE_H */
new file mode 100644
--- /dev/null
+++ b/src/goal_gui.cpp
@@ -0,0 +1,253 @@
+/* $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 goal_gui.cpp GUI for goals. */
+
+#include "stdafx.h"
+#include "industry.h"
+#include "town.h"
+#include "window_gui.h"
+#include "strings_func.h"
+#include "date_func.h"
+#include "viewport_func.h"
+#include "gfx_func.h"
+#include "gui.h"
+#include "goal_base.h"
+#include "core/geometry_func.hpp"
+
+#include "widgets/goal_widget.h"
+
+#include "table/strings.h"
+
+struct GoalListWindow : Window {
+	Scrollbar *vscroll;
+
+	GoalListWindow(const WindowDesc *desc, WindowNumber window_number) : Window()
+	{
+		this->CreateNestedTree(desc);
+		this->vscroll = this->GetScrollbar(WID_GL_SCROLLBAR);
+		this->FinishInitNested(desc, window_number);
+		this->OnInvalidateData(0);
+	}
+
+	virtual void OnClick(Point pt, int widget, int click_count)
+	{
+		if (widget != WID_GL_PANEL) return;
+
+		int y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_GL_PANEL, WD_FRAMERECT_TOP);
+		int num = 0;
+		const Goal *s;
+		FOR_ALL_GOALS(s) {
+			if (s->company == INVALID_COMPANY) {
+				y--;
+				if (y == 0) {
+					this->HandleClick(s);
+					return;
+				}
+				num++;
+			}
+		}
+
+		if (num == 0) {
+			y--; // "None"
+			if (y < 0) return;
+		}
+
+		y -= 2; // "Company specific goals:"
+		if (y < 0) return;
+
+		FOR_ALL_GOALS(s) {
+			if (s->company != INVALID_COMPANY) {
+				y--;
+				if (y == 0) {
+					this->HandleClick(s);
+					return;
+				}
+			}
+		}
+	}
+
+	void HandleClick(const Goal *s)
+	{
+		/* determine dst coordinate for goal and try to scroll to it */
+		TileIndex xy;
+		switch (s->type) {
+			case GT_NONE: return;
+			case GT_COMPANY: return;
+
+			case GT_TILE:
+				if (!IsValidTile(s->dst)) return;
+				xy = s->dst;
+				break;
+
+			case GT_INDUSTRY:
+				if (!Industry::IsValidID(s->dst)) return;
+				xy = Industry::Get(s->dst)->location.tile;
+				break;
+
+			case GT_TOWN:
+				if (!Town::IsValidID(s->dst)) return;
+				xy = Town::Get(s->dst)->xy;
+				break;
+
+			default: NOT_REACHED();
+		}
+
+		if (_ctrl_pressed) {
+			ShowExtraViewPortWindow(xy);
+		} else {
+			ScrollMainWindowToTile(xy);
+		}
+	}
+
+	/**
+	 * Count the number of lines in this window.
+	 * @return the number of lines
+	 */
+	uint CountLines()
+	{
+		/* Count number of (non) awarded goals */
+		uint num_global = 0;
+		uint num_company = 0;
+		const Goal *s;
+		FOR_ALL_GOALS(s) {
+			if (s->company == INVALID_COMPANY) {
+				num_global++;
+			} else {
+				num_company++;
+			}
+		}
+
+		/* Count the 'none' lines */
+		if (num_global  == 0) num_global = 1;
+		if (num_company == 0) num_company = 1;
+
+		/* Global, company and an empty line before the accepted ones. */
+		return 3 + num_global + num_company;
+	}
+
+	virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
+	{
+		if (widget != WID_GL_PANEL) return;
+		Dimension d = maxdim(GetStringBoundingBox(STR_GOALS_GLOBAL_TITLE), GetStringBoundingBox(STR_GOALS_COMPANY_TITLE));
+
+		resize->height = d.height;
+
+		d.height *= 5;
+		d.width += padding.width + WD_FRAMERECT_RIGHT + WD_FRAMERECT_LEFT;
+		d.height += padding.height + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
+		*size = maxdim(*size, d);
+	}
+
+	virtual void DrawWidget(const Rect &r, int widget) const
+	{
+		if (widget != WID_GL_PANEL) return;
+
+		YearMonthDay ymd;
+		ConvertDateToYMD(_date, &ymd);
+
+		int right = r.right - WD_FRAMERECT_RIGHT;
+		int y = r.top + WD_FRAMERECT_TOP;
+		int x = r.left + WD_FRAMERECT_LEFT;
+
+		int pos = -this->vscroll->GetPosition();
+		const int cap = this->vscroll->GetCapacity();
+
+		/* Section for drawing the global goals */
+		if (IsInsideMM(pos, 0, cap)) DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_GOALS_GLOBAL_TITLE);
+		pos++;
+
+		uint num = 0;
+		const Goal *s;
+		FOR_ALL_GOALS(s) {
+			if (s->company == INVALID_COMPANY) {
+				if (IsInsideMM(pos, 0, cap)) {
+					/* Display the goal */
+					SetDParamStr(0, s->text);
+					DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_GOALS_TEXT);
+				}
+				pos++;
+				num++;
+			}
+		}
+
+		if (num == 0) {
+			if (IsInsideMM(pos, 0, cap)) DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_GOALS_NONE);
+			pos++;
+		}
+
+		/* Section for drawing the company goals */
+		pos++;
+		if (IsInsideMM(pos, 0, cap)) DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_GOALS_COMPANY_TITLE);
+		pos++;
+		num = 0;
+
+		FOR_ALL_GOALS(s) {
+			if (s->company != INVALID_COMPANY) {
+				if (IsInsideMM(pos, 0, cap)) {
+					/* Display the goal */
+					SetDParamStr(0, s->text);
+					DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_GOALS_TEXT);
+				}
+				pos++;
+				num++;
+			}
+		}
+
+		if (num == 0) {
+			if (IsInsideMM(pos, 0, cap)) DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_GOALS_NONE);
+			pos++;
+		}
+	}
+
+	virtual void OnResize()
+	{
+		this->vscroll->SetCapacityFromWidget(this, WID_GL_PANEL);
+	}
+
+	/**
+	 * Some data on this window has become invalid.
+	 * @param data Information about the changed data.
+	 * @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details.
+	 */
+	virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
+	{
+		if (!gui_scope) return;
+		this->vscroll->SetCount(this->CountLines());
+	}
+};
+
+static const NWidgetPart _nested_goals_list_widgets[] = {
+	NWidget(NWID_HORIZONTAL),
+		NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
+		NWidget(WWT_CAPTION, COLOUR_BROWN), SetDataTip(STR_GOALS_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
+		NWidget(WWT_SHADEBOX, COLOUR_BROWN),
+		NWidget(WWT_STICKYBOX, COLOUR_BROWN),
+	EndContainer(),
+	NWidget(NWID_HORIZONTAL),
+		NWidget(WWT_PANEL, COLOUR_BROWN, WID_GL_PANEL), SetDataTip(0x0, STR_GOALS_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER), SetResize(1, 1), SetScrollbar(WID_GL_SCROLLBAR), EndContainer(),
+		NWidget(NWID_VERTICAL),
+			NWidget(NWID_VSCROLLBAR, COLOUR_BROWN, WID_GL_SCROLLBAR),
+			NWidget(WWT_RESIZEBOX, COLOUR_BROWN),
+		EndContainer(),
+	EndContainer(),
+};
+
+static const WindowDesc _goals_list_desc(
+	WDP_AUTO, 500, 127,
+	WC_GOALS_LIST, WC_NONE,
+	0,
+	_nested_goals_list_widgets, lengthof(_nested_goals_list_widgets)
+);
+
+
+void ShowGoalsList()
+{
+	AllocateWindowDescFront<GoalListWindow>(&_goals_list_desc, 0);
+}
new file mode 100644
--- /dev/null
+++ b/src/goal_type.h
@@ -0,0 +1,33 @@
+/* $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 goal_type.h basic types related to goals */
+
+#ifndef GOAL_TYPE_H
+#define GOAL_TYPE_H
+
+/** Types of goal destinations */
+enum GoalType {
+	GT_NONE,         ///< Destination is not linked
+	GT_TILE,         ///< Destination is a tile
+	GT_INDUSTRY,     ///< Destination is an industry
+	GT_TOWN,         ///< Destination is a town
+	GT_COMPANY,      ///< Destination is a company
+};
+typedef SimpleTinyEnumT<GoalType, byte> GoalTypeByte; ///< The GoalType packed into a byte for savegame purposes.
+
+typedef uint32 GoalTypeID; ///< Contains either tile, industry ID, town ID or company ID (or INVALID_GOALTYPE)
+static const GoalTypeID INVALID_GOALTYPE = 0xFFFFFFFF; ///< Invalid/unknown index of GoalType
+
+typedef uint16 GoalID; ///< ID of a goal
+struct Goal;
+
+extern GoalID _new_goal_id;
+
+#endif /* GOAL_TYPE_H */
--- a/src/gui.h
+++ b/src/gui.h
@@ -52,6 +52,7 @@
 void ShowTownDirectory();
 void ShowIndustryDirectory();
 void ShowSubsidiesList();
+void ShowGoalsList();
 
 void ShowEstimatedCostOrIncome(Money cost, int x, int y);
 
--- a/src/lang/english.txt
+++ b/src/lang/english.txt
@@ -382,6 +382,7 @@
 
 ############ range for subsidies menu starts
 STR_SUBSIDIES_MENU_SUBSIDIES                                    :Subsidies
+STR_SUBSIDIES_MENU_GOAL                                         :Current goals
 ############ range ends here
 
 ############ range for graph menu starts
@@ -2657,6 +2658,14 @@
 STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT          :{YELLOW}Buy 1 year's exclusive transport rights in town. Town authority will only allow passengers and cargo to use your company's stations.{}Cost: {CURRENCY_LONG}
 STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE                        :{YELLOW}Bribe the local authority to increase your rating, at the risk of a severe penalty if caught.{}Cost: {CURRENCY_LONG}
 
+# Goal window
+STR_GOALS_CAPTION                                               :{WHITE}Goals
+STR_GOALS_GLOBAL_TITLE                                          :{BLACK}Global goals:
+STR_GOALS_TEXT                                                  :{ORANGE}{RAW_STRING}
+STR_GOALS_NONE                                                  :{ORANGE}- None -
+STR_GOALS_COMPANY_TITLE                                         :{BLACK}Company goals:
+STR_GOALS_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER                    :{BLACK}Click on goal to centre main view on industry/town/tile. Ctrl+Click opens a new viewport on industry/town/tile location
+
 # Subsidies window
 STR_SUBSIDIES_CAPTION                                           :{WHITE}Subsidies
 STR_SUBSIDIES_OFFERED_TITLE                                     :{BLACK}Subsidies on offer for services taking:
new file mode 100644
--- /dev/null
+++ b/src/saveload/goal_sl.cpp
@@ -0,0 +1,45 @@
+/* $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 goal_sl.cpp Code handling saving and loading of goals */
+
+#include "../stdafx.h"
+#include "../goal_base.h"
+
+#include "saveload.h"
+
+static const SaveLoad _goals_desc[] = {
+	    SLE_VAR(Goal, company, SLE_UINT16),
+	    SLE_VAR(Goal, type,    SLE_UINT16),
+	    SLE_VAR(Goal, dst,     SLE_UINT32),
+	    SLE_STR(Goal, text,    SLE_STR, 0),
+	    SLE_END()
+};
+
+static void Save_GOAL()
+{
+	Goal *s;
+	FOR_ALL_GOALS(s) {
+		SlSetArrayIndex(s->index);
+		SlObject(s, _goals_desc);
+	}
+}
+
+static void Load_GOAL()
+{
+	int index;
+	while ((index = SlIterateArray()) != -1) {
+		Goal *s = new (index) Goal();
+		SlObject(s, _goals_desc);
+	}
+}
+
+extern const ChunkHandler _goal_chunk_handlers[] = {
+	{ 'GOAL', Save_GOAL, Load_GOAL, NULL, NULL, CH_ARRAY | CH_LAST},
+};
--- a/src/saveload/saveload.cpp
+++ b/src/saveload/saveload.cpp
@@ -402,6 +402,7 @@
 extern const ChunkHandler _industry_chunk_handlers[];
 extern const ChunkHandler _economy_chunk_handlers[];
 extern const ChunkHandler _subsidy_chunk_handlers[];
+extern const ChunkHandler _goal_chunk_handlers[];
 extern const ChunkHandler _ai_chunk_handlers[];
 extern const ChunkHandler _game_chunk_handlers[];
 extern const ChunkHandler _animated_tile_chunk_handlers[];
@@ -429,6 +430,7 @@
 	_industry_chunk_handlers,
 	_economy_chunk_handlers,
 	_subsidy_chunk_handlers,
+	_goal_chunk_handlers,
 	_engine_chunk_handlers,
 	_town_chunk_handlers,
 	_sign_chunk_handlers,
new file mode 100644
--- /dev/null
+++ b/src/script/api/game/game_goal.hpp.sq
@@ -0,0 +1,36 @@
+/* $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/>.
+ */
+
+/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
+
+#include "../script_goal.hpp"
+#include "../template/template_goal.hpp.sq"
+
+
+template <> const char *GetClassName<ScriptGoal, ST_GS>() { return "GSGoal"; }
+
+void SQGSGoal_Register(Squirrel *engine)
+{
+	DefSQClass<ScriptGoal, ST_GS> SQGSGoal("GSGoal");
+	SQGSGoal.PreRegister(engine);
+	SQGSGoal.AddConstructor<void (ScriptGoal::*)(), 1>(engine, "x");
+
+	SQGSGoal.DefSQConst(engine, ScriptGoal::GOAL_INVALID, "GOAL_INVALID");
+	SQGSGoal.DefSQConst(engine, ScriptGoal::GT_NONE,      "GT_NONE");
+	SQGSGoal.DefSQConst(engine, ScriptGoal::GT_TILE,      "GT_TILE");
+	SQGSGoal.DefSQConst(engine, ScriptGoal::GT_INDUSTRY,  "GT_INDUSTRY");
+	SQGSGoal.DefSQConst(engine, ScriptGoal::GT_TOWN,      "GT_TOWN");
+	SQGSGoal.DefSQConst(engine, ScriptGoal::GT_COMPANY,   "GT_COMPANY");
+
+	SQGSGoal.DefSQStaticMethod(engine, &ScriptGoal::IsValidGoal, "IsValidGoal", 2, ".i");
+	SQGSGoal.DefSQStaticMethod(engine, &ScriptGoal::New,         "New",         5, ".i.ii");
+	SQGSGoal.DefSQStaticMethod(engine, &ScriptGoal::Remove,      "Remove",      2, ".i");
+
+	SQGSGoal.PostRegister(engine);
+}
new file mode 100644
--- /dev/null
+++ b/src/script/api/script_goal.cpp
@@ -0,0 +1,51 @@
+/* $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 script_goal.cpp Implementation of ScriptGoal. */
+
+#include "../../stdafx.h"
+#include "script_goal.hpp"
+#include "script_error.hpp"
+#include "script_industry.hpp"
+#include "script_map.hpp"
+#include "script_town.hpp"
+#include "../script_instance.hpp"
+#include "../../command_type.h"
+#include "../../settings_type.h"
+#include "../../openttd.h"
+#include "../../network/network.h"
+#include "../../goal_base.h"
+#include "../../string_func.h"
+
+/* static */ bool ScriptGoal::IsValidGoal(GoalID goal_id)
+{
+	return ::Goal::IsValidID(goal_id);
+}
+
+/* static */ ScriptGoal::GoalID ScriptGoal::New(ScriptCompany::CompanyID company, const char *goal, GoalType type, uint32 destination)
+{
+	EnforcePrecondition(GOAL_INVALID, !StrEmpty(goal));
+	EnforcePrecondition(GOAL_INVALID, company == ScriptCompany::COMPANY_INVALID || ScriptCompany::ResolveCompanyID(company) != ScriptCompany::COMPANY_INVALID);
+	EnforcePrecondition(GOAL_INVALID, (type == GT_NONE && destination == 0) || (type == GT_TILE && ScriptMap::IsValidTile(destination)) || (type == GT_INDUSTRY && ScriptIndustry::IsValidIndustry(destination)) || (type == GT_TOWN && ScriptTown::IsValidTown(destination)) || (type == GT_COMPANY && ScriptCompany::ResolveCompanyID((ScriptCompany::CompanyID)destination) != ScriptCompany::COMPANY_INVALID));
+
+	uint8 c = company;
+	if (company == ScriptCompany::COMPANY_INVALID) c = INVALID_COMPANY;
+
+	if (!ScriptObject::DoCommand(0, type | (c << 8), destination, CMD_CREATE_GOAL, goal, &ScriptInstance::DoCommandReturnGoalID)) return GOAL_INVALID;
+
+	/* In case of test-mode, we return GoalID 0 */
+	return (ScriptGoal::GoalID)0;
+}
+
+/* static */ bool ScriptGoal::Remove(GoalID goal_id)
+{
+	EnforcePrecondition(false, IsValidGoal(goal_id));
+
+	return ScriptObject::DoCommand(0, goal_id, 0, CMD_REMOVE_GOAL);
+}
new file mode 100644
--- /dev/null
+++ b/src/script/api/script_goal.hpp
@@ -0,0 +1,73 @@
+/* $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 script_goal.hpp Everything to manipulate the current running goal. */
+
+#ifndef SCRIPT_GOAL_HPP
+#define SCRIPT_GOAL_HPP
+
+#include "script_object.hpp"
+#include "script_company.hpp"
+#include "../../goal_type.h"
+
+/**
+ * Class that handles some goal related functions.
+ * @api game
+ */
+class ScriptGoal : public ScriptObject {
+public:
+	/**
+	 * The goal IDs.
+	 */
+	enum GoalID {
+		/* Note: these values represent part of the in-game GoalID enum */
+		GOAL_INVALID = ::INVALID_GOALTYPE, ///< An invalid goal id.
+	};
+
+	/**
+	 * Goal types that can be given to a goal.
+	 */
+	enum GoalType {
+		/* Note: these values represent part of the in-game GoalType enum */
+		GT_NONE     = ::GT_NONE,     ///< Destination is not linked.
+		GT_TILE     = ::GT_TILE,     ///< Destination is a tile.
+		GT_INDUSTRY = ::GT_INDUSTRY, ///< Destination is an industry.
+		GT_TOWN     = ::GT_TOWN,     ///< Destination is a town.
+		GT_COMPANY  = ::GT_COMPANY,  ///< Destination is a company.
+	};
+
+	/**
+	 * Check whether this is a valid goalID.
+	 * @param goal_id The GoalID to check.
+	 * @return True if and only if this goal is valid.
+	 */
+	static bool IsValidGoal(GoalID goal_id);
+
+	/**
+	 * Create a new goal.
+	 * @param company The company to create the goal for, or ScriptCompany::COMPANY_INVALID for all.
+	 * @param goal The goal to add to the GUI.
+	 * @param type The type of the goal.
+	 * @param destination The destination of the #type type.
+	 * @return The new GoalID, or GOAL_INVALID if it failed.
+	 * @pre goal != NULL.
+	 * @pre company == COMPANY_INVALID || ResolveCompanyID(company) != COMPANY_INVALID.
+	 */
+	static GoalID New(ScriptCompany::CompanyID company, const char *goal, GoalType type, uint32 destination);
+
+	/**
+	 * Remove a goal from the list.
+	 * @param goal_id The goal to remove.
+	 * @return True if the action succeeded.
+	 * @pre IsValidGoal(goal_id).
+	 */
+	static bool Remove(GoalID goal_id);
+};
+
+#endif /* SCRIPT_GOAL_HPP */
--- a/src/script/api/script_object.cpp
+++ b/src/script/api/script_object.cpp
@@ -16,6 +16,7 @@
 #include "../../network/network.h"
 #include "../../tunnelbridge.h"
 #include "../../genworld.h"
+#include "../../goal_type.h"
 
 #include "../script_storage.hpp"
 #include "../script_instance.hpp"
@@ -142,6 +143,7 @@
 	SetNewVehicleID(_new_vehicle_id);
 	SetNewSignID(_new_sign_id);
 	SetNewGroupID(_new_group_id);
+	SetNewGoalID(_new_goal_id);
 }
 
 /* static */ bool ScriptObject::GetLastCommandRes()
@@ -179,6 +181,16 @@
 	return GetStorage()->new_group_id;
 }
 
+/* static */ void ScriptObject::SetNewGoalID(GoalID goal_id)
+{
+	GetStorage()->new_goal_id = goal_id;
+}
+
+/* static */ GroupID ScriptObject::GetNewGoalID()
+{
+	return GetStorage()->new_goal_id;
+}
+
 /* static */ void ScriptObject::SetAllowDoCommand(bool allow)
 {
 	GetStorage()->allow_do_command = allow;
--- a/src/script/api/script_object.hpp
+++ b/src/script/api/script_object.hpp
@@ -161,6 +161,11 @@
 	static GroupID GetNewGroupID();
 
 	/**
+	 * Get the latest stored new_goal_id.
+	 */
+	static GoalID GetNewGoalID();
+
+	/**
 	 * Store a allow_do_command per company.
 	 * @param allow The new allow.
 	 */
@@ -228,6 +233,12 @@
 	 * @param group_id The new GroupID.
 	 */
 	static void SetNewGroupID(GroupID group_id);
+
+	/**
+	 * Store a new_goal_id per company.
+	 * @param goal_id The new GoalID.
+	 */
+	static void SetNewGoalID(GoalID goal_id);
 };
 
 #endif /* SCRIPT_OBJECT_HPP */
--- a/src/script/api/script_types.hpp
+++ b/src/script/api/script_types.hpp
@@ -32,6 +32,10 @@
  *                           <td> introduction, preview \ref dynamic_engines "(2)"  </td>
  *                           <td> engines retires \ref dynamic_engines "(2)"        </td>
  *                           <td> no \ref dynamic_engines "(2)"                     </td></tr>
+ * <tr><td>#GoalID      </td><td> goal                                              </td>
+ *                           <td> creation                                          </td>
+ *                           <td> deletion                                          </td>
+ *                           <td> yes                                               </td></tr>
  * <tr><td>#GroupID     </td><td> vehicle group                                     </td>
  *                           <td> creation                                          </td>
  *                           <td> deletion                                          </td>
@@ -87,6 +91,7 @@
 typedef byte CargoID;        ///< The ID of a cargo.
 class CommandCost;           ///< The cost of a command.
 typedef uint16 EngineID;     ///< The ID of an engine.
+typedef uint16 GoalID;       ///< The ID of a goal.
 typedef uint16 GroupID;      ///< The ID of a group.
 typedef uint16 IndustryID;   ///< The ID of an industry.
 typedef uint8 IndustryType;  ///< The ID of an industry-type.
new file mode 100644
--- /dev/null
+++ b/src/script/api/template/template_goal.hpp.sq
@@ -0,0 +1,27 @@
+/* $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/>.
+ */
+
+/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
+
+#include "../script_goal.hpp"
+
+namespace SQConvert {
+	/* Allow enums to be used as Squirrel parameters */
+	template <> inline ScriptGoal::GoalID GetParam(ForceType<ScriptGoal::GoalID>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (ScriptGoal::GoalID)tmp; }
+	template <> inline int Return<ScriptGoal::GoalID>(HSQUIRRELVM vm, ScriptGoal::GoalID res) { sq_pushinteger(vm, (int32)res); return 1; }
+	template <> inline ScriptGoal::GoalType GetParam(ForceType<ScriptGoal::GoalType>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (ScriptGoal::GoalType)tmp; }
+	template <> inline int Return<ScriptGoal::GoalType>(HSQUIRRELVM vm, ScriptGoal::GoalType res) { sq_pushinteger(vm, (int32)res); return 1; }
+
+	/* Allow ScriptGoal to be used as Squirrel parameter */
+	template <> inline ScriptGoal *GetParam(ForceType<ScriptGoal *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (ScriptGoal *)instance; }
+	template <> inline ScriptGoal &GetParam(ForceType<ScriptGoal &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptGoal *)instance; }
+	template <> inline const ScriptGoal *GetParam(ForceType<const ScriptGoal *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (ScriptGoal *)instance; }
+	template <> inline const ScriptGoal &GetParam(ForceType<const ScriptGoal &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptGoal *)instance; }
+	template <> inline int Return<ScriptGoal *>(HSQUIRRELVM vm, ScriptGoal *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Goal", res, NULL, DefSQDestructorCallback<ScriptGoal>, true); return 1; }
+} // namespace SQConvert
--- a/src/script/script_instance.cpp
+++ b/src/script/script_instance.cpp
@@ -245,6 +245,11 @@
 	instance->engine->InsertResult(ScriptObject::GetNewGroupID());
 }
 
+/* static */ void ScriptInstance::DoCommandReturnGoalID(ScriptInstance *instance)
+{
+	instance->engine->InsertResult(ScriptObject::GetNewGoalID());
+}
+
 ScriptStorage *ScriptInstance::GetStorage()
 {
 	return this->storage;
--- a/src/script/script_instance.hpp
+++ b/src/script/script_instance.hpp
@@ -100,6 +100,11 @@
 	static void DoCommandReturnGroupID(ScriptInstance *instance);
 
 	/**
+	 * Return a GoalID reply for a DoCommand.
+	 */
+	static void DoCommandReturnGoalID(ScriptInstance *instance);
+
+	/**
 	 * Get the controller attached to the instance.
 	 */
 	class ScriptController *GetController() { return controller; }
--- a/src/script/script_storage.hpp
+++ b/src/script/script_storage.hpp
@@ -16,6 +16,7 @@
 #include "../vehicle_func.h"
 #include "../road_type.h"
 #include "../group.h"
+#include "../goal_type.h"
 
 #include "table/strings.h"
 #include <vector>
@@ -45,6 +46,7 @@
 	VehicleID new_vehicle_id;        ///< The ID of the new Vehicle.
 	SignID new_sign_id;              ///< The ID of the new Sign.
 	GroupID new_group_id;            ///< The ID of the new Group.
+	GoalID new_goal_id;              ///< The ID of the new Goal.
 
 	std::vector<int> callback_value; ///< The values which need to survive a callback.
 
--- a/src/toolbar_gui.cpp
+++ b/src/toolbar_gui.cpp
@@ -475,7 +475,7 @@
 
 static CallBackFunction ToolbarSubsidiesClick(Window *w)
 {
-	PopupMainToolbMenu(w, WID_TN_SUBSIDIES, STR_SUBSIDIES_MENU_SUBSIDIES, 1);
+	PopupMainToolbMenu(w, WID_TN_SUBSIDIES, STR_SUBSIDIES_MENU_SUBSIDIES, 2);
 	return CBF_NONE;
 }
 
@@ -487,7 +487,10 @@
  */
 static CallBackFunction MenuClickSubsidies(int index)
 {
-	ShowSubsidiesList();
+	switch (index) {
+		case 0: ShowSubsidiesList(); break;
+		case 1: ShowGoalsList();     break;
+	}
 	return CBF_NONE;
 }
 
new file mode 100644
--- /dev/null
+++ b/src/widgets/goal_widget.h
@@ -0,0 +1,22 @@
+
+/* $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 goal_widget.h Types related to the goal widgets. */
+
+#ifndef WIDGETS_GOAL_WIDGET_H
+#define WIDGETS_GOAL_WIDGET_H
+
+/** Widgets of the #GoalListWindow class. */
+enum GoalListWidgets {
+	WID_GL_PANEL,     ///< Panel of the window.
+	WID_GL_SCROLLBAR, ///< Scrollbar of the panel.
+};
+
+#endif /* WIDGETS_GOAL_WIDGET_H */
--- a/src/window_type.h
+++ b/src/window_type.h
@@ -277,6 +277,12 @@
 	 */
 	WC_AI_LIST,
 
+	/**
+	 * Goals list; Window numbers:
+	 *   - 0 ; #GoalListWidgets
+	 */
+	WC_GOALS_LIST,
+
 
 	/**
 	 * Station list; Window numbers: