00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #include "stdafx.h"
00013 #include "landscape.h"
00014 #include "error.h"
00015 #include "gui.h"
00016 #include "command_func.h"
00017 #include "network/network_type.h"
00018 #include "network/network.h"
00019 #include "genworld.h"
00020 #include "newgrf_storage.h"
00021 #include "strings_func.h"
00022 #include "gfx_func.h"
00023 #include "texteff.hpp"
00024 #include "town.h"
00025 #include "date_func.h"
00026 #include "company_func.h"
00027 #include "company_base.h"
00028 #include "signal_func.h"
00029 #include "core/backup_type.hpp"
00030 #include "object_base.h"
00031
00032 #include "table/strings.h"
00033
00034 CommandProc CmdBuildRailroadTrack;
00035 CommandProc CmdRemoveRailroadTrack;
00036 CommandProc CmdBuildSingleRail;
00037 CommandProc CmdRemoveSingleRail;
00038
00039 CommandProc CmdLandscapeClear;
00040
00041 CommandProc CmdBuildBridge;
00042
00043 CommandProc CmdBuildRailStation;
00044 CommandProc CmdRemoveFromRailStation;
00045 CommandProc CmdConvertRail;
00046
00047 CommandProc CmdBuildSingleSignal;
00048 CommandProc CmdRemoveSingleSignal;
00049
00050 CommandProc CmdTerraformLand;
00051
00052 CommandProc CmdBuildObject;
00053 CommandProc CmdSellLandArea;
00054
00055 CommandProc CmdBuildTunnel;
00056
00057 CommandProc CmdBuildTrainDepot;
00058 CommandProc CmdBuildRailWaypoint;
00059 CommandProc CmdRenameWaypoint;
00060 CommandProc CmdRemoveFromRailWaypoint;
00061
00062 CommandProc CmdBuildRoadStop;
00063 CommandProc CmdRemoveRoadStop;
00064
00065 CommandProc CmdBuildLongRoad;
00066 CommandProc CmdRemoveLongRoad;
00067 CommandProc CmdBuildRoad;
00068
00069 CommandProc CmdBuildRoadDepot;
00070
00071 CommandProc CmdBuildAirport;
00072
00073 CommandProc CmdBuildDock;
00074
00075 CommandProc CmdBuildShipDepot;
00076
00077 CommandProc CmdBuildBuoy;
00078
00079 CommandProc CmdPlantTree;
00080
00081 CommandProc CmdMoveRailVehicle;
00082
00083 CommandProc CmdBuildVehicle;
00084 CommandProc CmdSellVehicle;
00085 CommandProc CmdRefitVehicle;
00086 CommandProc CmdSendVehicleToDepot;
00087
00088 CommandProc CmdForceTrainProceed;
00089 CommandProc CmdReverseTrainDirection;
00090
00091 CommandProc CmdClearOrderBackup;
00092 CommandProc CmdModifyOrder;
00093 CommandProc CmdSkipToOrder;
00094 CommandProc CmdDeleteOrder;
00095 CommandProc CmdInsertOrder;
00096 CommandProc CmdChangeServiceInt;
00097
00098 CommandProc CmdBuildIndustry;
00099
00100 CommandProc CmdSetCompanyManagerFace;
00101 CommandProc CmdSetCompanyColour;
00102
00103 CommandProc CmdIncreaseLoan;
00104 CommandProc CmdDecreaseLoan;
00105
00106 CommandProc CmdWantEnginePreview;
00107
00108 CommandProc CmdRenameVehicle;
00109 CommandProc CmdRenameEngine;
00110
00111 CommandProc CmdRenameCompany;
00112 CommandProc CmdRenamePresident;
00113
00114 CommandProc CmdRenameStation;
00115 CommandProc CmdRenameDepot;
00116
00117 CommandProc CmdPlaceSign;
00118 CommandProc CmdRenameSign;
00119
00120 CommandProc CmdTurnRoadVeh;
00121
00122 CommandProc CmdPause;
00123
00124 CommandProc CmdBuyShareInCompany;
00125 CommandProc CmdSellShareInCompany;
00126 CommandProc CmdBuyCompany;
00127
00128 CommandProc CmdFoundTown;
00129 CommandProc CmdRenameTown;
00130 CommandProc CmdDoTownAction;
00131 CommandProc CmdTownGrowthRate;
00132 CommandProc CmdTownCargoGoal;
00133 CommandProc CmdTownSetText;
00134 CommandProc CmdExpandTown;
00135 CommandProc CmdDeleteTown;
00136
00137 CommandProc CmdChangeSetting;
00138 CommandProc CmdChangeCompanySetting;
00139
00140 CommandProc CmdOrderRefit;
00141 CommandProc CmdCloneOrder;
00142
00143 CommandProc CmdClearArea;
00144
00145 CommandProc CmdGiveMoney;
00146 CommandProc CmdMoneyCheat;
00147 CommandProc CmdBuildCanal;
00148 CommandProc CmdBuildLock;
00149
00150 CommandProc CmdCreateSubsidy;
00151 CommandProc CmdCompanyCtrl;
00152 CommandProc CmdCustomNewsItem;
00153 CommandProc CmdCreateGoal;
00154 CommandProc CmdRemoveGoal;
00155
00156 CommandProc CmdLevelLand;
00157
00158 CommandProc CmdBuildSignalTrack;
00159 CommandProc CmdRemoveSignalTrack;
00160
00161 CommandProc CmdSetAutoReplace;
00162
00163 CommandProc CmdCloneVehicle;
00164 CommandProc CmdStartStopVehicle;
00165 CommandProc CmdMassStartStopVehicle;
00166 CommandProc CmdAutoreplaceVehicle;
00167 CommandProc CmdDepotSellAllVehicles;
00168 CommandProc CmdDepotMassAutoReplace;
00169
00170 CommandProc CmdCreateGroup;
00171 CommandProc CmdRenameGroup;
00172 CommandProc CmdDeleteGroup;
00173 CommandProc CmdAddVehicleGroup;
00174 CommandProc CmdAddSharedVehicleGroup;
00175 CommandProc CmdRemoveAllVehiclesGroup;
00176 CommandProc CmdSetGroupReplaceProtection;
00177
00178 CommandProc CmdMoveOrder;
00179 CommandProc CmdChangeTimetable;
00180 CommandProc CmdSetVehicleOnTime;
00181 CommandProc CmdAutofillTimetable;
00182 CommandProc CmdSetTimetableStart;
00183
00184 #define DEF_CMD(proc, flags, type) {proc, #proc, (CommandFlags)flags, type}
00185
00193 static const Command _command_proc_table[] = {
00194 DEF_CMD(CmdBuildRailroadTrack, CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION),
00195 DEF_CMD(CmdRemoveRailroadTrack, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION),
00196 DEF_CMD(CmdBuildSingleRail, CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION),
00197 DEF_CMD(CmdRemoveSingleRail, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION),
00198 DEF_CMD(CmdLandscapeClear, 0, CMDT_LANDSCAPE_CONSTRUCTION),
00199 DEF_CMD(CmdBuildBridge, CMD_DEITY | CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION),
00200 DEF_CMD(CmdBuildRailStation, CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION),
00201 DEF_CMD(CmdBuildTrainDepot, CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION),
00202 DEF_CMD(CmdBuildSingleSignal, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION),
00203 DEF_CMD(CmdRemoveSingleSignal, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION),
00204 DEF_CMD(CmdTerraformLand, CMD_ALL_TILES | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION),
00205 DEF_CMD(CmdBuildObject, CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION),
00206 DEF_CMD(CmdBuildTunnel, CMD_DEITY | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION),
00207 DEF_CMD(CmdRemoveFromRailStation, 0, CMDT_LANDSCAPE_CONSTRUCTION),
00208 DEF_CMD(CmdConvertRail, 0, CMDT_LANDSCAPE_CONSTRUCTION),
00209 DEF_CMD(CmdBuildRailWaypoint, 0, CMDT_LANDSCAPE_CONSTRUCTION),
00210 DEF_CMD(CmdRenameWaypoint, CMD_STR_CTRL, CMDT_OTHER_MANAGEMENT ),
00211 DEF_CMD(CmdRemoveFromRailWaypoint, 0, CMDT_LANDSCAPE_CONSTRUCTION),
00212
00213 DEF_CMD(CmdBuildRoadStop, CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION),
00214 DEF_CMD(CmdRemoveRoadStop, 0, CMDT_LANDSCAPE_CONSTRUCTION),
00215 DEF_CMD(CmdBuildLongRoad,CMD_DEITY | CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION),
00216 DEF_CMD(CmdRemoveLongRoad, CMD_NO_TEST | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION),
00217 DEF_CMD(CmdBuildRoad, CMD_DEITY | CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION),
00218 DEF_CMD(CmdBuildRoadDepot, CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION),
00219
00220 DEF_CMD(CmdBuildAirport, CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION),
00221 DEF_CMD(CmdBuildDock, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION),
00222 DEF_CMD(CmdBuildShipDepot, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION),
00223 DEF_CMD(CmdBuildBuoy, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION),
00224 DEF_CMD(CmdPlantTree, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION),
00225
00226 DEF_CMD(CmdBuildVehicle, CMD_CLIENT_ID, CMDT_VEHICLE_CONSTRUCTION ),
00227 DEF_CMD(CmdSellVehicle, CMD_CLIENT_ID, CMDT_VEHICLE_CONSTRUCTION ),
00228 DEF_CMD(CmdRefitVehicle, 0, CMDT_VEHICLE_CONSTRUCTION ),
00229 DEF_CMD(CmdSendVehicleToDepot, 0, CMDT_VEHICLE_MANAGEMENT ),
00230
00231 DEF_CMD(CmdMoveRailVehicle, 0, CMDT_VEHICLE_CONSTRUCTION ),
00232 DEF_CMD(CmdForceTrainProceed, 0, CMDT_VEHICLE_MANAGEMENT ),
00233 DEF_CMD(CmdReverseTrainDirection, 0, CMDT_VEHICLE_MANAGEMENT ),
00234
00235 DEF_CMD(CmdClearOrderBackup, CMD_CLIENT_ID, CMDT_ROUTE_MANAGEMENT ),
00236 DEF_CMD(CmdModifyOrder, 0, CMDT_ROUTE_MANAGEMENT ),
00237 DEF_CMD(CmdSkipToOrder, 0, CMDT_ROUTE_MANAGEMENT ),
00238 DEF_CMD(CmdDeleteOrder, 0, CMDT_ROUTE_MANAGEMENT ),
00239 DEF_CMD(CmdInsertOrder, 0, CMDT_ROUTE_MANAGEMENT ),
00240
00241 DEF_CMD(CmdChangeServiceInt, 0, CMDT_VEHICLE_MANAGEMENT ),
00242
00243 DEF_CMD(CmdBuildIndustry, 0, CMDT_LANDSCAPE_CONSTRUCTION),
00244 DEF_CMD(CmdSetCompanyManagerFace, 0, CMDT_OTHER_MANAGEMENT ),
00245 DEF_CMD(CmdSetCompanyColour, 0, CMDT_OTHER_MANAGEMENT ),
00246
00247 DEF_CMD(CmdIncreaseLoan, 0, CMDT_MONEY_MANAGEMENT ),
00248 DEF_CMD(CmdDecreaseLoan, 0, CMDT_MONEY_MANAGEMENT ),
00249
00250 DEF_CMD(CmdWantEnginePreview, 0, CMDT_VEHICLE_MANAGEMENT ),
00251
00252 DEF_CMD(CmdRenameVehicle, CMD_STR_CTRL, CMDT_OTHER_MANAGEMENT ),
00253 DEF_CMD(CmdRenameEngine, CMD_STR_CTRL, CMDT_OTHER_MANAGEMENT ),
00254
00255 DEF_CMD(CmdRenameCompany, CMD_STR_CTRL, CMDT_OTHER_MANAGEMENT ),
00256 DEF_CMD(CmdRenamePresident, CMD_STR_CTRL, CMDT_OTHER_MANAGEMENT ),
00257
00258 DEF_CMD(CmdRenameStation, CMD_STR_CTRL, CMDT_OTHER_MANAGEMENT ),
00259 DEF_CMD(CmdRenameDepot, CMD_STR_CTRL, CMDT_OTHER_MANAGEMENT ),
00260
00261 DEF_CMD(CmdPlaceSign, CMD_STR_CTRL | CMD_DEITY, CMDT_OTHER_MANAGEMENT ),
00262 DEF_CMD(CmdRenameSign, CMD_STR_CTRL | CMD_DEITY, CMDT_OTHER_MANAGEMENT ),
00263
00264 DEF_CMD(CmdTurnRoadVeh, 0, CMDT_VEHICLE_MANAGEMENT ),
00265
00266 DEF_CMD(CmdPause, CMD_SERVER, CMDT_SERVER_SETTING ),
00267
00268 DEF_CMD(CmdBuyShareInCompany, 0, CMDT_MONEY_MANAGEMENT ),
00269 DEF_CMD(CmdSellShareInCompany, 0, CMDT_MONEY_MANAGEMENT ),
00270 DEF_CMD(CmdBuyCompany, 0, CMDT_MONEY_MANAGEMENT ),
00271
00272 DEF_CMD(CmdFoundTown, CMD_NO_TEST, CMDT_LANDSCAPE_CONSTRUCTION),
00273 DEF_CMD(CmdRenameTown, CMD_STR_CTRL | CMD_SERVER, CMDT_OTHER_MANAGEMENT ),
00274 DEF_CMD(CmdDoTownAction, 0, CMDT_LANDSCAPE_CONSTRUCTION),
00275 DEF_CMD(CmdTownCargoGoal, CMD_DEITY, CMDT_OTHER_MANAGEMENT ),
00276 DEF_CMD(CmdTownGrowthRate, CMD_DEITY, CMDT_OTHER_MANAGEMENT ),
00277 DEF_CMD(CmdTownSetText, CMD_STR_CTRL | CMD_DEITY, CMDT_OTHER_MANAGEMENT ),
00278 DEF_CMD(CmdExpandTown, CMD_DEITY, CMDT_LANDSCAPE_CONSTRUCTION),
00279 DEF_CMD(CmdDeleteTown, CMD_OFFLINE, CMDT_LANDSCAPE_CONSTRUCTION),
00280
00281 DEF_CMD(CmdOrderRefit, 0, CMDT_ROUTE_MANAGEMENT ),
00282 DEF_CMD(CmdCloneOrder, 0, CMDT_ROUTE_MANAGEMENT ),
00283
00284 DEF_CMD(CmdClearArea, CMD_NO_TEST, CMDT_LANDSCAPE_CONSTRUCTION),
00285
00286 DEF_CMD(CmdMoneyCheat, CMD_OFFLINE, CMDT_CHEAT ),
00287 DEF_CMD(CmdBuildCanal, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION),
00288 DEF_CMD(CmdCreateSubsidy, CMD_DEITY, CMDT_OTHER_MANAGEMENT ),
00289 DEF_CMD(CmdCompanyCtrl, CMD_SPECTATOR | CMD_CLIENT_ID, CMDT_SERVER_SETTING ),
00290 DEF_CMD(CmdCustomNewsItem, CMD_STR_CTRL | CMD_DEITY, CMDT_OTHER_MANAGEMENT ),
00291 DEF_CMD(CmdCreateGoal, CMD_STR_CTRL | CMD_DEITY, CMDT_OTHER_MANAGEMENT ),
00292 DEF_CMD(CmdRemoveGoal, CMD_DEITY, CMDT_OTHER_MANAGEMENT ),
00293
00294 DEF_CMD(CmdLevelLand, CMD_ALL_TILES | CMD_NO_TEST | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION),
00295
00296 DEF_CMD(CmdBuildLock, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION),
00297
00298 DEF_CMD(CmdBuildSignalTrack, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION),
00299 DEF_CMD(CmdRemoveSignalTrack, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION),
00300
00301 DEF_CMD(CmdGiveMoney, 0, CMDT_MONEY_MANAGEMENT ),
00302 DEF_CMD(CmdChangeSetting, CMD_SERVER, CMDT_SERVER_SETTING ),
00303 DEF_CMD(CmdChangeCompanySetting, 0, CMDT_COMPANY_SETTING ),
00304 DEF_CMD(CmdSetAutoReplace, 0, CMDT_VEHICLE_MANAGEMENT ),
00305 DEF_CMD(CmdCloneVehicle, CMD_NO_TEST, CMDT_VEHICLE_CONSTRUCTION ),
00306 DEF_CMD(CmdStartStopVehicle, 0, CMDT_VEHICLE_MANAGEMENT ),
00307 DEF_CMD(CmdMassStartStopVehicle, 0, CMDT_VEHICLE_MANAGEMENT ),
00308 DEF_CMD(CmdAutoreplaceVehicle, 0, CMDT_VEHICLE_MANAGEMENT ),
00309 DEF_CMD(CmdDepotSellAllVehicles, 0, CMDT_VEHICLE_CONSTRUCTION ),
00310 DEF_CMD(CmdDepotMassAutoReplace, 0, CMDT_VEHICLE_CONSTRUCTION ),
00311 DEF_CMD(CmdCreateGroup, 0, CMDT_ROUTE_MANAGEMENT ),
00312 DEF_CMD(CmdDeleteGroup, 0, CMDT_ROUTE_MANAGEMENT ),
00313 DEF_CMD(CmdRenameGroup, CMD_STR_CTRL, CMDT_OTHER_MANAGEMENT ),
00314 DEF_CMD(CmdAddVehicleGroup, 0, CMDT_ROUTE_MANAGEMENT ),
00315 DEF_CMD(CmdAddSharedVehicleGroup, 0, CMDT_ROUTE_MANAGEMENT ),
00316 DEF_CMD(CmdRemoveAllVehiclesGroup, 0, CMDT_ROUTE_MANAGEMENT ),
00317 DEF_CMD(CmdSetGroupReplaceProtection, 0, CMDT_ROUTE_MANAGEMENT ),
00318 DEF_CMD(CmdMoveOrder, 0, CMDT_ROUTE_MANAGEMENT ),
00319 DEF_CMD(CmdChangeTimetable, 0, CMDT_ROUTE_MANAGEMENT ),
00320 DEF_CMD(CmdSetVehicleOnTime, 0, CMDT_ROUTE_MANAGEMENT ),
00321 DEF_CMD(CmdAutofillTimetable, 0, CMDT_ROUTE_MANAGEMENT ),
00322 DEF_CMD(CmdSetTimetableStart, 0, CMDT_ROUTE_MANAGEMENT ),
00323 };
00324
00331 bool IsValidCommand(uint32 cmd)
00332 {
00333 cmd &= CMD_ID_MASK;
00334
00335 return cmd < lengthof(_command_proc_table) && _command_proc_table[cmd].proc != NULL;
00336 }
00337
00345 CommandFlags GetCommandFlags(uint32 cmd)
00346 {
00347 assert(IsValidCommand(cmd));
00348
00349 return _command_proc_table[cmd & CMD_ID_MASK].flags;
00350 }
00351
00359 const char *GetCommandName(uint32 cmd)
00360 {
00361 assert(IsValidCommand(cmd));
00362
00363 return _command_proc_table[cmd & CMD_ID_MASK].name;
00364 }
00365
00371 bool IsCommandAllowedWhilePaused(uint32 cmd)
00372 {
00373
00374 static const int command_type_lookup[] = {
00375 CMDPL_ALL_ACTIONS,
00376 CMDPL_NO_LANDSCAPING,
00377 CMDPL_NO_LANDSCAPING,
00378 CMDPL_NO_CONSTRUCTION,
00379 CMDPL_NO_CONSTRUCTION,
00380 CMDPL_NO_CONSTRUCTION,
00381 CMDPL_NO_CONSTRUCTION,
00382 CMDPL_NO_ACTIONS,
00383 CMDPL_NO_ACTIONS,
00384 };
00385 assert_compile(lengthof(command_type_lookup) == CMDT_END);
00386
00387 assert(IsValidCommand(cmd));
00388 return _game_mode == GM_EDITOR || command_type_lookup[_command_proc_table[cmd & CMD_ID_MASK].type] <= _settings_game.construction.command_pause_level;
00389 }
00390
00391
00392 static int _docommand_recursive = 0;
00393
00402 CommandCost DoCommand(const CommandContainer *container, DoCommandFlag flags)
00403 {
00404 return DoCommand(container->tile, container->p1, container->p2, flags, container->cmd & CMD_ID_MASK, container->text);
00405 }
00406
00420 CommandCost DoCommand(TileIndex tile, uint32 p1, uint32 p2, DoCommandFlag flags, uint32 cmd, const char *text)
00421 {
00422 CommandCost res;
00423
00424
00425 if (tile != 0 && (tile >= MapSize() || (!IsValidTile(tile) && (flags & DC_ALL_TILES) == 0))) return CMD_ERROR;
00426
00427
00428 CommandProc *proc = _command_proc_table[cmd & CMD_ID_MASK].proc;
00429
00430 _docommand_recursive++;
00431
00432
00433 if (_docommand_recursive == 1 || !(flags & DC_EXEC) ) {
00434 if (_docommand_recursive == 1) _cleared_object_areas.Clear();
00435 SetTownRatingTestMode(true);
00436 res = proc(tile, flags & ~DC_EXEC, p1, p2, text);
00437 SetTownRatingTestMode(false);
00438 if (res.Failed()) {
00439 goto error;
00440 }
00441
00442 if (_docommand_recursive == 1 &&
00443 !(flags & DC_QUERY_COST) &&
00444 !(flags & DC_BANKRUPT) &&
00445 !CheckCompanyHasMoney(res)) {
00446 goto error;
00447 }
00448
00449 if (!(flags & DC_EXEC)) {
00450 _docommand_recursive--;
00451 return res;
00452 }
00453 }
00454
00455
00456
00457 if (_docommand_recursive == 1) _cleared_object_areas.Clear();
00458 res = proc(tile, flags, p1, p2, text);
00459 if (res.Failed()) {
00460 error:
00461 _docommand_recursive--;
00462 return res;
00463 }
00464
00465
00466 if (--_docommand_recursive == 0 && !(flags & DC_BANKRUPT)) {
00467 SubtractMoneyFromCompany(res);
00468 }
00469
00470 return res;
00471 }
00472
00480 Money GetAvailableMoneyForCommand()
00481 {
00482 CompanyID company = _current_company;
00483 if (!Company::IsValidID(company)) return INT64_MAX;
00484 return Company::Get(company)->money;
00485 }
00486
00493 bool DoCommandP(const CommandContainer *container, bool my_cmd)
00494 {
00495 return DoCommandP(container->tile, container->p1, container->p2, container->cmd, container->callback, container->text, my_cmd);
00496 }
00497
00513 bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const char *text, bool my_cmd)
00514 {
00515
00516
00517
00518
00519
00520 bool estimate_only = _shift_pressed && IsLocalCompany() &&
00521 !_generating_world &&
00522 !(cmd & CMD_NETWORK_COMMAND) &&
00523 (cmd & CMD_ID_MASK) != CMD_PAUSE;
00524
00525
00526
00527 bool only_sending = _networking && !(cmd & CMD_NETWORK_COMMAND);
00528
00529
00530 int x = TileX(tile) * TILE_SIZE;
00531 int y = TileY(tile) * TILE_SIZE;
00532
00533 if (_pause_mode != PM_UNPAUSED && !IsCommandAllowedWhilePaused(cmd)) {
00534 ShowErrorMessage(GB(cmd, 16, 16), STR_ERROR_NOT_ALLOWED_WHILE_PAUSED, WL_INFO, x, y);
00535 return false;
00536 }
00537
00538 #ifdef ENABLE_NETWORK
00539
00540 if (!(cmd & CMD_NETWORK_COMMAND) && GetCommandFlags(cmd) & CMD_CLIENT_ID && p2 == 0) p2 = CLIENT_ID_SERVER;
00541 #endif
00542
00543 CommandCost res = DoCommandPInternal(tile, p1, p2, cmd, callback, text, my_cmd, estimate_only);
00544 if (res.Failed()) {
00545
00546 StringID error_part1 = GB(cmd, 16, 16);
00547 if (estimate_only || (IsLocalCompany() && error_part1 != 0 && my_cmd)) {
00548 ShowErrorMessage(error_part1, res.GetErrorMessage(), WL_INFO, x, y, res.GetTextRefStackSize(), res.GetTextRefStack());
00549 }
00550 } else if (estimate_only) {
00551 ShowEstimatedCostOrIncome(res.GetCost(), x, y);
00552 } else if (!only_sending && res.GetCost() != 0 && tile != 0 && IsLocalCompany() && _game_mode != GM_EDITOR) {
00553
00554
00555
00556
00557
00558 ShowCostOrIncomeAnimation(x, y, GetSlopePixelZ(x, y), res.GetCost());
00559 }
00560
00561 if (!estimate_only && !only_sending && callback != NULL) {
00562 callback(res, tile, p1, p2);
00563 }
00564
00565 return res.Succeeded();
00566 }
00567
00568
00574 #define return_dcpi(cmd, clear) { _docommand_recursive = 0; ClearStorageChanges(clear); return cmd; }
00575
00589 CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const char *text, bool my_cmd, bool estimate_only)
00590 {
00591
00592 assert(_docommand_recursive == 0);
00593 _docommand_recursive = 1;
00594
00595
00596 _additional_cash_required = 0;
00597
00598
00599 byte cmd_id = cmd & CMD_ID_MASK;
00600 assert(cmd_id < lengthof(_command_proc_table));
00601
00602 CommandProc *proc = _command_proc_table[cmd_id].proc;
00603
00604
00605 assert(proc != NULL);
00606
00607
00608 CommandFlags cmd_flags = GetCommandFlags(cmd);
00609
00610 DoCommandFlag flags = CommandFlagsToDCFlags(cmd_flags);
00611
00612 #ifdef ENABLE_NETWORK
00613
00614 assert(!(cmd_flags & CMD_CLIENT_ID) || p2 != 0);
00615 #endif
00616
00617
00618 if (tile != 0 && (tile >= MapSize() || (!IsValidTile(tile) && (cmd_flags & CMD_ALL_TILES) == 0))) return_dcpi(CMD_ERROR, false);
00619
00620
00621 bool exec_as_spectator = (cmd_flags & (CMD_SPECTATOR | CMD_SERVER)) != 0;
00622
00623
00624
00625
00626 if (_game_mode == GM_NORMAL && !exec_as_spectator && !Company::IsValidID(_current_company) && !(_current_company == OWNER_DEITY && (cmd_flags & CMD_DEITY) != 0)) {
00627 return_dcpi(CMD_ERROR, false);
00628 }
00629
00630 Backup<CompanyByte> cur_company(_current_company, FILE_LINE);
00631 if (exec_as_spectator) cur_company.Change(COMPANY_SPECTATOR);
00632
00633 bool test_and_exec_can_differ = (cmd_flags & CMD_NO_TEST) != 0;
00634 bool skip_test = _networking && (cmd & CMD_NO_TEST_IF_IN_NETWORK) != 0;
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646 CommandCost res;
00647 if (estimate_only || !skip_test) {
00648
00649 _cleared_object_areas.Clear();
00650 SetTownRatingTestMode(true);
00651 ClearStorageChanges(false);
00652 res = proc(tile, flags, p1, p2, text);
00653 SetTownRatingTestMode(false);
00654
00655
00656 assert(exec_as_spectator ? _current_company == COMPANY_SPECTATOR : cur_company.Verify());
00657
00658
00659
00660
00661
00662
00663 if (res.Failed() || estimate_only ||
00664 (!test_and_exec_can_differ && !CheckCompanyHasMoney(res))) {
00665 cur_company.Restore();
00666 return_dcpi(res, false);
00667 }
00668 }
00669
00670 #ifdef ENABLE_NETWORK
00671
00672
00673
00674
00675 if (_networking && !_generating_world && !(cmd & CMD_NETWORK_COMMAND)) {
00676 NetworkSendCommand(tile, p1, p2, cmd & ~CMD_FLAGS_MASK, callback, text, _current_company);
00677 cur_company.Restore();
00678
00679
00680
00681
00682
00683 return_dcpi(CommandCost(), false);
00684 }
00685 #endif
00686 DEBUG(desync, 1, "cmd: %08x; %02x; %02x; %06x; %08x; %08x; %08x; \"%s\" (%s)", _date, _date_fract, (int)_current_company, tile, p1, p2, cmd & ~CMD_NETWORK_COMMAND, text, GetCommandName(cmd));
00687
00688
00689
00690 _cleared_object_areas.Clear();
00691 ClearStorageChanges(false);
00692 CommandCost res2 = proc(tile, flags | DC_EXEC, p1, p2, text);
00693
00694 if (cmd_id == CMD_COMPANY_CTRL) {
00695 cur_company.Trash();
00696
00697
00698
00699 _current_company = _local_company;
00700 } else {
00701
00702 assert(exec_as_spectator ? _current_company == COMPANY_SPECTATOR : cur_company.Verify());
00703 cur_company.Restore();
00704 }
00705
00706
00707
00708
00709
00710 if (!test_and_exec_can_differ && !skip_test) {
00711 assert(res.GetCost() == res2.GetCost() && res.Failed() == res2.Failed());
00712 } else if (res2.Failed()) {
00713 return_dcpi(res2, false);
00714 }
00715
00716
00717
00718 if (_additional_cash_required != 0 && res2.GetCost() == 0) {
00719
00720
00721 UpdateSignalsInBuffer();
00722 SetDParam(0, _additional_cash_required);
00723 return_dcpi(CommandCost(STR_ERROR_NOT_ENOUGH_CASH_REQUIRES_CURRENCY), false);
00724 }
00725
00726
00727 if (tile != 0) {
00728 Company *c = Company::GetIfValid(_current_company);
00729 if (c != NULL) c->last_build_coordinate = tile;
00730 }
00731
00732 SubtractMoneyFromCompany(res2);
00733
00734
00735 UpdateSignalsInBuffer();
00736
00737 return_dcpi(res2, true);
00738 }
00739 #undef return_dcpi
00740
00741
00747 void CommandCost::AddCost(const CommandCost &ret)
00748 {
00749 this->AddCost(ret.cost);
00750 if (this->success && !ret.success) {
00751 this->message = ret.message;
00752 this->success = false;
00753 }
00754 }
00755
00761 uint32 CommandCost::textref_stack[16];
00762
00767 void CommandCost::UseTextRefStack(uint num_registers)
00768 {
00769 extern TemporaryStorageArray<int32, 0x110> _temp_store;
00770
00771 assert(num_registers < lengthof(textref_stack));
00772 this->textref_stack_size = num_registers;
00773 for (uint i = 0; i < num_registers; i++) {
00774 textref_stack[i] = _temp_store.GetValue(0x100 + i);
00775 }
00776 }