# misc_cmd.cpp

Go to the documentation of this file.

    00001 /* $Id: misc_cmd.cpp 16482 2009-05-31 12:22:53Z rubidium $ */
    00002
    00005 #include "stdafx.h"
    00006 #include "openttd.h"
    00007 #include "command_func.h"
    00008 #include "economy_func.h"
    00009 #include "window_func.h"
    00010 #include "textbuf_gui.h"
    00011 #include "network/network.h"
    00012 #include "company_manager_face.h"
    00013 #include "strings_func.h"
    00014 #include "gfx_func.h"
    00015 #include "functions.h"
    00016 #include "vehicle_func.h"
    00017 #include "string_func.h"
    00018 #include "company_func.h"
    00019 #include "company_gui.h"
    00020 #include "settings_type.h"
    00021 #include "vehicle_base.h"
    00022
    00023 #include "table/strings.h"
    00024
    00031 CommandCost CmdSetCompanyManagerFace(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
    00032 {
    00033   CompanyManagerFace cmf = (CompanyManagerFace)p2;
    00034
    00035   if (!IsValidCompanyManagerFace(cmf)) return CMD_ERROR;
    00036
    00037   if (flags & DC_EXEC) {
    00038     GetCompany(_current_company)->face = cmf;
    00039     MarkWholeScreenDirty();
    00040   }
    00041   return CommandCost();
    00042 }
    00043
    00052 CommandCost CmdSetCompanyColour(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
    00053 {
    00054   if (p2 >= 16) return CMD_ERROR; // max 16 colours
    00055
    00056   Colours colour = (Colours)p2;
    00057
    00058   LiveryScheme scheme = (LiveryScheme)GB(p1, 0, 8);
    00059   byte state = GB(p1, 8, 2);
    00060
    00061   if (scheme >= LS_END || state >= 3) return CMD_ERROR;
    00062
    00063   Company *c = GetCompany(_current_company);
    00064
    00065   /* Ensure no two companies have the same primary colour */
    00066   if (scheme == LS_DEFAULT && state == 0) {
    00067     const Company *cc;
    00068     FOR_ALL_COMPANIES(cc) {
    00069       if (cc != c && cc->colour == colour) return CMD_ERROR;
    00070     }
    00071   }
    00072
    00073   if (flags & DC_EXEC) {
    00074     switch (state) {
    00075       case 0:
    00076         c->livery[scheme].colour1 = colour;
    00077
    00078         /* If setting the first colour of the default scheme, adjust the
    00079          * original and cached company colours too. */
    00080         if (scheme == LS_DEFAULT) {
    00081           _company_colours[_current_company] = colour;
    00082           c->colour = colour;
    00083         }
    00084         break;
    00085
    00086       case 1:
    00087         c->livery[scheme].colour2 = colour;
    00088         break;
    00089
    00090       case 2:
    00091         c->livery[scheme].in_use = colour != 0;
    00092
    00093         /* Now handle setting the default scheme's in_use flag.
    00094          * This is different to the other schemes, as it signifies if any
    00095          * scheme is active at all. If this flag is not set, then no
    00096          * processing of vehicle types occurs at all, and only the default
    00097          * colours will be used. */
    00098
    00099         /* If enabling a scheme, set the default scheme to be in use too */
    00100         if (colour != 0) {
    00101           c->livery[LS_DEFAULT].in_use = true;
    00102           break;
    00103         }
    00104
    00105         /* Else loop through all schemes to see if any are left enabled.
    00106          * If not, disable the default scheme too. */
    00107         c->livery[LS_DEFAULT].in_use = false;
    00108         for (scheme = LS_DEFAULT; scheme < LS_END; scheme++) {
    00109           if (c->livery[scheme].in_use) {
    00110             c->livery[LS_DEFAULT].in_use = true;
    00111             break;
    00112           }
    00113         }
    00114         break;
    00115
    00116       default:
    00117         break;
    00118     }
    00119     ResetVehicleColourMap();
    00120     MarkWholeScreenDirty();
    00121
    00122     /* Company colour data is indirectly cached. */
    00123     Vehicle *v;
    00124     FOR_ALL_VEHICLES(v) {
    00125       if (v->owner == _current_company) v->InvalidateNewGRFCache();
    00126     }
    00127   }
    00128   return CommandCost();
    00129 }
    00130
    00139 CommandCost CmdIncreaseLoan(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
    00140 {
    00141   Company *c = GetCompany(_current_company);
    00142
    00143   if (c->current_loan >= _economy.max_loan) {
    00144     SetDParam(0, _economy.max_loan);
    00145     return_cmd_error(STR_702B_MAXIMUM_PERMITTED_LOAN);
    00146   }
    00147
    00148   Money loan;
    00149   switch (p2) {
    00150     default: return CMD_ERROR; // Invalid method
    00151     case 0: // Take some extra loan
    00152       loan = LOAN_INTERVAL;
    00153       break;
    00154     case 1: // Take a loan as big as possible
    00155       loan = _economy.max_loan - c->current_loan;
    00156       break;
    00157     case 2: // Take the given amount of loan
    00158       if ((((int32)p1 < LOAN_INTERVAL) || c->current_loan + (int32)p1 > _economy.max_loan || (p1 % LOAN_INTERVAL) != 0)) return CMD_ERROR;
    00159       loan = p1;
    00160       break;
    00161   }
    00162
    00163   /* Overflow protection */
    00164   if (c->money + c->current_loan + loan < c->money) return CMD_ERROR;
    00165
    00166   if (flags & DC_EXEC) {
    00167     c->money        += loan;
    00168     c->current_loan += loan;
    00169     InvalidateCompanyWindows(c);
    00170   }
    00171
    00172   return CommandCost(EXPENSES_OTHER);
    00173 }
    00174
    00183 CommandCost CmdDecreaseLoan(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
    00184 {
    00185   Company *c = GetCompany(_current_company);
    00186
    00187   if (c->current_loan == 0) return_cmd_error(STR_702D_LOAN_ALREADY_REPAYED);
    00188
    00189   Money loan;
    00190   switch (p2) {
    00191     default: return CMD_ERROR; // Invalid method
    00192     case 0: // Pay back one step
    00193       loan = min(c->current_loan, (Money)LOAN_INTERVAL);
    00194       break;
    00195     case 1: // Pay back as much as possible
    00196       loan = max(min(c->current_loan, c->money), (Money)LOAN_INTERVAL);
    00197       loan -= loan % LOAN_INTERVAL;
    00198       break;
    00199     case 2: // Repay the given amount of loan
    00200       if ((p1 % LOAN_INTERVAL != 0) || ((int32)p1 < LOAN_INTERVAL)) return CMD_ERROR; // Invalid amount to loan
    00201       loan = p1;
    00202       break;
    00203   }
    00204
    00205   if (c->money < loan) {
    00206     SetDParam(0, loan);
    00207     return_cmd_error(STR_702E_REQUIRED);
    00208   }
    00209
    00210   if (flags & DC_EXEC) {
    00211     c->money        -= loan;
    00212     c->current_loan -= loan;
    00213     InvalidateCompanyWindows(c);
    00214   }
    00215   return CommandCost();
    00216 }
    00217
    00218 static bool IsUniqueCompanyName(const char *name)
    00219 {
    00220   const Company *c;
    00221
    00222   FOR_ALL_COMPANIES(c) {
    00223     if (c->name != NULL && strcmp(c->name, name) == 0) return false;
    00224   }
    00225
    00226   return true;
    00227 }
    00228
    00235 CommandCost CmdRenameCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
    00236 {
    00237   bool reset = StrEmpty(text);
    00238
    00239   if (!reset) {
    00240     if (strlen(text) >= MAX_LENGTH_COMPANY_NAME_BYTES) return CMD_ERROR;
    00241     if (!IsUniqueCompanyName(text)) return_cmd_error(STR_NAME_MUST_BE_UNIQUE);
    00242   }
    00243
    00244   if (flags & DC_EXEC) {
    00245     Company *c = GetCompany(_current_company);
    00246     free(c->name);
    00247     c->name = reset ? NULL : strdup(text);
    00248     MarkWholeScreenDirty();
    00249   }
    00250
    00251   return CommandCost();
    00252 }
    00253
    00254 static bool IsUniquePresidentName(const char *name)
    00255 {
    00256   const Company *c;
    00257
    00258   FOR_ALL_COMPANIES(c) {
    00259     if (c->president_name != NULL && strcmp(c->president_name, name) == 0) return false;
    00260   }
    00261
    00262   return true;
    00263 }
    00264
    00271 CommandCost CmdRenamePresident(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
    00272 {
    00273   bool reset = StrEmpty(text);
    00274
    00275   if (!reset) {
    00276     if (strlen(text) >= MAX_LENGTH_PRESIDENT_NAME_BYTES) return CMD_ERROR;
    00277     if (!IsUniquePresidentName(text)) return_cmd_error(STR_NAME_MUST_BE_UNIQUE);
    00278   }
    00279
    00280   if (flags & DC_EXEC) {
    00281     Company *c = GetCompany(_current_company);
    00282     free(c->president_name);
    00283
    00284     if (reset) {
    00285       c->president_name = NULL;
    00286     } else {
    00287       c->president_name = strdup(text);
    00288
    00289       if (c->name_1 == STR_SV_UNNAMED && c->name == NULL) {
    00290         char buf[80];
    00291
    00292         snprintf(buf, lengthof(buf), "%s Transport", text);
    00293         DoCommand(0, 0, 0, DC_EXEC, CMD_RENAME_COMPANY, buf);
    00294       }
    00295     }
    00296
    00297     MarkWholeScreenDirty();
    00298   }
    00299
    00300   return CommandCost();
    00301 }
    00302
    00309 static void AskUnsafeUnpauseCallback(Window *w, bool confirmed)
    00310 {
    00311   DoCommandP(0, confirmed ? 0 : 1, 0, CMD_PAUSE);
    00312 }
    00313
    00323 CommandCost CmdPause(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
    00324 {
    00325   if (flags & DC_EXEC) {
    00326     _pause_game += (p1 == 0) ? -1 : 1;
    00327
    00328     switch (_pause_game) {
    00329       case -4:
    00330       case -1:
    00331         _pause_game = 0;
    00332         break;
    00333       case -3:
    00334         ShowQuery(
    00335           STR_NEWGRF_UNPAUSE_WARNING_TITLE,
    00336           STR_NEWGRF_UNPAUSE_WARNING,
    00337           NULL,
    00338           AskUnsafeUnpauseCallback
    00339         );
    00340         break;
    00341
    00342       default: break;
    00343     }
    00344
    00345     InvalidateWindow(WC_STATUS_BAR, 0);
    00346     InvalidateWindow(WC_MAIN_TOOLBAR, 0);
    00347   }
    00348   return CommandCost();
    00349 }
    00350
    00359 CommandCost CmdMoneyCheat(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
    00360 {
    00361 #ifndef _DEBUG
    00362   if (_networking) return CMD_ERROR;
    00363 #endif
    00364   return CommandCost(EXPENSES_OTHER, -(int32)p1);
    00365 }
    00366
    00376 CommandCost CmdGiveMoney(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
    00377 {
    00378   if (!_settings_game.economy.give_money) return CMD_ERROR;
    00379
    00380   const Company *c = GetCompany(_current_company);
    00381   CommandCost amount(EXPENSES_OTHER, min((Money)p1, (Money)20000000LL));
    00382
    00383   /* You can only transfer funds that is in excess of your loan */
    00384   if (c->money - c->current_loan < amount.GetCost() || amount.GetCost() <= 0) return CMD_ERROR;
    00385   if (!_networking || !IsValidCompanyID((CompanyID)p2)) return CMD_ERROR;
    00386
    00387   if (flags & DC_EXEC) {
    00388     /* Add money to company */
    00389     CompanyID old_company = _current_company;
    00390     _current_company = (CompanyID)p2;
    00391     SubtractMoneyFromCompany(CommandCost(EXPENSES_OTHER, -amount.GetCost()));
    00392     _current_company = old_company;
    00393   }
    00394
    00395   /* Subtract money from local-company */
    00396   return amount;
    00397 }