command.cpp

Go to the documentation of this file.
00001 /* $Id: command.cpp 14465 2008-10-14 18:49:21Z rubidium $ */
00002 
00005 #include "stdafx.h"
00006 #include "openttd.h"
00007 #include "landscape.h"
00008 #include "tile_map.h"
00009 #include "gui.h"
00010 #include "command_func.h"
00011 #include "network/network.h"
00012 #include "variables.h"
00013 #include "genworld.h"
00014 #include "newgrf_storage.h"
00015 #include "strings_func.h"
00016 #include "gfx_func.h"
00017 #include "functions.h"
00018 #include "town.h"
00019 #include "date_func.h"
00020 #include "debug.h"
00021 #include "company_func.h"
00022 #include "company_base.h"
00023 #include "signal_func.h"
00024 
00025 #include "table/strings.h"
00026 
00027 const char *_cmd_text = NULL;
00028 StringID _error_message;
00029 
00039 #define DEF_COMMAND(yyyy) CommandCost yyyy(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
00040 
00041 DEF_COMMAND(CmdBuildRailroadTrack);
00042 DEF_COMMAND(CmdRemoveRailroadTrack);
00043 DEF_COMMAND(CmdBuildSingleRail);
00044 DEF_COMMAND(CmdRemoveSingleRail);
00045 
00046 DEF_COMMAND(CmdLandscapeClear);
00047 
00048 DEF_COMMAND(CmdBuildBridge);
00049 
00050 DEF_COMMAND(CmdBuildRailroadStation);
00051 DEF_COMMAND(CmdRemoveFromRailroadStation);
00052 DEF_COMMAND(CmdConvertRail);
00053 
00054 DEF_COMMAND(CmdBuildSingleSignal);
00055 DEF_COMMAND(CmdRemoveSingleSignal);
00056 
00057 DEF_COMMAND(CmdTerraformLand);
00058 
00059 DEF_COMMAND(CmdPurchaseLandArea);
00060 DEF_COMMAND(CmdSellLandArea);
00061 
00062 DEF_COMMAND(CmdBuildTunnel);
00063 
00064 DEF_COMMAND(CmdBuildTrainDepot);
00065 DEF_COMMAND(CmdBuildTrainWaypoint);
00066 DEF_COMMAND(CmdRenameWaypoint);
00067 DEF_COMMAND(CmdRemoveTrainWaypoint);
00068 
00069 DEF_COMMAND(CmdBuildRoadStop);
00070 DEF_COMMAND(CmdRemoveRoadStop);
00071 
00072 DEF_COMMAND(CmdBuildLongRoad);
00073 DEF_COMMAND(CmdRemoveLongRoad);
00074 DEF_COMMAND(CmdBuildRoad);
00075 DEF_COMMAND(CmdRemoveRoad);
00076 
00077 DEF_COMMAND(CmdBuildRoadDepot);
00078 
00079 DEF_COMMAND(CmdBuildAirport);
00080 
00081 DEF_COMMAND(CmdBuildDock);
00082 
00083 DEF_COMMAND(CmdBuildShipDepot);
00084 
00085 DEF_COMMAND(CmdBuildBuoy);
00086 
00087 DEF_COMMAND(CmdPlantTree);
00088 
00089 DEF_COMMAND(CmdBuildRailVehicle);
00090 DEF_COMMAND(CmdMoveRailVehicle);
00091 
00092 DEF_COMMAND(CmdSellRailWagon);
00093 
00094 DEF_COMMAND(CmdSendTrainToDepot);
00095 DEF_COMMAND(CmdForceTrainProceed);
00096 DEF_COMMAND(CmdReverseTrainDirection);
00097 
00098 DEF_COMMAND(CmdModifyOrder);
00099 DEF_COMMAND(CmdSkipToOrder);
00100 DEF_COMMAND(CmdDeleteOrder);
00101 DEF_COMMAND(CmdInsertOrder);
00102 DEF_COMMAND(CmdChangeServiceInt);
00103 DEF_COMMAND(CmdRestoreOrderIndex);
00104 
00105 DEF_COMMAND(CmdBuildIndustry);
00106 
00107 DEF_COMMAND(CmdBuildCompanyHQ);
00108 DEF_COMMAND(CmdSetCompanyManagerFace);
00109 DEF_COMMAND(CmdSetCompanyColor);
00110 
00111 DEF_COMMAND(CmdIncreaseLoan);
00112 DEF_COMMAND(CmdDecreaseLoan);
00113 
00114 DEF_COMMAND(CmdWantEnginePreview);
00115 
00116 DEF_COMMAND(CmdRenameVehicle);
00117 DEF_COMMAND(CmdRenameEngine);
00118 
00119 DEF_COMMAND(CmdRenameCompany);
00120 DEF_COMMAND(CmdRenamePresident);
00121 
00122 DEF_COMMAND(CmdRenameStation);
00123 
00124 DEF_COMMAND(CmdSellAircraft);
00125 DEF_COMMAND(CmdBuildAircraft);
00126 DEF_COMMAND(CmdSendAircraftToHangar);
00127 DEF_COMMAND(CmdRefitAircraft);
00128 
00129 DEF_COMMAND(CmdPlaceSign);
00130 DEF_COMMAND(CmdRenameSign);
00131 
00132 DEF_COMMAND(CmdBuildRoadVeh);
00133 DEF_COMMAND(CmdSellRoadVeh);
00134 DEF_COMMAND(CmdSendRoadVehToDepot);
00135 DEF_COMMAND(CmdTurnRoadVeh);
00136 DEF_COMMAND(CmdRefitRoadVeh);
00137 
00138 DEF_COMMAND(CmdPause);
00139 
00140 DEF_COMMAND(CmdBuyShareInCompany);
00141 DEF_COMMAND(CmdSellShareInCompany);
00142 DEF_COMMAND(CmdBuyCompany);
00143 
00144 DEF_COMMAND(CmdBuildTown);
00145 
00146 DEF_COMMAND(CmdRenameTown);
00147 DEF_COMMAND(CmdDoTownAction);
00148 
00149 DEF_COMMAND(CmdSetRoadDriveSide);
00150 
00151 DEF_COMMAND(CmdChangePatchSetting);
00152 
00153 DEF_COMMAND(CmdSellShip);
00154 DEF_COMMAND(CmdBuildShip);
00155 DEF_COMMAND(CmdSendShipToDepot);
00156 DEF_COMMAND(CmdRefitShip);
00157 
00158 DEF_COMMAND(CmdOrderRefit);
00159 DEF_COMMAND(CmdCloneOrder);
00160 
00161 DEF_COMMAND(CmdClearArea);
00162 
00163 DEF_COMMAND(CmdGiveMoney);
00164 DEF_COMMAND(CmdMoneyCheat);
00165 DEF_COMMAND(CmdBuildCanal);
00166 DEF_COMMAND(CmdBuildLock);
00167 
00168 DEF_COMMAND(CmdCompanyCtrl);
00169 
00170 DEF_COMMAND(CmdLevelLand);
00171 
00172 DEF_COMMAND(CmdRefitRailVehicle);
00173 
00174 DEF_COMMAND(CmdBuildSignalTrack);
00175 DEF_COMMAND(CmdRemoveSignalTrack);
00176 
00177 DEF_COMMAND(CmdSetAutoReplace);
00178 
00179 DEF_COMMAND(CmdCloneVehicle);
00180 DEF_COMMAND(CmdStartStopVehicle);
00181 DEF_COMMAND(CmdMassStartStopVehicle);
00182 DEF_COMMAND(CmdAutoreplaceVehicle);
00183 DEF_COMMAND(CmdDepotSellAllVehicles);
00184 DEF_COMMAND(CmdDepotMassAutoReplace);
00185 
00186 DEF_COMMAND(CmdCreateGroup);
00187 DEF_COMMAND(CmdRenameGroup);
00188 DEF_COMMAND(CmdDeleteGroup);
00189 DEF_COMMAND(CmdAddVehicleGroup);
00190 DEF_COMMAND(CmdAddSharedVehicleGroup);
00191 DEF_COMMAND(CmdRemoveAllVehiclesGroup);
00192 DEF_COMMAND(CmdSetGroupReplaceProtection);
00193 
00194 DEF_COMMAND(CmdMoveOrder);
00195 DEF_COMMAND(CmdChangeTimetable);
00196 DEF_COMMAND(CmdSetVehicleOnTime);
00197 DEF_COMMAND(CmdAutofillTimetable);
00198 #undef DEF_COMMAND
00199 
00207 static const Command _command_proc_table[] = {
00208   {CmdBuildRailroadTrack,           CMD_AUTO}, /* CMD_BUILD_RAILROAD_TRACK */
00209   {CmdRemoveRailroadTrack,          CMD_AUTO}, /* CMD_REMOVE_RAILROAD_TRACK */
00210   {CmdBuildSingleRail,              CMD_AUTO}, /* CMD_BUILD_SINGLE_RAIL */
00211   {CmdRemoveSingleRail,             CMD_AUTO}, /* CMD_REMOVE_SINGLE_RAIL */
00212   {CmdLandscapeClear,                      0}, /* CMD_LANDSCAPE_CLEAR */
00213   {CmdBuildBridge,                  CMD_AUTO}, /* CMD_BUILD_BRIDGE */
00214   {CmdBuildRailroadStation,         CMD_AUTO}, /* CMD_BUILD_RAILROAD_STATION */
00215   {CmdBuildTrainDepot,              CMD_AUTO}, /* CMD_BUILD_TRAIN_DEPOT */
00216   {CmdBuildSingleSignal,            CMD_AUTO}, /* CMD_BUILD_SIGNALS */
00217   {CmdRemoveSingleSignal,           CMD_AUTO}, /* CMD_REMOVE_SIGNALS */
00218   {CmdTerraformLand,                CMD_AUTO}, /* CMD_TERRAFORM_LAND */
00219   {CmdPurchaseLandArea,             CMD_AUTO}, /* CMD_PURCHASE_LAND_AREA */
00220   {CmdSellLandArea,                        0}, /* CMD_SELL_LAND_AREA */
00221   {CmdBuildTunnel,                  CMD_AUTO}, /* CMD_BUILD_TUNNEL */
00222   {CmdRemoveFromRailroadStation,           0}, /* CMD_REMOVE_FROM_RAILROAD_STATION */
00223   {CmdConvertRail,                         0}, /* CMD_CONVERT_RAILD */
00224   {CmdBuildTrainWaypoint,                  0}, /* CMD_BUILD_TRAIN_WAYPOINT */
00225   {CmdRenameWaypoint,                      0}, /* CMD_RENAME_WAYPOINT */
00226   {CmdRemoveTrainWaypoint,                 0}, /* CMD_REMOVE_TRAIN_WAYPOINT */
00227 
00228   {CmdBuildRoadStop,                CMD_AUTO}, /* CMD_BUILD_ROAD_STOP */
00229   {CmdRemoveRoadStop,                      0}, /* CMD_REMOVE_ROAD_STOP */
00230   {CmdBuildLongRoad,                CMD_AUTO}, /* CMD_BUILD_LONG_ROAD */
00231   {CmdRemoveLongRoad,               CMD_AUTO}, /* CMD_REMOVE_LONG_ROAD */
00232   {CmdBuildRoad,                           0}, /* CMD_BUILD_ROAD */
00233   {CmdRemoveRoad,                          0}, /* CMD_REMOVE_ROAD */
00234   {CmdBuildRoadDepot,               CMD_AUTO}, /* CMD_BUILD_ROAD_DEPOT */
00235 
00236   {CmdBuildAirport,                 CMD_AUTO}, /* CMD_BUILD_AIRPORT */
00237   {CmdBuildDock,                    CMD_AUTO}, /* CMD_BUILD_DOCK */
00238   {CmdBuildShipDepot,               CMD_AUTO}, /* CMD_BUILD_SHIP_DEPOT */
00239   {CmdBuildBuoy,                    CMD_AUTO}, /* CMD_BUILD_BUOY */
00240   {CmdPlantTree,                    CMD_AUTO}, /* CMD_PLANT_TREE */
00241   {CmdBuildRailVehicle,                    0}, /* CMD_BUILD_RAIL_VEHICLE */
00242   {CmdMoveRailVehicle,                     0}, /* CMD_MOVE_RAIL_VEHICLE */
00243 
00244   {CmdSellRailWagon,                       0}, /* CMD_SELL_RAIL_WAGON */
00245   {CmdSendTrainToDepot,                    0}, /* CMD_SEND_TRAIN_TO_DEPOT */
00246   {CmdForceTrainProceed,                   0}, /* CMD_FORCE_TRAIN_PROCEED */
00247   {CmdReverseTrainDirection,               0}, /* CMD_REVERSE_TRAIN_DIRECTION */
00248 
00249   {CmdModifyOrder,                         0}, /* CMD_MODIFY_ORDER */
00250   {CmdSkipToOrder,                         0}, /* CMD_SKIP_TO_ORDER */
00251   {CmdDeleteOrder,                         0}, /* CMD_DELETE_ORDER */
00252   {CmdInsertOrder,                         0}, /* CMD_INSERT_ORDER */
00253 
00254   {CmdChangeServiceInt,                    0}, /* CMD_CHANGE_SERVICE_INT */
00255 
00256   {CmdBuildIndustry,                       0}, /* CMD_BUILD_INDUSTRY */
00257   {CmdBuildCompanyHQ,               CMD_AUTO}, /* CMD_BUILD_COMPANY_HQ */
00258   {CmdSetCompanyManagerFace,               0}, /* CMD_SET_COMPANY_MANAGER_FACE */
00259   {CmdSetCompanyColor,                     0}, /* CMD_SET_COMPANY_COLOR */
00260 
00261   {CmdIncreaseLoan,                        0}, /* CMD_INCREASE_LOAN */
00262   {CmdDecreaseLoan,                        0}, /* CMD_DECREASE_LOAN */
00263 
00264   {CmdWantEnginePreview,                   0}, /* CMD_WANT_ENGINE_PREVIEW */
00265 
00266   {CmdRenameVehicle,                       0}, /* CMD_RENAME_VEHICLE */
00267   {CmdRenameEngine,                        0}, /* CMD_RENAME_ENGINE */
00268 
00269   {CmdRenameCompany,                       0}, /* CMD_RENAME_COMPANY */
00270   {CmdRenamePresident,                     0}, /* CMD_RENAME_PRESIDENT */
00271 
00272   {CmdRenameStation,                       0}, /* CMD_RENAME_STATION */
00273 
00274   {CmdSellAircraft,                        0}, /* CMD_SELL_AIRCRAFT */
00275 
00276   {CmdBuildAircraft,                       0}, /* CMD_BUILD_AIRCRAFT */
00277   {CmdSendAircraftToHangar,                0}, /* CMD_SEND_AIRCRAFT_TO_HANGAR */
00278   {CmdRefitAircraft,                       0}, /* CMD_REFIT_AIRCRAFT */
00279 
00280   {CmdPlaceSign,                           0}, /* CMD_PLACE_SIGN */
00281   {CmdRenameSign,                          0}, /* CMD_RENAME_SIGN */
00282 
00283   {CmdBuildRoadVeh,                        0}, /* CMD_BUILD_ROAD_VEH */
00284   {CmdSellRoadVeh,                         0}, /* CMD_SELL_ROAD_VEH */
00285   {CmdSendRoadVehToDepot,                  0}, /* CMD_SEND_ROADVEH_TO_DEPOT */
00286   {CmdTurnRoadVeh,                         0}, /* CMD_TURN_ROADVEH */
00287   {CmdRefitRoadVeh,                        0}, /* CMD_REFIT_ROAD_VEH */
00288 
00289   {CmdPause,                      CMD_SERVER}, /* CMD_PAUSE */
00290 
00291   {CmdBuyShareInCompany,                   0}, /* CMD_BUY_SHARE_IN_COMPANY */
00292   {CmdSellShareInCompany,                  0}, /* CMD_SELL_SHARE_IN_COMPANY */
00293   {CmdBuyCompany,                          0}, /* CMD_BUY_COMANY */
00294 
00295   {CmdBuildTown,                 CMD_OFFLINE}, /* CMD_BUILD_TOWN */
00296   {CmdRenameTown,                 CMD_SERVER}, /* CMD_RENAME_TOWN */
00297   {CmdDoTownAction,                        0}, /* CMD_DO_TOWN_ACTION */
00298 
00299   {CmdSetRoadDriveSide,           CMD_SERVER}, /* CMD_SET_ROAD_DRIVE_SIDE */
00300 
00301   {CmdSellShip,                            0}, /* CMD_SELL_SHIP */
00302   {CmdBuildShip,                           0}, /* CMD_BUILD_SHIP */
00303   {CmdSendShipToDepot,                     0}, /* CMD_SEND_SHIP_TO_DEPOT */
00304   {CmdRefitShip,                           0}, /* CMD_REFIT_SHIP */
00305 
00306   {CmdOrderRefit,                          0}, /* CMD_ORDER_REFIT */
00307   {CmdCloneOrder,                          0}, /* CMD_CLONE_ORDER */
00308 
00309   {CmdClearArea,                           0}, /* CMD_CLEAR_AREA */
00310 
00311   {CmdMoneyCheat,                CMD_OFFLINE}, /* CMD_MONEY_CHEAT */
00312   {CmdBuildCanal,                   CMD_AUTO}, /* CMD_BUILD_CANAL */
00313   {CmdCompanyCtrl,                         0}, /* CMD_COMPANY_CTRL */
00314 
00315   {CmdLevelLand,                    CMD_AUTO}, /* CMD_LEVEL_LAND */
00316 
00317   {CmdRefitRailVehicle,                    0}, /* CMD_REFIT_RAIL_VEHICLE */
00318   {CmdRestoreOrderIndex,                   0}, /* CMD_RESTORE_ORDER_INDEX */
00319   {CmdBuildLock,                    CMD_AUTO}, /* CMD_BUILD_LOCK */
00320 
00321   {CmdBuildSignalTrack,             CMD_AUTO}, /* CMD_BUILD_SIGNAL_TRACK */
00322   {CmdRemoveSignalTrack,            CMD_AUTO}, /* CMD_REMOVE_SIGNAL_TRACK */
00323 
00324   {CmdGiveMoney,                           0}, /* CMD_GIVE_MONEY */
00325   {CmdChangePatchSetting,         CMD_SERVER}, /* CMD_CHANGE_PATCH_SETTING */
00326   {CmdSetAutoReplace,                      0}, /* CMD_SET_AUTOREPLACE */
00327   {CmdCloneVehicle,                        0}, /* CMD_CLONE_VEHICLE */
00328   {CmdStartStopVehicle,                    0}, /* CMD_START_STOP_VEHICLE */
00329   {CmdMassStartStopVehicle,                0}, /* CMD_MASS_START_STOP */
00330   {CmdAutoreplaceVehicle,                  0}, /* CMD_AUTOREPLACE_VEHICLE */
00331   {CmdDepotSellAllVehicles,                0}, /* CMD_DEPOT_SELL_ALL_VEHICLES */
00332   {CmdDepotMassAutoReplace,                0}, /* CMD_DEPOT_MASS_AUTOREPLACE */
00333   {CmdCreateGroup,                         0}, /* CMD_CREATE_GROUP */
00334   {CmdDeleteGroup,                         0}, /* CMD_DELETE_GROUP */
00335   {CmdRenameGroup,                         0}, /* CMD_RENAME_GROUP */
00336   {CmdAddVehicleGroup,                     0}, /* CMD_ADD_VEHICLE_GROUP */
00337   {CmdAddSharedVehicleGroup,               0}, /* CMD_ADD_SHARE_VEHICLE_GROUP */
00338   {CmdRemoveAllVehiclesGroup,              0}, /* CMD_REMOVE_ALL_VEHICLES_GROUP */
00339   {CmdSetGroupReplaceProtection,           0}, /* CMD_SET_GROUP_REPLACE_PROTECTION */
00340   {CmdMoveOrder,                           0}, /* CMD_MOVE_ORDER */
00341   {CmdChangeTimetable,                     0}, /* CMD_CHANGE_TIMETABLE */
00342   {CmdSetVehicleOnTime,                    0}, /* CMD_SET_VEHICLE_ON_TIME */
00343   {CmdAutofillTimetable,                   0}, /* CMD_AUTOFILL_TIMETABLE */
00344 };
00345 
00352 bool IsValidCommand(uint32 cmd)
00353 {
00354   cmd &= 0xFF;
00355 
00356   return
00357     cmd < lengthof(_command_proc_table) &&
00358     _command_proc_table[cmd].proc != NULL;
00359 }
00360 
00368 byte GetCommandFlags(uint32 cmd)
00369 {
00370   assert(IsValidCommand(cmd));
00371 
00372   return _command_proc_table[cmd & 0xFF].flags;
00373 }
00374 
00375 static int _docommand_recursive = 0;
00376 
00388 CommandCost DoCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint32 procc)
00389 {
00390   CommandCost res;
00391 
00392   /* Do not even think about executing out-of-bounds tile-commands */
00393   if (!IsValidTile(tile)) {
00394     _cmd_text = NULL;
00395     return CMD_ERROR;
00396   }
00397 
00398   CommandProc *proc = _command_proc_table[procc].proc;
00399 
00400   if (_docommand_recursive == 0) _error_message = INVALID_STRING_ID;
00401 
00402   _docommand_recursive++;
00403 
00404   /* only execute the test call if it's toplevel, or we're not execing. */
00405   if (_docommand_recursive == 1 || !(flags & DC_EXEC) ) {
00406     SetTownRatingTestMode(true);
00407     res = proc(tile, flags & ~DC_EXEC, p1, p2);
00408     SetTownRatingTestMode(false);
00409     if (CmdFailed(res)) {
00410       res.SetGlobalErrorMessage();
00411       goto error;
00412     }
00413 
00414     if (_docommand_recursive == 1 &&
00415         !(flags & DC_QUERY_COST) &&
00416         !(flags & DC_BANKRUPT) &&
00417         res.GetCost() != 0 &&
00418         !CheckCompanyHasMoney(res)) {
00419       goto error;
00420     }
00421 
00422     if (!(flags & DC_EXEC)) {
00423       _docommand_recursive--;
00424       _cmd_text = NULL;
00425       return res;
00426     }
00427   }
00428 
00429   /* Execute the command here. All cost-relevant functions set the expenses type
00430    * themselves to the cost object at some point */
00431   res = proc(tile, flags, p1, p2);
00432   if (CmdFailed(res)) {
00433     res.SetGlobalErrorMessage();
00434 error:
00435     _docommand_recursive--;
00436     _cmd_text = NULL;
00437     return CMD_ERROR;
00438   }
00439 
00440   /* if toplevel, subtract the money. */
00441   if (--_docommand_recursive == 0 && !(flags & DC_BANKRUPT)) {
00442     SubtractMoneyFromCompany(res);
00443     /* XXX - Old AI hack which doesn't use DoCommandDP; update last build coord of company */
00444     if (tile != 0 && IsValidCompanyID(_current_company)) {
00445       GetCompany(_current_company)->last_build_coordinate = tile;
00446     }
00447   }
00448 
00449   _cmd_text = NULL;
00450   return res;
00451 }
00452 
00460 Money GetAvailableMoneyForCommand()
00461 {
00462   CompanyID company = _current_company;
00463   if (!IsValidCompanyID(company)) return INT64_MAX;
00464   return GetCompany(company)->money;
00465 }
00466 
00481 bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, CommandCallback *callback, uint32 cmd, bool my_cmd)
00482 {
00483   CommandCost res, res2;
00484   CommandProc *proc;
00485   uint32 flags;
00486   bool notest;
00487   StringID error_part1;
00488 
00489   int x = TileX(tile) * TILE_SIZE;
00490   int y = TileY(tile) * TILE_SIZE;
00491 
00492   /* Do not even think about executing out-of-bounds tile-commands */
00493   if (!IsValidTile(tile)) {
00494     _cmd_text = NULL;
00495     return false;
00496   }
00497 
00498   assert(_docommand_recursive == 0);
00499 
00500   _error_message = INVALID_STRING_ID;
00501   error_part1 = GB(cmd, 16, 16);
00502   _additional_cash_required = 0;
00503 
00506   if (_current_company == COMPANY_SPECTATOR && !_network_server) {
00507     if (my_cmd) ShowErrorMessage(_error_message, error_part1, x, y);
00508     _cmd_text = NULL;
00509     return false;
00510   }
00511 
00512   flags = 0;
00513   if (cmd & CMD_NO_WATER) flags |= DC_NO_WATER;
00514 
00515   /* get pointer to command handler */
00516   assert((cmd & 0xFF) < lengthof(_command_proc_table));
00517   proc = _command_proc_table[cmd & 0xFF].proc;
00518   if (proc == NULL) {
00519     _cmd_text = NULL;
00520     return false;
00521   }
00522 
00523   if (GetCommandFlags(cmd) & CMD_AUTO) flags |= DC_AUTO;
00524 
00525   /* Some commands have a different output in dryrun than the realrun
00526    *  e.g.: if you demolish a whole town, the dryrun would say okay.
00527    *  but by really destroying, your rating drops and at a certain point
00528    *  it will fail. so res and res2 are different
00529    * CMD_REMOVE_LONG_ROAD: This command has special local authority
00530    * restrictions which may cause the test run to fail (the previous
00531    * road fragments still stay there and the town won't let you
00532    * disconnect the road system), but the exec will succeed and this
00533    * fact will trigger an assertion failure. --pasky
00534    * CMD_CLONE_VEHICLE: Both building new vehicles and refitting them can be
00535    * influenced by newgrf callbacks, which makes it impossible to accurately
00536    * estimate the cost of cloning a vehicle. */
00537   notest =
00538     (cmd & 0xFF) == CMD_CLEAR_AREA ||
00539     (cmd & 0xFF) == CMD_LEVEL_LAND ||
00540     (cmd & 0xFF) == CMD_REMOVE_LONG_ROAD ||
00541     (cmd & 0xFF) == CMD_CLONE_VEHICLE;
00542 
00543   _docommand_recursive = 1;
00544 
00545   /* cost estimation only? */
00546   if (!IsGeneratingWorld() &&
00547       _shift_pressed &&
00548       IsLocalCompany() &&
00549       !(cmd & (CMD_NETWORK_COMMAND | CMD_SHOW_NO_ERROR)) &&
00550       (cmd & 0xFF) != CMD_PAUSE) {
00551     /* estimate the cost. */
00552     SetTownRatingTestMode(true);
00553     res = proc(tile, flags, p1, p2);
00554     SetTownRatingTestMode(false);
00555     if (CmdFailed(res)) {
00556       res.SetGlobalErrorMessage();
00557       ShowErrorMessage(_error_message, error_part1, x, y);
00558     } else {
00559       ShowEstimatedCostOrIncome(res.GetCost(), x, y);
00560     }
00561 
00562     _docommand_recursive = 0;
00563     _cmd_text = NULL;
00564     ClearStorageChanges(false);
00565     return false;
00566   }
00567 
00568 
00569   if (!((cmd & CMD_NO_TEST_IF_IN_NETWORK) && _networking)) {
00570     /* first test if the command can be executed. */
00571     SetTownRatingTestMode(true);
00572     res = proc(tile, flags, p1, p2);
00573     SetTownRatingTestMode(false);
00574     if (CmdFailed(res)) {
00575       res.SetGlobalErrorMessage();
00576       goto show_error;
00577     }
00578     /* no money? Only check if notest is off */
00579     if (!notest && res.GetCost() != 0 && !CheckCompanyHasMoney(res)) goto show_error;
00580   }
00581 
00582 #ifdef ENABLE_NETWORK
00583 
00590   if (_networking && !(cmd & CMD_NETWORK_COMMAND)) {
00591     CompanyID bck = _local_company;
00592     if (_network_dedicated || (_network_server && bck == COMPANY_SPECTATOR)) _local_company = COMPANY_FIRST;
00593     NetworkSend_Command(tile, p1, p2, cmd, callback);
00594     if (_network_dedicated || (_network_server && bck == COMPANY_SPECTATOR)) _local_company = bck;
00595     _docommand_recursive = 0;
00596     _cmd_text = NULL;
00597     ClearStorageChanges(false);
00598     return true;
00599   }
00600 #endif /* ENABLE_NETWORK */
00601   DebugDumpCommands("ddc:cmd:%d;%d;%d;%d;%d;%d;%d;%s\n", _date, _date_fract, (int)_current_company, tile, p1, p2, cmd, _cmd_text);
00602 
00603   /* update last build coordinate of company. */
00604   if (tile != 0 && IsValidCompanyID(_current_company)) {
00605     GetCompany(_current_company)->last_build_coordinate = tile;
00606   }
00607 
00608   /* Actually try and execute the command. If no cost-type is given
00609    * use the construction one */
00610   res2 = proc(tile, flags | DC_EXEC, p1, p2);
00611 
00612   /* If notest is on, it means the result of the test can be different than
00613    *  the real command.. so ignore the test */
00614   if (!notest && !((cmd & CMD_NO_TEST_IF_IN_NETWORK) && _networking)) {
00615     assert(res.GetCost() == res2.GetCost() && CmdFailed(res) == CmdFailed(res2)); // sanity check
00616   } else {
00617     if (CmdFailed(res2)) {
00618       res.SetGlobalErrorMessage();
00619       goto show_error;
00620     }
00621   }
00622 
00623   SubtractMoneyFromCompany(res2);
00624 
00625   /* update signals if needed */
00626   UpdateSignalsInBuffer();
00627 
00628   if (IsLocalCompany() && _game_mode != GM_EDITOR) {
00629     if (res2.GetCost() != 0 && tile != 0) ShowCostOrIncomeAnimation(x, y, GetSlopeZ(x, y), res2.GetCost());
00630     if (_additional_cash_required != 0) {
00631       SetDParam(0, _additional_cash_required);
00632       if (my_cmd) ShowErrorMessage(STR_0003_NOT_ENOUGH_CASH_REQUIRES, error_part1, x, y);
00633       if (res2.GetCost() == 0) goto callb_err;
00634     }
00635   }
00636 
00637   _docommand_recursive = 0;
00638 
00639   if (callback) callback(true, tile, p1, p2);
00640   _cmd_text = NULL;
00641   ClearStorageChanges(true);
00642   return true;
00643 
00644 show_error:
00645   /* show error message if the command fails? */
00646   if (IsLocalCompany() && error_part1 != 0 && my_cmd) {
00647     ShowErrorMessage(_error_message, error_part1, x, y);
00648   }
00649 
00650 callb_err:
00651   _docommand_recursive = 0;
00652 
00653   if (callback) callback(false, tile, p1, p2);
00654   _cmd_text = NULL;
00655   ClearStorageChanges(false);
00656   return false;
00657 }
00658 
00659 
00660 CommandCost CommandCost::AddCost(CommandCost ret)
00661 {
00662   this->AddCost(ret.cost);
00663   if (this->success && !ret.success) {
00664     this->message = ret.message;
00665     this->success = false;
00666   }
00667   return *this;
00668 }

Generated on Fri Nov 21 19:01:31 2008 for openttd by  doxygen 1.5.6