misc_cmd.cpp

Go to the documentation of this file.
00001 /* $Id: misc_cmd.cpp 14347 2008-09-16 20:29:09Z rubidium $ */
00002 
00005 #include "stdafx.h"
00006 #include "openttd.h"
00007 #include "command_func.h"
00008 #include "economy_func.h"
00009 #include "gui.h"
00010 #include "window_func.h"
00011 #include "textbuf_gui.h"
00012 #include "network/network.h"
00013 #include "variables.h"
00014 #include "livery.h"
00015 #include "player_face.h"
00016 #include "strings_func.h"
00017 #include "gfx_func.h"
00018 #include "functions.h"
00019 #include "vehicle_func.h"
00020 #include "string_func.h"
00021 #include "player_func.h"
00022 #include "player_base.h"
00023 #include "player_gui.h"
00024 #include "settings_type.h"
00025 
00026 #include "table/strings.h"
00027 
00034 CommandCost CmdSetPlayerFace(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
00035 {
00036   PlayerFace pf = (PlayerFace)p2;
00037 
00038   if (!IsValidPlayerFace(pf)) return CMD_ERROR;
00039 
00040   if (flags & DC_EXEC) {
00041     GetPlayer(_current_player)->face = pf;
00042     MarkWholeScreenDirty();
00043   }
00044   return CommandCost();
00045 }
00046 
00055 CommandCost CmdSetPlayerColor(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
00056 {
00057   Player *p, *pp;
00058   byte colour;
00059   LiveryScheme scheme = (LiveryScheme)GB(p1, 0, 8);
00060   byte state = GB(p1, 8, 2);
00061 
00062   if (p2 >= 16) return CMD_ERROR; // max 16 colours
00063   colour = p2;
00064 
00065   if (scheme >= LS_END || state >= 3) return CMD_ERROR;
00066 
00067   p = GetPlayer(_current_player);
00068 
00069   /* Ensure no two companies have the same primary colour */
00070   if (scheme == LS_DEFAULT && state == 0) {
00071     FOR_ALL_PLAYERS(pp) {
00072       if (pp->is_active && pp != p && pp->player_color == colour) return CMD_ERROR;
00073     }
00074   }
00075 
00076   if (flags & DC_EXEC) {
00077     switch (state) {
00078       case 0:
00079         p->livery[scheme].colour1 = colour;
00080 
00081         /* If setting the first colour of the default scheme, adjust the
00082          * original and cached player colours too. */
00083         if (scheme == LS_DEFAULT) {
00084           _player_colors[_current_player] = colour;
00085           p->player_color = colour;
00086         }
00087         break;
00088 
00089       case 1:
00090         p->livery[scheme].colour2 = colour;
00091         break;
00092 
00093       case 2:
00094         p->livery[scheme].in_use = colour != 0;
00095 
00096         /* Now handle setting the default scheme's in_use flag.
00097          * This is different to the other schemes, as it signifies if any
00098          * scheme is active at all. If this flag is not set, then no
00099          * processing of vehicle types occurs at all, and only the default
00100          * colours will be used. */
00101 
00102         /* If enabling a scheme, set the default scheme to be in use too */
00103         if (colour != 0) {
00104           p->livery[LS_DEFAULT].in_use = true;
00105           break;
00106         }
00107 
00108         /* Else loop through all schemes to see if any are left enabled.
00109          * If not, disable the default scheme too. */
00110         p->livery[LS_DEFAULT].in_use = false;
00111         for (scheme = LS_DEFAULT; scheme < LS_END; scheme++) {
00112           if (p->livery[scheme].in_use) {
00113             p->livery[LS_DEFAULT].in_use = true;
00114             break;
00115           }
00116         }
00117         break;
00118 
00119       default:
00120         break;
00121     }
00122     ResetVehicleColorMap();
00123     MarkWholeScreenDirty();
00124   }
00125   return CommandCost();
00126 }
00127 
00135 CommandCost CmdIncreaseLoan(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
00136 {
00137   Player *p = GetPlayer(_current_player);
00138 
00139   if (p->current_loan >= _economy.max_loan) {
00140     SetDParam(0, _economy.max_loan);
00141     return_cmd_error(STR_702B_MAXIMUM_PERMITTED_LOAN);
00142   }
00143 
00144   Money loan;
00145   switch (p2) {
00146     default: return CMD_ERROR; // Invalid method
00147     case 0: // Take some extra loan
00148       loan = (IsHumanPlayer(_current_player) || _patches.ainew_active) ? LOAN_INTERVAL : LOAN_INTERVAL_OLD_AI;
00149       break;
00150     case 1: // Take a loan as big as possible
00151       loan = _economy.max_loan - p->current_loan;
00152       break;
00153   }
00154 
00155   /* Overflow protection */
00156   if (p->player_money + p->current_loan + loan < p->player_money) return CMD_ERROR;
00157 
00158   if (flags & DC_EXEC) {
00159     p->player_money += loan;
00160     p->current_loan += loan;
00161     InvalidatePlayerWindows(p);
00162   }
00163 
00164   return CommandCost(EXPENSES_OTHER);
00165 }
00166 
00174 CommandCost CmdDecreaseLoan(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
00175 {
00176   Player *p = GetPlayer(_current_player);
00177 
00178   if (p->current_loan == 0) return_cmd_error(STR_702D_LOAN_ALREADY_REPAYED);
00179 
00180   Money loan;
00181   switch (p2) {
00182     default: return CMD_ERROR; // Invalid method
00183     case 0: // Pay back one step
00184       loan = min(p->current_loan, (Money)(IsHumanPlayer(_current_player) || _patches.ainew_active) ? LOAN_INTERVAL : LOAN_INTERVAL_OLD_AI);
00185       break;
00186     case 1: // Pay back as much as possible
00187       loan = max(min(p->current_loan, p->player_money), (Money)LOAN_INTERVAL);
00188       loan -= loan % LOAN_INTERVAL;
00189       break;
00190   }
00191 
00192   if (p->player_money < loan) {
00193     SetDParam(0, loan);
00194     return_cmd_error(STR_702E_REQUIRED);
00195   }
00196 
00197   if (flags & DC_EXEC) {
00198     p->player_money -= loan;
00199     p->current_loan -= loan;
00200     InvalidatePlayerWindows(p);
00201   }
00202   return CommandCost();
00203 }
00204 
00205 static bool IsUniqueCompanyName(const char *name)
00206 {
00207   const Player *p;
00208   char buf[512];
00209 
00210   FOR_ALL_PLAYERS(p) {
00211     if (!p->is_active) continue;
00212     SetDParam(0, p->index);
00213     GetString(buf, STR_COMPANY_NAME, lastof(buf));
00214     if (strcmp(buf, name) == 0) return false;
00215   }
00216 
00217   return true;
00218 }
00219 
00226 CommandCost CmdChangeCompanyName(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
00227 {
00228   if (StrEmpty(_cmd_text) || strlen(_cmd_text) > MAX_LENGTH_COMPANY_NAME) return CMD_ERROR;
00229 
00230   if (!IsUniqueCompanyName(_cmd_text)) return_cmd_error(STR_NAME_MUST_BE_UNIQUE);
00231 
00232   if (flags & DC_EXEC) {
00233     Player *p = GetPlayer(_current_player);
00234     free(p->name);
00235     p->name = strdup(_cmd_text);
00236     MarkWholeScreenDirty();
00237   }
00238 
00239   return CommandCost();
00240 }
00241 
00242 static bool IsUniquePresidentName(const char *name)
00243 {
00244   const Player *p;
00245   char buf[512];
00246 
00247   FOR_ALL_PLAYERS(p) {
00248     if (!p->is_active) continue;
00249     SetDParam(0, p->index);
00250     GetString(buf, STR_PLAYER_NAME, lastof(buf));
00251     if (strcmp(buf, name) == 0) return false;
00252   }
00253 
00254   return true;
00255 }
00256 
00263 CommandCost CmdChangePresidentName(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
00264 {
00265   if (StrEmpty(_cmd_text) || strlen(_cmd_text) > MAX_LENGTH_PRESIDENT_NAME) return CMD_ERROR;
00266 
00267   if (!IsUniquePresidentName(_cmd_text)) return_cmd_error(STR_NAME_MUST_BE_UNIQUE);
00268 
00269   if (flags & DC_EXEC) {
00270     Player *p = GetPlayer(_current_player);
00271     free(p->president_name);
00272     p->president_name = strdup(_cmd_text);
00273 
00274     if (p->name_1 == STR_SV_UNNAMED && p->name == NULL) {
00275       char buf[80];
00276 
00277       snprintf(buf, lengthof(buf), "%s Transport", _cmd_text);
00278       _cmd_text = buf;
00279       DoCommand(0, 0, 0, DC_EXEC, CMD_CHANGE_COMPANY_NAME);
00280     }
00281     MarkWholeScreenDirty();
00282   }
00283 
00284   return CommandCost();
00285 }
00286 
00293 static void AskUnsafeUnpauseCallback(Window *w, bool confirmed)
00294 {
00295   DoCommandP(0, confirmed ? 0 : 1, 0, NULL, CMD_PAUSE);
00296 }
00297 
00307 CommandCost CmdPause(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
00308 {
00309   if (flags & DC_EXEC) {
00310     _pause_game += (p1 == 0) ? -1 : 1;
00311 
00312     switch (_pause_game) {
00313       case -4:
00314       case -1:
00315         _pause_game = 0;
00316         break;
00317       case -3:
00318         ShowQuery(
00319           STR_NEWGRF_UNPAUSE_WARNING_TITLE,
00320           STR_NEWGRF_UNPAUSE_WARNING,
00321           NULL,
00322           AskUnsafeUnpauseCallback
00323         );
00324         break;
00325 
00326       default: break;
00327     }
00328 
00329     InvalidateWindow(WC_STATUS_BAR, 0);
00330     InvalidateWindow(WC_MAIN_TOOLBAR, 0);
00331   }
00332   return CommandCost();
00333 }
00334 
00343 CommandCost CmdMoneyCheat(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
00344 {
00345 #ifndef _DEBUG
00346   if (_networking) return CMD_ERROR;
00347 #endif
00348   return CommandCost(EXPENSES_OTHER, -(int32)p1);
00349 }
00350 
00360 CommandCost CmdGiveMoney(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
00361 {
00362   if (!_patches.give_money) return CMD_ERROR;
00363 
00364   const Player *p = GetPlayer(_current_player);
00365   CommandCost amount(EXPENSES_OTHER, min((Money)p1, (Money)20000000LL));
00366 
00367   /* You can only transfer funds that is in excess of your loan */
00368   if (p->player_money - p->current_loan < amount.GetCost() || amount.GetCost() <= 0) return CMD_ERROR;
00369   if (!_networking || !IsValidPlayer((PlayerID)p2)) return CMD_ERROR;
00370 
00371   if (flags & DC_EXEC) {
00372     /* Add money to player */
00373     PlayerID old_cp = _current_player;
00374     _current_player = (PlayerID)p2;
00375     SubtractMoneyFromPlayer(CommandCost(EXPENSES_OTHER, -amount.GetCost()));
00376     _current_player = old_cp;
00377   }
00378 
00379   /* Subtract money from local-player */
00380   return amount;
00381 }
00382 
00393 CommandCost CmdChangeDifficultyLevel(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
00394 {
00395   if (p1 != (uint32)-1L && ((int32)p1 >= GAME_DIFFICULTY_NUM || (int32)p1 < 0)) return CMD_ERROR;
00396 
00397   if (flags & DC_EXEC) {
00398     if (p1 != (uint32)-1L) {
00399       ((GDType*)&_opt_ptr->diff)[p1] = p2;
00400       _opt_ptr->diff_level = 3; // custom difficulty level
00401     } else {
00402       _opt_ptr->diff_level = p2;
00403     }
00404 
00405     /* If we are a network-client, update the difficult setting (if it is open).
00406      * Use this instead of just dirtying the window because we need to load in
00407      * the new difficulty settings */
00408     if (_networking && !_network_server && FindWindowById(WC_GAME_OPTIONS, 0) != NULL)
00409       ShowGameDifficulty();
00410   }
00411   return CommandCost();
00412 }

Generated on Wed Oct 1 17:03:21 2008 for openttd by  doxygen 1.5.6