Fix 03cc0d6: Mark level crossings dirty when removing road from them, not from bridge...
[openttd-github.git] / src / misc_cmd.cpp
blob6422bcf3aca581a1b2e73a602dc37c7e50266b46
1 /*
2 * This file is part of OpenTTD.
3 * 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.
4 * 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.
5 * 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/>.
6 */
8 /** @file misc_cmd.cpp Some misc functions that are better fitted in other files, but never got moved there... */
10 #include "stdafx.h"
11 #include "command_func.h"
12 #include "economy_func.h"
13 #include "window_func.h"
14 #include "textbuf_gui.h"
15 #include "network/network.h"
16 #include "network/network_func.h"
17 #include "strings_func.h"
18 #include "company_func.h"
19 #include "company_gui.h"
20 #include "company_base.h"
21 #include "tile_map.h"
22 #include "texteff.hpp"
23 #include "core/backup_type.hpp"
24 #include "misc_cmd.h"
26 #include "table/strings.h"
28 #include "safeguards.h"
30 /**
31 * Increase the loan of your company.
32 * @param flags operation to perform
33 * @param cmd when LoanCommand::Interval: loans LOAN_INTERVAL,
34 * when LoanCommand::Max: loans the maximum loan permitting money (press CTRL),
35 * when LoanCommand::Amount: loans the amount specified in \c amount
36 * @param amount amount to increase the loan with, multitude of LOAN_INTERVAL. Only used when cmd == LoanCommand::Amount.
37 * @return the cost of this operation or an error
39 CommandCost CmdIncreaseLoan(DoCommandFlag flags, LoanCommand cmd, Money amount)
41 Company *c = Company::Get(_current_company);
43 if (c->current_loan >= _economy.max_loan) {
44 SetDParam(0, _economy.max_loan);
45 return_cmd_error(STR_ERROR_MAXIMUM_PERMITTED_LOAN);
48 Money loan;
49 switch (cmd) {
50 default: return CMD_ERROR; // Invalid method
51 case LoanCommand::Interval: // Take some extra loan
52 loan = LOAN_INTERVAL;
53 break;
54 case LoanCommand::Max: // Take a loan as big as possible
55 loan = _economy.max_loan - c->current_loan;
56 break;
57 case LoanCommand::Amount: // Take the given amount of loan
58 loan = amount;
59 if (loan < LOAN_INTERVAL || c->current_loan + loan > _economy.max_loan || loan % LOAN_INTERVAL != 0) return CMD_ERROR;
60 break;
63 /* Overflow protection */
64 if (c->money + c->current_loan + loan < c->money) return CMD_ERROR;
66 if (flags & DC_EXEC) {
67 c->money += loan;
68 c->current_loan += loan;
69 InvalidateCompanyWindows(c);
72 return CommandCost(EXPENSES_OTHER);
75 /**
76 * Decrease the loan of your company.
77 * @param flags operation to perform
78 * @param cmd when LoanCommand::Interval: pays back LOAN_INTERVAL,
79 * when LoanCommand::Max: pays back the maximum loan permitting money (press CTRL),
80 * when LoanCommand::Amount: pays back the amount specified in \c amount
81 * @param amount amount to decrease the loan with, multitude of LOAN_INTERVAL. Only used when cmd == LoanCommand::Amount.
82 * @return the cost of this operation or an error
84 CommandCost CmdDecreaseLoan(DoCommandFlag flags, LoanCommand cmd, Money amount)
86 Company *c = Company::Get(_current_company);
88 if (c->current_loan == 0) return_cmd_error(STR_ERROR_LOAN_ALREADY_REPAYED);
90 Money loan;
91 switch (cmd) {
92 default: return CMD_ERROR; // Invalid method
93 case LoanCommand::Interval: // Pay back one step
94 loan = std::min(c->current_loan, (Money)LOAN_INTERVAL);
95 break;
96 case LoanCommand::Max: // Pay back as much as possible
97 loan = std::max(std::min(c->current_loan, c->money), (Money)LOAN_INTERVAL);
98 loan -= loan % LOAN_INTERVAL;
99 break;
100 case LoanCommand::Amount: // Repay the given amount of loan
101 loan = amount;
102 if (loan % LOAN_INTERVAL != 0 || loan < LOAN_INTERVAL || loan > c->current_loan) return CMD_ERROR; // Invalid amount to loan
103 break;
106 if (c->money < loan) {
107 SetDParam(0, loan);
108 return_cmd_error(STR_ERROR_CURRENCY_REQUIRED);
111 if (flags & DC_EXEC) {
112 c->money -= loan;
113 c->current_loan -= loan;
114 InvalidateCompanyWindows(c);
116 return CommandCost();
120 * In case of an unsafe unpause, we want the
121 * user to confirm that it might crash.
122 * @param w unused
123 * @param confirmed whether the user confirmed their action
125 static void AskUnsafeUnpauseCallback(Window *w, bool confirmed)
127 if (confirmed) {
128 Command<CMD_PAUSE>::Post(PM_PAUSED_ERROR, false);
133 * Pause/Unpause the game (server-only).
134 * Set or unset a bit in the pause mode. If pause mode is zero the game is
135 * unpaused. A bitset is used instead of a boolean value/counter to have
136 * more control over the game when saving/loading, etc.
137 * @param flags operation to perform
138 * @param mode the pause mode to change
139 * @param pause true pauses, false unpauses this mode
140 * @return the cost of this operation or an error
142 CommandCost CmdPause(DoCommandFlag flags, PauseMode mode, bool pause)
144 switch (mode) {
145 case PM_PAUSED_SAVELOAD:
146 case PM_PAUSED_ERROR:
147 case PM_PAUSED_NORMAL:
148 case PM_PAUSED_GAME_SCRIPT:
149 case PM_PAUSED_LINK_GRAPH:
150 break;
152 case PM_PAUSED_JOIN:
153 case PM_PAUSED_ACTIVE_CLIENTS:
154 if (!_networking) return CMD_ERROR;
155 break;
157 default: return CMD_ERROR;
159 if (flags & DC_EXEC) {
160 if (mode == PM_PAUSED_NORMAL && _pause_mode & PM_PAUSED_ERROR) {
161 ShowQuery(
162 STR_NEWGRF_UNPAUSE_WARNING_TITLE,
163 STR_NEWGRF_UNPAUSE_WARNING,
164 nullptr,
165 AskUnsafeUnpauseCallback
167 } else {
168 PauseMode prev_mode = _pause_mode;
170 if (pause) {
171 _pause_mode |= mode;
172 } else {
173 _pause_mode &= ~mode;
176 NetworkHandlePauseChange(prev_mode, mode);
179 SetWindowDirty(WC_STATUS_BAR, 0);
180 SetWindowDirty(WC_MAIN_TOOLBAR, 0);
182 return CommandCost();
186 * Change the financial flow of your company.
187 * @param flags operation to perform
188 * @param amount the amount of money to receive (if positive), or spend (if negative)
189 * @return the cost of this operation or an error
191 CommandCost CmdMoneyCheat(DoCommandFlag flags, Money amount)
193 return CommandCost(EXPENSES_OTHER, -amount);
197 * Change the bank bank balance of a company by inserting or removing money without affecting the loan.
198 * @param flags operation to perform
199 * @param tile tile to show text effect on (if not 0)
200 * @param delta the amount of money to receive (if positive), or spend (if negative)
201 * @param company the company ID.
202 * @param expenses_type the expenses type which should register the cost/income @see ExpensesType.
203 * @return zero cost or an error
205 CommandCost CmdChangeBankBalance(DoCommandFlag flags, TileIndex tile, Money delta, CompanyID company, ExpensesType expenses_type)
207 if (!Company::IsValidID(company)) return CMD_ERROR;
208 if (expenses_type >= EXPENSES_END) return CMD_ERROR;
209 if (_current_company != OWNER_DEITY) return CMD_ERROR;
211 if (flags & DC_EXEC) {
212 /* Change company bank balance of company. */
213 Backup<CompanyID> cur_company(_current_company, company, FILE_LINE);
214 SubtractMoneyFromCompany(CommandCost(expenses_type, -delta));
215 cur_company.Restore();
217 if (tile != 0) {
218 ShowCostOrIncomeAnimation(TileX(tile) * TILE_SIZE, TileY(tile) * TILE_SIZE, GetTilePixelZ(tile), -delta);
222 /* This command doesn't cost anything for deity. */
223 CommandCost zero_cost(expenses_type, 0);
224 return zero_cost;