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 }