# misc_cmd.cpp

Go to the documentation of this file.

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