# misc_cmd.cpp

Go to the documentation of this file.

    00001 /* $Id: misc_cmd.cpp 25788 2013-09-21 13:07:42Z zuu $ */
    00002
    00003 /*
    00004  * This file is part of OpenTTD.
    00005  * 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.
    00006  * 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.
    00007  * 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/>.
    00008  */
    00009
    00012 #include "stdafx.h"
    00013 #include "command_func.h"
    00014 #include "economy_func.h"
    00015 #include "cmd_helper.h"
    00016 #include "window_func.h"
    00017 #include "textbuf_gui.h"
    00018 #include "network/network.h"
    00019 #include "network/network_func.h"
    00020 #include "strings_func.h"
    00021 #include "company_func.h"
    00022 #include "company_gui.h"
    00023 #include "company_base.h"
    00024 #include "core/backup_type.hpp"
    00025
    00026 #include "table/strings.h"
    00027
    00039 CommandCost CmdIncreaseLoan(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
    00040 {
    00041   Company *c = Company::Get(_current_company);
    00042
    00043   if (c->current_loan >= _economy.max_loan) {
    00044     SetDParam(0, _economy.max_loan);
    00045     return_cmd_error(STR_ERROR_MAXIMUM_PERMITTED_LOAN);
    00046   }
    00047
    00048   Money loan;
    00049   switch (p2) {
    00050     default: return CMD_ERROR; // Invalid method
    00051     case 0: // Take some extra loan
    00052       loan = LOAN_INTERVAL;
    00053       break;
    00054     case 1: // Take a loan as big as possible
    00055       loan = _economy.max_loan - c->current_loan;
    00056       break;
    00057     case 2: // Take the given amount of loan
    00058       if ((int32)p1 < LOAN_INTERVAL || c->current_loan + (int32)p1 > _economy.max_loan || p1 % LOAN_INTERVAL != 0) return CMD_ERROR;
    00059       loan = p1;
    00060       break;
    00061   }
    00062
    00063   /* Overflow protection */
    00064   if (c->money + c->current_loan + loan < c->money) return CMD_ERROR;
    00065
    00066   if (flags & DC_EXEC) {
    00067     c->money        += loan;
    00068     c->current_loan += loan;
    00069     InvalidateCompanyWindows(c);
    00070   }
    00071
    00072   return CommandCost(EXPENSES_OTHER);
    00073 }
    00074
    00086 CommandCost CmdDecreaseLoan(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
    00087 {
    00088   Company *c = Company::Get(_current_company);
    00089
    00090   if (c->current_loan == 0) return_cmd_error(STR_ERROR_LOAN_ALREADY_REPAYED);
    00091
    00092   Money loan;
    00093   switch (p2) {
    00094     default: return CMD_ERROR; // Invalid method
    00095     case 0: // Pay back one step
    00096       loan = min(c->current_loan, (Money)LOAN_INTERVAL);
    00097       break;
    00098     case 1: // Pay back as much as possible
    00099       loan = max(min(c->current_loan, c->money), (Money)LOAN_INTERVAL);
    00100       loan -= loan % LOAN_INTERVAL;
    00101       break;
    00102     case 2: // Repay the given amount of loan
    00103       if (p1 % LOAN_INTERVAL != 0 || (int32)p1 < LOAN_INTERVAL || p1 > c->current_loan) return CMD_ERROR; // Invalid amount to loan
    00104       loan = p1;
    00105       break;
    00106   }
    00107
    00108   if (c->money < loan) {
    00109     SetDParam(0, loan);
    00110     return_cmd_error(STR_ERROR_CURRENCY_REQUIRED);
    00111   }
    00112
    00113   if (flags & DC_EXEC) {
    00114     c->money        -= loan;
    00115     c->current_loan -= loan;
    00116     InvalidateCompanyWindows(c);
    00117   }
    00118   return CommandCost();
    00119 }
    00120
    00127 static void AskUnsafeUnpauseCallback(Window *w, bool confirmed)
    00128 {
    00129   if (confirmed) {
    00130     DoCommandP(0, PM_PAUSED_ERROR, 0, CMD_PAUSE);
    00131   }
    00132 }
    00133
    00146 CommandCost CmdPause(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
    00147 {
    00148   switch (p1) {
    00149     case PM_PAUSED_SAVELOAD:
    00150     case PM_PAUSED_ERROR:
    00151     case PM_PAUSED_NORMAL:
    00152     case PM_PAUSED_GAME_SCRIPT:
    00153       break;
    00154
    00155 #ifdef ENABLE_NETWORK
    00156     case PM_PAUSED_JOIN:
    00157     case PM_PAUSED_ACTIVE_CLIENTS:
    00158       if (!_networking) return CMD_ERROR;
    00159       break;
    00160 #endif /* ENABLE_NETWORK */
    00161
    00162     default: return CMD_ERROR;
    00163   }
    00164   if (flags & DC_EXEC) {
    00165     if (p1 == PM_PAUSED_NORMAL && _pause_mode & PM_PAUSED_ERROR) {
    00166       ShowQuery(
    00167         STR_NEWGRF_UNPAUSE_WARNING_TITLE,
    00168         STR_NEWGRF_UNPAUSE_WARNING,
    00169         NULL,
    00170         AskUnsafeUnpauseCallback
    00171       );
    00172     } else {
    00173 #ifdef ENABLE_NETWORK
    00174       PauseMode prev_mode = _pause_mode;
    00175 #endif /* ENABLE_NETWORK */
    00176
    00177       if (p2 == 0) {
    00178         _pause_mode = _pause_mode & ~p1;
    00179       } else {
    00180         _pause_mode = _pause_mode | p1;
    00181       }
    00182
    00183 #ifdef ENABLE_NETWORK
    00184       NetworkHandlePauseChange(prev_mode, (PauseMode)p1);
    00185 #endif /* ENABLE_NETWORK */
    00186     }
    00187
    00188     SetWindowDirty(WC_STATUS_BAR, 0);
    00189     SetWindowDirty(WC_MAIN_TOOLBAR, 0);
    00190   }
    00191   return CommandCost();
    00192 }
    00193
    00203 CommandCost CmdMoneyCheat(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
    00204 {
    00205   return CommandCost(EXPENSES_OTHER, -(int32)p1);
    00206 }
    00207
    00218 CommandCost CmdChangeBankBalance(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
    00219 {
    00220   int32 delta = (int32)p1;
    00221   CompanyID company = (CompanyID) GB(p2, 0, 8);
    00222   ExpensesType expenses_type = Extract<ExpensesType, 8, 8>(p2);
    00223
    00224   if (!Company::IsValidID(company)) return CMD_ERROR;
    00225   if (expenses_type >= EXPENSES_END) return CMD_ERROR;
    00226   if (_current_company != OWNER_DEITY) return CMD_ERROR;
    00227
    00228   if (flags & DC_EXEC) {
    00229     /* Change company bank balance of company. */
    00230     Backup<CompanyByte> cur_company(_current_company, company, FILE_LINE);
    00231     SubtractMoneyFromCompany(CommandCost(expenses_type, -delta));
    00232     cur_company.Restore();
    00233   }
    00234
    00235   /* This command doesn't cost anyting for deity. */
    00236   CommandCost zero_cost(expenses_type, 0);
    00237   return zero_cost;
    00238 }
    00239
    00252 CommandCost CmdGiveMoney(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
    00253 {
    00254   if (!_settings_game.economy.give_money) return CMD_ERROR;
    00255
    00256   const Company *c = Company::Get(_current_company);
    00257   CommandCost amount(EXPENSES_OTHER, min((Money)p1, (Money)20000000LL));
    00258   CompanyID dest_company = (CompanyID)p2;
    00259
    00260   /* You can only transfer funds that is in excess of your loan */
    00261   if (c->money - c->current_loan < amount.GetCost() || amount.GetCost() < 0) return CMD_ERROR;
    00262   if (!_networking || !Company::IsValidID(dest_company)) return CMD_ERROR;
    00263
    00264   if (flags & DC_EXEC) {
    00265     /* Add money to company */
    00266     Backup<CompanyByte> cur_company(_current_company, dest_company, FILE_LINE);
    00267     SubtractMoneyFromCompany(CommandCost(EXPENSES_OTHER, -amount.GetCost()));
    00268     cur_company.Restore();
    00269   }
    00270
    00271   /* Subtract money from local-company */
    00272   return amount;
    00273 }