# misc_cmd.cpp

Go to the documentation of this file.

    00001 /* $Id$ */
    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 "window_func.h"
    00016 #include "textbuf_gui.h"
    00017 #include "network/network.h"
    00018 #include "network/network_func.h"
    00019 #include "company_manager_face.h"
    00020 #include "strings_func.h"
    00021 #include "gfx_func.h"
    00022 #include "functions.h"
    00023 #include "vehicle_func.h"
    00024 #include "company_func.h"
    00025 #include "company_gui.h"
    00026 #include "vehicle_base.h"
    00027
    00028 #include "table/strings.h"
    00029
    00038 CommandCost CmdSetCompanyManagerFace(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
    00039 {
    00040   CompanyManagerFace cmf = (CompanyManagerFace)p2;
    00041
    00042   if (!IsValidCompanyManagerFace(cmf)) return CMD_ERROR;
    00043
    00044   if (flags & DC_EXEC) {
    00045     Company::Get(_current_company)->face = cmf;
    00046     MarkWholeScreenDirty();
    00047   }
    00048   return CommandCost();
    00049 }
    00050
    00061 CommandCost CmdSetCompanyColour(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
    00062 {
    00063   if (p2 >= 16) return CMD_ERROR; // max 16 colours
    00064
    00065   Colours colour = (Colours)p2;
    00066
    00067   LiveryScheme scheme = (LiveryScheme)GB(p1, 0, 8);
    00068   byte state = GB(p1, 8, 2);
    00069
    00070   if (scheme >= LS_END || state >= 3) return CMD_ERROR;
    00071
    00072   Company *c = Company::Get(_current_company);
    00073
    00074   /* Ensure no two companies have the same primary colour */
    00075   if (scheme == LS_DEFAULT && state == 0) {
    00076     const Company *cc;
    00077     FOR_ALL_COMPANIES(cc) {
    00078       if (cc != c && cc->colour == colour) return CMD_ERROR;
    00079     }
    00080   }
    00081
    00082   if (flags & DC_EXEC) {
    00083     switch (state) {
    00084       case 0:
    00085         c->livery[scheme].colour1 = colour;
    00086
    00087         /* If setting the first colour of the default scheme, adjust the
    00088          * original and cached company colours too. */
    00089         if (scheme == LS_DEFAULT) {
    00090           _company_colours[_current_company] = colour;
    00091           c->colour = colour;
    00092         }
    00093         break;
    00094
    00095       case 1:
    00096         c->livery[scheme].colour2 = colour;
    00097         break;
    00098
    00099       case 2:
    00100         c->livery[scheme].in_use = colour != 0;
    00101
    00102         /* Now handle setting the default scheme's in_use flag.
    00103          * This is different to the other schemes, as it signifies if any
    00104          * scheme is active at all. If this flag is not set, then no
    00105          * processing of vehicle types occurs at all, and only the default
    00106          * colours will be used. */
    00107
    00108         /* If enabling a scheme, set the default scheme to be in use too */
    00109         if (colour != 0) {
    00110           c->livery[LS_DEFAULT].in_use = true;
    00111           break;
    00112         }
    00113
    00114         /* Else loop through all schemes to see if any are left enabled.
    00115          * If not, disable the default scheme too. */
    00116         c->livery[LS_DEFAULT].in_use = false;
    00117         for (scheme = LS_DEFAULT; scheme < LS_END; scheme++) {
    00118           if (c->livery[scheme].in_use) {
    00119             c->livery[LS_DEFAULT].in_use = true;
    00120             break;
    00121           }
    00122         }
    00123         break;
    00124
    00125       default:
    00126         break;
    00127     }
    00128     ResetVehicleColourMap();
    00129     MarkWholeScreenDirty();
    00130
    00131     /* Company colour data is indirectly cached. */
    00132     Vehicle *v;
    00133     FOR_ALL_VEHICLES(v) {
    00134       if (v->owner == _current_company) v->InvalidateNewGRFCache();
    00135     }
    00136   }
    00137   return CommandCost();
    00138 }
    00139
    00150 CommandCost CmdIncreaseLoan(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
    00151 {
    00152   Company *c = Company::Get(_current_company);
    00153
    00154   if (c->current_loan >= _economy.max_loan) {
    00155     SetDParam(0, _economy.max_loan);
    00156     return_cmd_error(STR_ERROR_MAXIMUM_PERMITTED_LOAN);
    00157   }
    00158
    00159   Money loan;
    00160   switch (p2) {
    00161     default: return CMD_ERROR; // Invalid method
    00162     case 0: // Take some extra loan
    00163       loan = LOAN_INTERVAL;
    00164       break;
    00165     case 1: // Take a loan as big as possible
    00166       loan = _economy.max_loan - c->current_loan;
    00167       break;
    00168     case 2: // Take the given amount of loan
    00169       if ((((int32)p1 < LOAN_INTERVAL) || c->current_loan + (int32)p1 > _economy.max_loan || (p1 % LOAN_INTERVAL) != 0)) return CMD_ERROR;
    00170       loan = p1;
    00171       break;
    00172   }
    00173
    00174   /* Overflow protection */
    00175   if (c->money + c->current_loan + loan < c->money) return CMD_ERROR;
    00176
    00177   if (flags & DC_EXEC) {
    00178     c->money        += loan;
    00179     c->current_loan += loan;
    00180     InvalidateCompanyWindows(c);
    00181   }
    00182
    00183   return CommandCost(EXPENSES_OTHER);
    00184 }
    00185
    00196 CommandCost CmdDecreaseLoan(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
    00197 {
    00198   Company *c = Company::Get(_current_company);
    00199
    00200   if (c->current_loan == 0) return_cmd_error(STR_ERROR_LOAN_ALREADY_REPAYED);
    00201
    00202   Money loan;
    00203   switch (p2) {
    00204     default: return CMD_ERROR; // Invalid method
    00205     case 0: // Pay back one step
    00206       loan = min(c->current_loan, (Money)LOAN_INTERVAL);
    00207       break;
    00208     case 1: // Pay back as much as possible
    00209       loan = max(min(c->current_loan, c->money), (Money)LOAN_INTERVAL);
    00210       loan -= loan % LOAN_INTERVAL;
    00211       break;
    00212     case 2: // Repay the given amount of loan
    00213       if ((p1 % LOAN_INTERVAL != 0) || ((int32)p1 < LOAN_INTERVAL)) return CMD_ERROR; // Invalid amount to loan
    00214       loan = p1;
    00215       break;
    00216   }
    00217
    00218   if (c->money < loan) {
    00219     SetDParam(0, loan);
    00220     return_cmd_error(STR_ERROR_CURRENCY_REQUIRED);
    00221   }
    00222
    00223   if (flags & DC_EXEC) {
    00224     c->money        -= loan;
    00225     c->current_loan -= loan;
    00226     InvalidateCompanyWindows(c);
    00227   }
    00228   return CommandCost();
    00229 }
    00230
    00231 static bool IsUniqueCompanyName(const char *name)
    00232 {
    00233   const Company *c;
    00234
    00235   FOR_ALL_COMPANIES(c) {
    00236     if (c->name != NULL && strcmp(c->name, name) == 0) return false;
    00237   }
    00238
    00239   return true;
    00240 }
    00241
    00250 CommandCost CmdRenameCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
    00251 {
    00252   bool reset = StrEmpty(text);
    00253
    00254   if (!reset) {
    00255     if (strlen(text) >= MAX_LENGTH_COMPANY_NAME_BYTES) return CMD_ERROR;
    00256     if (!IsUniqueCompanyName(text)) return_cmd_error(STR_ERROR_NAME_MUST_BE_UNIQUE);
    00257   }
    00258
    00259   if (flags & DC_EXEC) {
    00260     Company *c = Company::Get(_current_company);
    00261     free(c->name);
    00262     c->name = reset ? NULL : strdup(text);
    00263     MarkWholeScreenDirty();
    00264   }
    00265
    00266   return CommandCost();
    00267 }
    00268
    00269 static bool IsUniquePresidentName(const char *name)
    00270 {
    00271   const Company *c;
    00272
    00273   FOR_ALL_COMPANIES(c) {
    00274     if (c->president_name != NULL && strcmp(c->president_name, name) == 0) return false;
    00275   }
    00276
    00277   return true;
    00278 }
    00279
    00288 CommandCost CmdRenamePresident(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
    00289 {
    00290   bool reset = StrEmpty(text);
    00291
    00292   if (!reset) {
    00293     if (strlen(text) >= MAX_LENGTH_PRESIDENT_NAME_BYTES) return CMD_ERROR;
    00294     if (!IsUniquePresidentName(text)) return_cmd_error(STR_ERROR_NAME_MUST_BE_UNIQUE);
    00295   }
    00296
    00297   if (flags & DC_EXEC) {
    00298     Company *c = Company::Get(_current_company);
    00299     free(c->president_name);
    00300
    00301     if (reset) {
    00302       c->president_name = NULL;
    00303     } else {
    00304       c->president_name = strdup(text);
    00305
    00306       if (c->name_1 == STR_SV_UNNAMED && c->name == NULL) {
    00307         char buf[80];
    00308
    00309         snprintf(buf, lengthof(buf), "%s Transport", text);
    00310         DoCommand(0, 0, 0, DC_EXEC, CMD_RENAME_COMPANY, buf);
    00311       }
    00312     }
    00313
    00314     MarkWholeScreenDirty();
    00315   }
    00316
    00317   return CommandCost();
    00318 }
    00319
    00326 static void AskUnsafeUnpauseCallback(Window *w, bool confirmed)
    00327 {
    00328   DoCommandP(0, PM_PAUSED_ERROR, confirmed ? 0 : 1, CMD_PAUSE);
    00329 }
    00330
    00343 CommandCost CmdPause(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
    00344 {
    00345   switch (p1) {
    00346     case PM_PAUSED_SAVELOAD:
    00347     case PM_PAUSED_ERROR:
    00348     case PM_PAUSED_NORMAL:
    00349       break;
    00350
    00351 #ifdef ENABLE_NETWORK
    00352     case PM_PAUSED_JOIN:
    00353     case PM_PAUSED_ACTIVE_CLIENTS:
    00354       if (!_networking) return CMD_ERROR;
    00355       break;
    00356 #endif /* ENABLE_NETWORK */
    00357
    00358     default: return CMD_ERROR;
    00359   }
    00360   if (flags & DC_EXEC) {
    00361     if (p1 == PM_PAUSED_NORMAL && _pause_mode & PM_PAUSED_ERROR) {
    00362       ShowQuery(
    00363         STR_NEWGRF_UNPAUSE_WARNING_TITLE,
    00364         STR_NEWGRF_UNPAUSE_WARNING,
    00365         NULL,
    00366         AskUnsafeUnpauseCallback
    00367       );
    00368     } else {
    00369 #ifdef ENABLE_NETWORK
    00370       PauseMode prev_mode = _pause_mode;
    00371 #endif /* ENABLE_NETWORK */
    00372
    00373       if (p2 == 0) {
    00374         _pause_mode = _pause_mode & ~p1;
    00375       } else {
    00376         _pause_mode = _pause_mode | p1;
    00377       }
    00378
    00379 #ifdef ENABLE_NETWORK
    00380       NetworkHandlePauseChange(prev_mode, (PauseMode)p1);
    00381 #endif /* ENABLE_NETWORK */
    00382     }
    00383
    00384     SetWindowDirty(WC_STATUS_BAR, 0);
    00385     SetWindowDirty(WC_MAIN_TOOLBAR, 0);
    00386   }
    00387   return CommandCost();
    00388 }
    00389
    00400 CommandCost CmdMoneyCheat(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
    00401 {
    00402 #ifndef _DEBUG
    00403   if (_networking) return CMD_ERROR;
    00404 #endif
    00405   return CommandCost(EXPENSES_OTHER, -(int32)p1);
    00406 }
    00407
    00419 CommandCost CmdGiveMoney(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
    00420 {
    00421   if (!_settings_game.economy.give_money) return CMD_ERROR;
    00422
    00423   const Company *c = Company::Get(_current_company);
    00424   CommandCost amount(EXPENSES_OTHER, min((Money)p1, (Money)20000000LL));
    00425
    00426   /* You can only transfer funds that is in excess of your loan */
    00427   if (c->money - c->current_loan < amount.GetCost() || amount.GetCost() <= 0) return CMD_ERROR;
    00428   if (!_networking || !Company::IsValidID((CompanyID)p2)) return CMD_ERROR;
    00429
    00430   if (flags & DC_EXEC) {
    00431     /* Add money to company */
    00432     CompanyID old_company = _current_company;
    00433     _current_company = (CompanyID)p2;
    00434     SubtractMoneyFromCompany(CommandCost(EXPENSES_OTHER, -amount.GetCost()));
    00435     _current_company = old_company;
    00436   }
    00437
    00438   /* Subtract money from local-company */
    00439   return amount;
    00440 }