diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/command.cpp | 4 | ||||
-rw-r--r-- | src/command_type.h | 2 | ||||
-rw-r--r-- | src/game/game_instance.cpp | 2 | ||||
-rw-r--r-- | src/goal.cpp | 120 | ||||
-rw-r--r-- | src/goal_base.h | 44 | ||||
-rw-r--r-- | src/goal_gui.cpp | 253 | ||||
-rw-r--r-- | src/goal_type.h | 33 | ||||
-rw-r--r-- | src/gui.h | 1 | ||||
-rw-r--r-- | src/lang/english.txt | 9 | ||||
-rw-r--r-- | src/saveload/goal_sl.cpp | 45 | ||||
-rw-r--r-- | src/saveload/saveload.cpp | 2 | ||||
-rw-r--r-- | src/script/api/game/game_goal.hpp.sq | 36 | ||||
-rw-r--r-- | src/script/api/script_goal.cpp | 51 | ||||
-rw-r--r-- | src/script/api/script_goal.hpp | 73 | ||||
-rw-r--r-- | src/script/api/script_object.cpp | 12 | ||||
-rw-r--r-- | src/script/api/script_object.hpp | 11 | ||||
-rw-r--r-- | src/script/api/script_types.hpp | 5 | ||||
-rw-r--r-- | src/script/api/template/template_goal.hpp.sq | 27 | ||||
-rw-r--r-- | src/script/script_instance.cpp | 5 | ||||
-rw-r--r-- | src/script/script_instance.hpp | 5 | ||||
-rw-r--r-- | src/script/script_storage.hpp | 2 | ||||
-rw-r--r-- | src/toolbar_gui.cpp | 7 | ||||
-rw-r--r-- | src/widgets/goal_widget.h | 22 | ||||
-rw-r--r-- | src/window_type.h | 6 |
24 files changed, 775 insertions, 2 deletions
diff --git a/src/command.cpp b/src/command.cpp index b34538294..47d305021 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -150,6 +150,8 @@ CommandProc CmdBuildLock; CommandProc CmdCreateSubsidy; CommandProc CmdCompanyCtrl; CommandProc CmdCustomNewsItem; +CommandProc CmdCreateGoal; +CommandProc CmdRemoveGoal; CommandProc CmdLevelLand; @@ -286,6 +288,8 @@ static const Command _command_proc_table[] = { 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 diff --git a/src/command_type.h b/src/command_type.h index eb1db573e..2e50c5eae 100644 --- a/src/command_type.h +++ b/src/command_type.h @@ -264,6 +264,8 @@ enum Commands { 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 diff --git a/src/game/game_instance.cpp b/src/game/game_instance.cpp index 438ccc019..ffe9a2db5 100644 --- 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 @@ void GameInstance::RegisterAPI() 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); diff --git a/src/goal.cpp b/src/goal.cpp new file mode 100644 index 000000000..91ba6d288 --- /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(); +} diff --git a/src/goal_base.h b/src/goal_base.h new file mode 100644 index 000000000..7b789abde --- /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 */ diff --git a/src/goal_gui.cpp b/src/goal_gui.cpp new file mode 100644 index 000000000..aeba8e576 --- /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); +} diff --git a/src/goal_type.h b/src/goal_type.h new file mode 100644 index 000000000..5014b1b21 --- /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 */ @@ -52,6 +52,7 @@ void ShowBuildTreesToolbar(); void ShowTownDirectory(); void ShowIndustryDirectory(); void ShowSubsidiesList(); +void ShowGoalsList(); void ShowEstimatedCostOrIncome(Money cost, int x, int y); diff --git a/src/lang/english.txt b/src/lang/english.txt index aa6c9b63a..e73a8f879 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -382,6 +382,7 @@ STR_TOWN_MENU_FOUND_TOWN :Found town ############ 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_NEW_BUILDINGS :{YELLOW}Fund th 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: diff --git a/src/saveload/goal_sl.cpp b/src/saveload/goal_sl.cpp new file mode 100644 index 000000000..721909a77 --- /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}, +}; diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index fe4053741..b45d105cf 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -402,6 +402,7 @@ extern const ChunkHandler _station_chunk_handlers[]; 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 @@ static const ChunkHandler * const _chunk_handlers[] = { _industry_chunk_handlers, _economy_chunk_handlers, _subsidy_chunk_handlers, + _goal_chunk_handlers, _engine_chunk_handlers, _town_chunk_handlers, _sign_chunk_handlers, diff --git a/src/script/api/game/game_goal.hpp.sq b/src/script/api/game/game_goal.hpp.sq new file mode 100644 index 000000000..54b1c6aeb --- /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); +} diff --git a/src/script/api/script_goal.cpp b/src/script/api/script_goal.cpp new file mode 100644 index 000000000..85aaeedb6 --- /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); +} diff --git a/src/script/api/script_goal.hpp b/src/script/api/script_goal.hpp new file mode 100644 index 000000000..ac7d8f449 --- /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 */ diff --git a/src/script/api/script_object.cpp b/src/script/api/script_object.cpp index d9a432b44..72185c786 100644 --- 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 @@ ScriptObject::ActiveInstance::~ActiveInstance() SetNewVehicleID(_new_vehicle_id); SetNewSignID(_new_sign_id); SetNewGroupID(_new_group_id); + SetNewGoalID(_new_goal_id); } /* static */ bool ScriptObject::GetLastCommandRes() @@ -179,6 +181,16 @@ ScriptObject::ActiveInstance::~ActiveInstance() 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; diff --git a/src/script/api/script_object.hpp b/src/script/api/script_object.hpp index d12f006ee..86bdbf8df 100644 --- a/src/script/api/script_object.hpp +++ b/src/script/api/script_object.hpp @@ -161,6 +161,11 @@ protected: 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 @@ private: * @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 */ diff --git a/src/script/api/script_types.hpp b/src/script/api/script_types.hpp index 1cce06571..2b763f4f5 100644 --- 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 uint BridgeType; ///< Internal name, not of any use for you. 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. diff --git a/src/script/api/template/template_goal.hpp.sq b/src/script/api/template/template_goal.hpp.sq new file mode 100644 index 000000000..012864324 --- /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 diff --git a/src/script/script_instance.cpp b/src/script/script_instance.cpp index 7a6b4fe70..641d939d3 100644 --- a/src/script/script_instance.cpp +++ b/src/script/script_instance.cpp @@ -245,6 +245,11 @@ void ScriptInstance::CollectGarbage() const instance->engine->InsertResult(ScriptObject::GetNewGroupID()); } +/* static */ void ScriptInstance::DoCommandReturnGoalID(ScriptInstance *instance) +{ + instance->engine->InsertResult(ScriptObject::GetNewGoalID()); +} + ScriptStorage *ScriptInstance::GetStorage() { return this->storage; diff --git a/src/script/script_instance.hpp b/src/script/script_instance.hpp index d24a40827..7617e370f 100644 --- a/src/script/script_instance.hpp +++ b/src/script/script_instance.hpp @@ -100,6 +100,11 @@ public: 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; } diff --git a/src/script/script_storage.hpp b/src/script/script_storage.hpp index 57cdc60ad..0af56b2b4 100644 --- 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 @@ private: 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. diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp index 84de5876b..de1fb73bf 100644 --- a/src/toolbar_gui.cpp +++ b/src/toolbar_gui.cpp @@ -475,7 +475,7 @@ static CallBackFunction MenuClickTown(int index) 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 ToolbarSubsidiesClick(Window *w) */ static CallBackFunction MenuClickSubsidies(int index) { - ShowSubsidiesList(); + switch (index) { + case 0: ShowSubsidiesList(); break; + case 1: ShowGoalsList(); break; + } return CBF_NONE; } diff --git a/src/widgets/goal_widget.h b/src/widgets/goal_widget.h new file mode 100644 index 000000000..aaa91acc3 --- /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 */ diff --git a/src/window_type.h b/src/window_type.h index 975103667..921e71dbc 100644 --- a/src/window_type.h +++ b/src/window_type.h @@ -277,6 +277,12 @@ enum WindowClass { */ WC_AI_LIST, + /** + * Goals list; Window numbers: + * - 0 ; #GoalListWidgets + */ + WC_GOALS_LIST, + /** * Station list; Window numbers: |