summaryrefslogtreecommitdiff
path: root/src/script/api/script_goal.hpp
blob: 372d6e8b499cfa2bc9c1caa70cb3ba31d94bd877 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
/*
 * 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_client.hpp"
#include "script_company.hpp"
#include "../../goal_type.h"

/**
 * Class that handles some goal related functions.
 *
 * Goals are saved and loaded. Upon bankruptcy or company takeover, all company
 * specific goals are removed for that company. You can also remove individual
 * goals using #Remove.
 *
 * @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.
		GT_STORY_PAGE = ::GT_STORY_PAGE ///< Destination is a story page.
	};

	/**
	 * Types of queries we could do to the user.
	 * Basically the title of the question window.
	 */
	enum QuestionType {
		QT_QUESTION,    ///< Asking a simple question; title: Question.
		QT_INFORMATION, ///< Showing an informational message; title: Information.
		QT_WARNING,     ///< Showing a warning; title: Warning.
		QT_ERROR,       ///< Showing an error; title: Error.
	};

	/**
	 * Types of buttons that can be in the question window.
	 */
	enum QuestionButton {
		/* Note: these values represent part of the string list starting with STR_GOAL_QUESTION_BUTTON_CANCEL */
		BUTTON_CANCEL    = (1 << 0),  ///< Cancel button.
		BUTTON_OK        = (1 << 1),  ///< OK button.
		BUTTON_NO        = (1 << 2),  ///< No button.
		BUTTON_YES       = (1 << 3),  ///< Yes button.
		BUTTON_DECLINE   = (1 << 4),  ///< Decline button.
		BUTTON_ACCEPT    = (1 << 5),  ///< Accept button.
		BUTTON_IGNORE    = (1 << 6),  ///< Ignore button.
		BUTTON_RETRY     = (1 << 7),  ///< Retry button.
		BUTTON_PREVIOUS  = (1 << 8),  ///< Previous button.
		BUTTON_NEXT      = (1 << 9),  ///< Next button.
		BUTTON_STOP      = (1 << 10), ///< Stop button.
		BUTTON_START     = (1 << 11), ///< Start button.
		BUTTON_GO        = (1 << 12), ///< Go button.
		BUTTON_CONTINUE  = (1 << 13), ///< Continue button.
		BUTTON_RESTART   = (1 << 14), ///< Restart button.
		BUTTON_POSTPONE  = (1 << 15), ///< Postpone button.
		BUTTON_SURRENDER = (1 << 16), ///< Surrender button.
		BUTTON_CLOSE     = (1 << 17), ///< Close button.
	};

	/**
	 * 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 (can be either a raw string, or a ScriptText object).
	 * @param type The type of the goal.
	 * @param destination The destination of the \a type type.
	 * @return The new GoalID, or GOAL_INVALID if it failed.
	 * @pre No ScriptCompanyMode may be in scope.
	 * @pre goal != nullptr && len(goal) != 0.
	 * @pre company == COMPANY_INVALID || ResolveCompanyID(company) != COMPANY_INVALID.
	 * @pre if type is GT_STORY_PAGE, the company of the goal and the company of the story page need to match:
	 *       \li Global goals can only reference global story pages.
	 *       \li Company specific goals can reference global story pages and story pages of the same company.
	 */
	static GoalID New(ScriptCompany::CompanyID company, Text *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 No ScriptCompanyMode may be in scope.
	 * @pre IsValidGoal(goal_id).
	 */
	static bool Remove(GoalID goal_id);

	/**
	 * Update goal text of a goal.
	 * @param goal_id The goal to update.
	 * @param goal The new goal text (can be either a raw string, or a ScriptText object).
	 * @return True if the action succeeded.
	 * @pre No ScriptCompanyMode may be in scope.
	 * @pre goal != nullptr && len(goal) != 0.
	 * @pre IsValidGoal(goal_id).
	 */
	static bool SetText(GoalID goal_id, Text *goal);

	/**
	 * Update the progress text of a goal. The progress text is a text that
	 * is shown adjacent to the goal but in a separate column. Try to keep
	 * the progress string short.
	 * @param goal_id The goal to update.
	 * @param progress The new progress text for the goal (can be either a raw string,
	 * or a ScriptText object). To clear the progress string you can pass nullptr or an
	 * empty string.
	 * @return True if the action succeeded.
	 * @pre No ScriptCompanyMode may be in scope.
	 * @pre IsValidGoal(goal_id).
	 */
	static bool SetProgress(GoalID goal_id, Text *progress);

	/**
	 * Update completed status of goal
	 * @param goal_id The goal to update.
	 * @param complete The new goal completed status.
	 * @return True if the action succeeded.
	 * @pre No ScriptCompanyMode may be in scope.
	 * @pre IsValidGoal(goal_id).
	 */
	static bool SetCompleted(GoalID goal_id, bool complete);

	/**
	 * Checks if a given goal have been marked as completed.
	 * @param goal_id The goal to check complete status.
	 * @return True if the goal is completed, otherwise false.
	 * @pre No ScriptCompanyMode may be in scope.
	 * @pre IsValidGoal(goal_id).
	 */
	static bool IsCompleted(GoalID goal_id);

	/**
	 * Ask a question of all players in a company.
	 * @param uniqueid Your unique id to distinguish results of multiple questions in the returning event.
	 * @param company The company to ask the question, or ScriptCompany::COMPANY_INVALID for all.
	 * @param question The question to ask (can be either a raw string, or a ScriptText object).
	 * @param type The type of question that is being asked.
	 * @param buttons Any combinations (at least 1, up to 3) of buttons defined in QuestionButton. Like BUTTON_YES + BUTTON_NO.
	 * @return True if the action succeeded.
	 * @pre No ScriptCompanyMode may be in scope.
	 * @pre question != nullptr && len(question) != 0.
	 * @pre company == COMPANY_INVALID || ResolveCompanyID(company) != COMPANY_INVALID.
	 * @pre CountBits(buttons) >= 1 && CountBits(buttons) <= 3.
	 * @note Replies to the question are given by you via the event ScriptEvent_GoalQuestionAnswer.
	 * @note There is no guarantee you ever get a reply on your question.
	 */
	static bool Question(uint16 uniqueid, ScriptCompany::CompanyID company, Text *question, QuestionType type, int buttons);

	/**
	 * Ask client a question.
	 * @param uniqueid Your unique id to distinguish results of multiple questions in the returning event.
	 * @param client The client to ask the question.
	 * @param question The question to ask (can be either a raw string, or a ScriptText object).
	 * @param type The type of question that is being asked.
	 * @param buttons Any combinations (at least 1, up to 3) of buttons defined in QuestionButton. Like BUTTON_YES + BUTTON_NO.
	 * @return True if the action succeeded.
	 * @pre No ScriptCompanyMode may be in scope.
	 * @pre ScriptGame::IsMultiplayer()
	 * @pre question != nullptr && len(question) != 0.
	 * @pre ResolveClientID(client) != CLIENT_INVALID.
	 * @pre CountBits(buttons) >= 1 && CountBits(buttons) <= 3.
	 * @note Replies to the question are given by you via the event ScriptEvent_GoalQuestionAnswer.
	 * @note There is no guarantee you ever get a reply on your question.
	 */
	static bool QuestionClient(uint16 uniqueid, ScriptClient::ClientID client, Text *question, QuestionType type, int buttons);

	/**
	 * Close the question on all clients.
	 * @param uniqueid The uniqueid of the question you want to close.
	 * @return True if the action succeeded.
	 * @pre No ScriptCompanyMode may be in scope.
	 * @note If you send a question to a single company, and get a reply for them,
	 *   the question is already closed on all clients. Only use this function if
	 *   you want to timeout a question, or if you send the question to all
	 *   companies, but you are only interested in the reply of the first.
	 */
	static bool CloseQuestion(uint16 uniqueid);

protected:
	/**
	 * Does common checks and asks the question.
	 */
	static bool DoQuestion(uint16 uniqueid, uint32 target, bool is_client, Text *question, QuestionType type, uint32 buttons);
};

#endif /* SCRIPT_GOAL_HPP */