00001
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},
00209 {CmdRemoveRailroadTrack, CMD_AUTO},
00210 {CmdBuildSingleRail, CMD_AUTO},
00211 {CmdRemoveSingleRail, CMD_AUTO},
00212 {CmdLandscapeClear, 0},
00213 {CmdBuildBridge, CMD_AUTO},
00214 {CmdBuildRailroadStation, CMD_AUTO},
00215 {CmdBuildTrainDepot, CMD_AUTO},
00216 {CmdBuildSingleSignal, CMD_AUTO},
00217 {CmdRemoveSingleSignal, CMD_AUTO},
00218 {CmdTerraformLand, CMD_AUTO},
00219 {CmdPurchaseLandArea, CMD_AUTO},
00220 {CmdSellLandArea, 0},
00221 {CmdBuildTunnel, CMD_AUTO},
00222 {CmdRemoveFromRailroadStation, 0},
00223 {CmdConvertRail, 0},
00224 {CmdBuildTrainWaypoint, 0},
00225 {CmdRenameWaypoint, 0},
00226 {CmdRemoveTrainWaypoint, 0},
00227
00228 {CmdBuildRoadStop, CMD_AUTO},
00229 {CmdRemoveRoadStop, 0},
00230 {CmdBuildLongRoad, CMD_AUTO},
00231 {CmdRemoveLongRoad, CMD_AUTO},
00232 {CmdBuildRoad, 0},
00233 {CmdRemoveRoad, 0},
00234 {CmdBuildRoadDepot, CMD_AUTO},
00235
00236 {CmdBuildAirport, CMD_AUTO},
00237 {CmdBuildDock, CMD_AUTO},
00238 {CmdBuildShipDepot, CMD_AUTO},
00239 {CmdBuildBuoy, CMD_AUTO},
00240 {CmdPlantTree, CMD_AUTO},
00241 {CmdBuildRailVehicle, 0},
00242 {CmdMoveRailVehicle, 0},
00243
00244 {CmdSellRailWagon, 0},
00245 {CmdSendTrainToDepot, 0},
00246 {CmdForceTrainProceed, 0},
00247 {CmdReverseTrainDirection, 0},
00248
00249 {CmdModifyOrder, 0},
00250 {CmdSkipToOrder, 0},
00251 {CmdDeleteOrder, 0},
00252 {CmdInsertOrder, 0},
00253
00254 {CmdChangeServiceInt, 0},
00255
00256 {CmdBuildIndustry, 0},
00257 {CmdBuildCompanyHQ, CMD_AUTO},
00258 {CmdSetCompanyManagerFace, 0},
00259 {CmdSetCompanyColor, 0},
00260
00261 {CmdIncreaseLoan, 0},
00262 {CmdDecreaseLoan, 0},
00263
00264 {CmdWantEnginePreview, 0},
00265
00266 {CmdRenameVehicle, 0},
00267 {CmdRenameEngine, 0},
00268
00269 {CmdRenameCompany, 0},
00270 {CmdRenamePresident, 0},
00271
00272 {CmdRenameStation, 0},
00273
00274 {CmdSellAircraft, 0},
00275
00276 {CmdBuildAircraft, 0},
00277 {CmdSendAircraftToHangar, 0},
00278 {CmdRefitAircraft, 0},
00279
00280 {CmdPlaceSign, 0},
00281 {CmdRenameSign, 0},
00282
00283 {CmdBuildRoadVeh, 0},
00284 {CmdSellRoadVeh, 0},
00285 {CmdSendRoadVehToDepot, 0},
00286 {CmdTurnRoadVeh, 0},
00287 {CmdRefitRoadVeh, 0},
00288
00289 {CmdPause, CMD_SERVER},
00290
00291 {CmdBuyShareInCompany, 0},
00292 {CmdSellShareInCompany, 0},
00293 {CmdBuyCompany, 0},
00294
00295 {CmdBuildTown, CMD_OFFLINE},
00296 {CmdRenameTown, CMD_SERVER},
00297 {CmdDoTownAction, 0},
00298
00299 {CmdSetRoadDriveSide, CMD_SERVER},
00300
00301 {CmdSellShip, 0},
00302 {CmdBuildShip, 0},
00303 {CmdSendShipToDepot, 0},
00304 {CmdRefitShip, 0},
00305
00306 {CmdOrderRefit, 0},
00307 {CmdCloneOrder, 0},
00308
00309 {CmdClearArea, 0},
00310
00311 {CmdMoneyCheat, CMD_OFFLINE},
00312 {CmdBuildCanal, CMD_AUTO},
00313 {CmdCompanyCtrl, 0},
00314
00315 {CmdLevelLand, CMD_AUTO},
00316
00317 {CmdRefitRailVehicle, 0},
00318 {CmdRestoreOrderIndex, 0},
00319 {CmdBuildLock, CMD_AUTO},
00320
00321 {CmdBuildSignalTrack, CMD_AUTO},
00322 {CmdRemoveSignalTrack, CMD_AUTO},
00323
00324 {CmdGiveMoney, 0},
00325 {CmdChangePatchSetting, CMD_SERVER},
00326 {CmdSetAutoReplace, 0},
00327 {CmdCloneVehicle, 0},
00328 {CmdStartStopVehicle, 0},
00329 {CmdMassStartStopVehicle, 0},
00330 {CmdAutoreplaceVehicle, 0},
00331 {CmdDepotSellAllVehicles, 0},
00332 {CmdDepotMassAutoReplace, 0},
00333 {CmdCreateGroup, 0},
00334 {CmdDeleteGroup, 0},
00335 {CmdRenameGroup, 0},
00336 {CmdAddVehicleGroup, 0},
00337 {CmdAddSharedVehicleGroup, 0},
00338 {CmdRemoveAllVehiclesGroup, 0},
00339 {CmdSetGroupReplaceProtection, 0},
00340 {CmdMoveOrder, 0},
00341 {CmdChangeTimetable, 0},
00342 {CmdSetVehicleOnTime, 0},
00343 {CmdAutofillTimetable, 0},
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
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
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
00430
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
00441 if (--_docommand_recursive == 0 && !(flags & DC_BANKRUPT)) {
00442 SubtractMoneyFromCompany(res);
00443
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
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
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
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
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
00546 if (!IsGeneratingWorld() &&
00547 _shift_pressed &&
00548 IsLocalCompany() &&
00549 !(cmd & (CMD_NETWORK_COMMAND | CMD_SHOW_NO_ERROR)) &&
00550 (cmd & 0xFF) != CMD_PAUSE) {
00551
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
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
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
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
00604 if (tile != 0 && IsValidCompanyID(_current_company)) {
00605 GetCompany(_current_company)->last_build_coordinate = tile;
00606 }
00607
00608
00609
00610 res2 = proc(tile, flags | DC_EXEC, p1, p2);
00611
00612
00613
00614 if (!notest && !((cmd & CMD_NO_TEST_IF_IN_NETWORK) && _networking)) {
00615 assert(res.GetCost() == res2.GetCost() && CmdFailed(res) == CmdFailed(res2));
00616 } else {
00617 if (CmdFailed(res2)) {
00618 res.SetGlobalErrorMessage();
00619 goto show_error;
00620 }
00621 }
00622
00623 SubtractMoneyFromCompany(res2);
00624
00625
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
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 }