truelight@0: #include "stdafx.h" truelight@0: #include "ttd.h" tron@507: #include "table/strings.h" tron@679: #include "map.h" truelight@0: #include "gui.h" truelight@0: #include "command.h" truelight@0: #include "player.h" truelight@543: #include "network.h" truelight@0: truelight@0: #define DEF_COMMAND(yyyy) int32 yyyy(int x, int y, uint32 flags, uint32 p1, uint32 p2) truelight@0: truelight@0: DEF_COMMAND(CmdBuildRailroadTrack); truelight@0: DEF_COMMAND(CmdRemoveRailroadTrack); truelight@0: DEF_COMMAND(CmdBuildSingleRail); truelight@0: DEF_COMMAND(CmdRemoveSingleRail); truelight@0: truelight@0: DEF_COMMAND(CmdLandscapeClear); truelight@0: truelight@0: DEF_COMMAND(CmdBuildBridge); truelight@0: truelight@0: DEF_COMMAND(CmdBuildRailroadStation); truelight@0: DEF_COMMAND(CmdRemoveFromRailroadStation); truelight@0: DEF_COMMAND(CmdConvertRail); truelight@0: darkvater@1227: DEF_COMMAND(CmdBuildSingleSignal); darkvater@1227: DEF_COMMAND(CmdRemoveSingleSignal); truelight@0: truelight@0: DEF_COMMAND(CmdTerraformLand); truelight@0: truelight@0: DEF_COMMAND(CmdPurchaseLandArea); truelight@0: DEF_COMMAND(CmdSellLandArea); truelight@0: truelight@0: DEF_COMMAND(CmdBuildTunnel); truelight@0: truelight@0: DEF_COMMAND(CmdBuildTrainDepot); darkvater@395: DEF_COMMAND(CmdBuildTrainWaypoint); darkvater@395: DEF_COMMAND(CmdRenameWaypoint); darkvater@395: DEF_COMMAND(CmdRemoveTrainWaypoint); truelight@0: celestar@1217: DEF_COMMAND(CmdBuildRoadStop); truelight@0: truelight@0: DEF_COMMAND(CmdBuildLongRoad); truelight@0: DEF_COMMAND(CmdRemoveLongRoad); truelight@0: DEF_COMMAND(CmdBuildRoad); truelight@0: DEF_COMMAND(CmdRemoveRoad); truelight@0: truelight@0: DEF_COMMAND(CmdBuildRoadDepot); truelight@0: truelight@0: DEF_COMMAND(CmdBuildAirport); truelight@0: truelight@0: DEF_COMMAND(CmdBuildDock); truelight@0: truelight@0: DEF_COMMAND(CmdBuildShipDepot); truelight@0: truelight@0: DEF_COMMAND(CmdBuildBuoy); truelight@0: truelight@0: DEF_COMMAND(CmdPlantTree); truelight@0: truelight@0: DEF_COMMAND(CmdBuildRailVehicle); truelight@0: DEF_COMMAND(CmdMoveRailVehicle); truelight@0: truelight@0: DEF_COMMAND(CmdStartStopTrain); truelight@0: truelight@0: DEF_COMMAND(CmdSellRailWagon); truelight@0: truelight@0: DEF_COMMAND(CmdTrainGotoDepot); truelight@0: DEF_COMMAND(CmdForceTrainProceed); truelight@0: DEF_COMMAND(CmdReverseTrainDirection); truelight@0: truelight@0: DEF_COMMAND(CmdModifyOrder); truelight@0: DEF_COMMAND(CmdSkipOrder); truelight@0: DEF_COMMAND(CmdDeleteOrder); truelight@0: DEF_COMMAND(CmdInsertOrder); truelight@0: DEF_COMMAND(CmdChangeTrainServiceInt); truelight@0: DEF_COMMAND(CmdRestoreOrderIndex); truelight@0: truelight@0: DEF_COMMAND(CmdBuildIndustry); truelight@0: //DEF_COMMAND(CmdDestroyIndustry); truelight@0: truelight@0: DEF_COMMAND(CmdBuildCompanyHQ); darkvater@147: DEF_COMMAND(CmdDestroyCompanyHQ); truelight@0: DEF_COMMAND(CmdSetPlayerFace); truelight@0: DEF_COMMAND(CmdSetPlayerColor); truelight@0: truelight@0: DEF_COMMAND(CmdIncreaseLoan); truelight@0: DEF_COMMAND(CmdDecreaseLoan); truelight@0: truelight@0: DEF_COMMAND(CmdWantEnginePreview); truelight@0: truelight@0: DEF_COMMAND(CmdNameVehicle); truelight@0: DEF_COMMAND(CmdRenameEngine); truelight@0: truelight@0: DEF_COMMAND(CmdChangeCompanyName); truelight@0: DEF_COMMAND(CmdChangePresidentName); truelight@0: truelight@0: DEF_COMMAND(CmdRenameStation); truelight@0: truelight@0: DEF_COMMAND(CmdSellAircraft); truelight@0: DEF_COMMAND(CmdStartStopAircraft); truelight@0: DEF_COMMAND(CmdBuildAircraft); truelight@0: DEF_COMMAND(CmdSendAircraftToHangar); truelight@0: DEF_COMMAND(CmdChangeAircraftServiceInt); truelight@0: DEF_COMMAND(CmdRefitAircraft); truelight@0: truelight@0: DEF_COMMAND(CmdPlaceSign); truelight@0: DEF_COMMAND(CmdRenameSign); truelight@0: truelight@0: DEF_COMMAND(CmdBuildRoadVeh); truelight@0: DEF_COMMAND(CmdStartStopRoadVeh); truelight@0: DEF_COMMAND(CmdSellRoadVeh); truelight@0: DEF_COMMAND(CmdSendRoadVehToDepot); truelight@0: DEF_COMMAND(CmdTurnRoadVeh); truelight@0: DEF_COMMAND(CmdChangeRoadVehServiceInt); truelight@0: truelight@0: DEF_COMMAND(CmdPause); truelight@0: DEF_COMMAND(CmdResume); truelight@0: truelight@0: DEF_COMMAND(CmdBuyShareInCompany); truelight@0: DEF_COMMAND(CmdSellShareInCompany); truelight@0: DEF_COMMAND(CmdBuyCompany); truelight@0: truelight@0: DEF_COMMAND(CmdBuildTown); truelight@0: truelight@0: DEF_COMMAND(CmdRenameTown); truelight@0: DEF_COMMAND(CmdDoTownAction); truelight@0: truelight@0: DEF_COMMAND(CmdSetRoadDriveSide); truelight@0: DEF_COMMAND(CmdSetTownNameType); truelight@0: truelight@0: DEF_COMMAND(CmdChangeDifficultyLevel); truelight@543: DEF_COMMAND(CmdChangePatchSetting); truelight@0: truelight@0: DEF_COMMAND(CmdStartStopShip); truelight@0: DEF_COMMAND(CmdSellShip); truelight@0: DEF_COMMAND(CmdBuildShip); truelight@0: DEF_COMMAND(CmdSendShipToDepot); truelight@0: DEF_COMMAND(CmdChangeShipServiceInt); truelight@0: DEF_COMMAND(CmdRefitShip); truelight@0: truelight@0: truelight@0: DEF_COMMAND(CmdStartNewGame); truelight@0: DEF_COMMAND(CmdLoadGame); truelight@0: DEF_COMMAND(CmdCreateScenario); truelight@0: DEF_COMMAND(CmdSetSinglePlayer); truelight@0: truelight@0: DEF_COMMAND(CmdSetNewLandscapeType); truelight@0: truelight@0: DEF_COMMAND(CmdGenRandomNewGame); truelight@0: DEF_COMMAND(CmdCloneOrder); truelight@0: truelight@0: DEF_COMMAND(CmdClearArea); truelight@0: truelight@543: DEF_COMMAND(CmdGiveMoney); truelight@0: DEF_COMMAND(CmdMoneyCheat); truelight@0: DEF_COMMAND(CmdBuildCanal); darkvater@147: DEF_COMMAND(CmdBuildLock); truelight@0: truelight@0: DEF_COMMAND(CmdPlayerCtrl); truelight@0: truelight@0: DEF_COMMAND(CmdLevelLand); truelight@0: truelight@0: DEF_COMMAND(CmdRefitRailVehicle); truelight@0: truelight@0: DEF_COMMAND(CmdStartScenario); truelight@0: darkvater@1227: DEF_COMMAND(CmdBuildSignalTrack); darkvater@1227: DEF_COMMAND(CmdRemoveSignalTrack); darkvater@58: bjarni@842: DEF_COMMAND(CmdReplaceVehicle); truelight@812: truelight@0: /* The master command table */ truelight@0: static CommandProc * const _command_proc_table[] = { darkvater@147: CmdBuildRailroadTrack, /* 0 */ darkvater@147: CmdRemoveRailroadTrack, /* 1 */ darkvater@147: CmdBuildSingleRail, /* 2 */ darkvater@147: CmdRemoveSingleRail, /* 3 */ darkvater@147: CmdLandscapeClear, /* 4 */ darkvater@147: CmdBuildBridge, /* 5 */ darkvater@147: CmdBuildRailroadStation, /* 6 */ darkvater@147: CmdBuildTrainDepot, /* 7 */ darkvater@1227: CmdBuildSingleSignal, /* 8 */ darkvater@1227: CmdRemoveSingleSignal, /* 9 */ darkvater@147: CmdTerraformLand, /* 10 */ darkvater@147: CmdPurchaseLandArea, /* 11 */ darkvater@147: CmdSellLandArea, /* 12 */ darkvater@147: CmdBuildTunnel, /* 13 */ truelight@0: CmdRemoveFromRailroadStation, /* 14 */ darkvater@147: CmdConvertRail, /* 15 */ darkvater@395: CmdBuildTrainWaypoint, /* 16 */ darkvater@395: CmdRenameWaypoint, /* 17 */ darkvater@395: CmdRemoveTrainWaypoint, /* 18 */ celestar@1217: NULL, /* 19 */ darkvater@147: NULL, /* 20 */ celestar@1217: CmdBuildRoadStop, /* 21 */ darkvater@147: NULL, /* 22 */ darkvater@147: CmdBuildLongRoad, /* 23 */ darkvater@147: CmdRemoveLongRoad, /* 24 */ darkvater@147: CmdBuildRoad, /* 25 */ darkvater@147: CmdRemoveRoad, /* 26 */ darkvater@147: CmdBuildRoadDepot, /* 27 */ darkvater@147: NULL, /* 28 */ darkvater@147: CmdBuildAirport, /* 29 */ darkvater@147: CmdBuildDock, /* 30 */ darkvater@147: CmdBuildShipDepot, /* 31 */ darkvater@147: CmdBuildBuoy, /* 32 */ darkvater@147: CmdPlantTree, /* 33 */ darkvater@147: CmdBuildRailVehicle, /* 34 */ darkvater@147: CmdMoveRailVehicle, /* 35 */ darkvater@147: CmdStartStopTrain, /* 36 */ darkvater@147: NULL, /* 37 */ darkvater@147: CmdSellRailWagon, /* 38 */ darkvater@147: CmdTrainGotoDepot, /* 39 */ darkvater@147: CmdForceTrainProceed, /* 40 */ darkvater@147: CmdReverseTrainDirection, /* 41 */ truelight@0: darkvater@147: CmdModifyOrder, /* 42 */ darkvater@147: CmdSkipOrder, /* 43 */ darkvater@147: CmdDeleteOrder, /* 44 */ darkvater@147: CmdInsertOrder, /* 45 */ truelight@0: darkvater@147: CmdChangeTrainServiceInt, /* 46 */ truelight@0: darkvater@147: CmdBuildIndustry, /* 47 */ darkvater@147: CmdBuildCompanyHQ, /* 48 */ darkvater@147: CmdSetPlayerFace, /* 49 */ darkvater@147: CmdSetPlayerColor, /* 50 */ truelight@0: darkvater@147: CmdIncreaseLoan, /* 51 */ darkvater@147: CmdDecreaseLoan, /* 52 */ darkvater@147: darkvater@147: CmdWantEnginePreview, /* 53 */ darkvater@147: darkvater@147: CmdNameVehicle, /* 54 */ darkvater@147: CmdRenameEngine, /* 55 */ darkvater@147: darkvater@147: CmdChangeCompanyName, /* 56 */ darkvater@147: CmdChangePresidentName, /* 57 */ darkvater@147: darkvater@147: CmdRenameStation, /* 58 */ darkvater@147: darkvater@147: CmdSellAircraft, /* 59 */ darkvater@147: CmdStartStopAircraft, /* 60 */ darkvater@147: CmdBuildAircraft, /* 61 */ darkvater@147: CmdSendAircraftToHangar, /* 62 */ truelight@0: CmdChangeAircraftServiceInt, /* 63 */ darkvater@147: CmdRefitAircraft, /* 64 */ truelight@0: darkvater@147: CmdPlaceSign, /* 65 */ darkvater@147: CmdRenameSign, /* 66 */ darkvater@147: darkvater@147: CmdBuildRoadVeh, /* 67 */ darkvater@147: CmdStartStopRoadVeh, /* 68 */ darkvater@147: CmdSellRoadVeh, /* 69 */ darkvater@147: CmdSendRoadVehToDepot, /* 70 */ darkvater@147: CmdTurnRoadVeh, /* 71 */ truelight@0: CmdChangeRoadVehServiceInt, /* 72 */ truelight@0: darkvater@147: CmdPause, /* 73 */ truelight@0: darkvater@147: CmdBuyShareInCompany, /* 74 */ darkvater@147: CmdSellShareInCompany, /* 75 */ darkvater@147: CmdBuyCompany, /* 76 */ truelight@0: darkvater@147: CmdBuildTown, /* 77 */ darkvater@147: NULL, /* 78 */ darkvater@147: NULL, /* 79 */ darkvater@147: CmdRenameTown, /* 80 */ darkvater@147: CmdDoTownAction, /* 81 */ truelight@0: darkvater@147: CmdSetRoadDriveSide, /* 82 */ darkvater@147: CmdSetTownNameType, /* 83 */ darkvater@147: NULL, /* 84 */ darkvater@147: CmdChangeDifficultyLevel, /* 85 */ truelight@0: darkvater@147: CmdStartStopShip, /* 86 */ darkvater@147: CmdSellShip, /* 87 */ darkvater@147: CmdBuildShip, /* 88 */ darkvater@147: CmdSendShipToDepot, /* 89 */ darkvater@147: CmdChangeShipServiceInt, /* 90 */ darkvater@147: CmdRefitShip, /* 91 */ darkvater@147: darkvater@147: CmdStartNewGame, /* 92 */ darkvater@147: CmdLoadGame, /* 93 */ darkvater@147: CmdCreateScenario, /* 94 */ darkvater@147: CmdSetSinglePlayer, /* 95 */ darkvater@147: NULL, /* 96 */ darkvater@147: CmdSetNewLandscapeType, /* 97 */ darkvater@147: darkvater@147: CmdGenRandomNewGame, /* 98 */ darkvater@147: darkvater@147: CmdCloneOrder, /* 99 */ darkvater@147: darkvater@147: CmdClearArea, /* 100 */ darkvater@147: CmdResume, /* 101 */ darkvater@147: darkvater@147: CmdMoneyCheat, /* 102 */ darkvater@147: CmdBuildCanal, /* 103 */ darkvater@147: CmdPlayerCtrl, /* 104 */ darkvater@147: darkvater@147: CmdLevelLand, /* 105 */ darkvater@147: darkvater@147: CmdRefitRailVehicle, /* 106 */ darkvater@147: CmdRestoreOrderIndex, /* 107 */ darkvater@147: CmdBuildLock, /* 108 */ darkvater@147: CmdStartScenario, /* 109 */ darkvater@1227: CmdBuildSignalTrack, /* 110 */ darkvater@1227: CmdRemoveSignalTrack, /* 111 */ darkvater@1227: CmdDestroyCompanyHQ, /* 112 */ darkvater@1227: CmdGiveMoney, /* 113 */ darkvater@1227: CmdChangePatchSetting, /* 114 */ darkvater@1227: CmdReplaceVehicle, /* 115 */ darkvater@1227: darkvater@1227: //CmdDestroyIndustry, /* 109 */ truelight@0: }; truelight@0: truelight@903: /* This function range-checks a cmd, and checks if the cmd is not NULL */ tron@959: bool IsValidCommand(uint cmd) truelight@903: { truelight@903: cmd = cmd & 0xFF; truelight@903: tron@959: if (cmd >= lengthof(_command_proc_table) || _command_proc_table[cmd] == NULL) truelight@903: return false; truelight@903: truelight@903: return true; truelight@903: } truelight@903: truelight@0: int32 DoCommandByTile(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint procc) truelight@0: { tron@926: return DoCommand(TileX(tile) * 16, TileY(tile) * 16, p1, p2, flags, procc); truelight@193: } truelight@0: truelight@0: truelight@0: //extern void _stdcall Sleep(int s); truelight@0: truelight@0: int32 DoCommand(int x, int y, uint32 p1, uint32 p2, uint32 flags, uint procc) truelight@0: { truelight@0: int32 res; truelight@0: CommandProc *proc; truelight@193: truelight@0: proc = _command_proc_table[procc]; truelight@0: truelight@0: if (_docommand_recursive == 0) { truelight@0: _error_message = INVALID_STRING_ID; truelight@0: // update last build coord of player truelight@0: if ( (x|y) != 0 && _current_player < MAX_PLAYERS) { truelight@0: DEREF_PLAYER(_current_player)->last_build_coordinate = TILE_FROM_XY(x,y); truelight@0: } truelight@0: } truelight@0: truelight@0: _docommand_recursive++; truelight@0: truelight@0: // only execute the test call if it's toplevel, or we're not execing. truelight@0: if (_docommand_recursive == 1 || !(flags & DC_EXEC) || (flags & DC_FORCETEST) ) { truelight@0: res = proc(x, y, flags&~DC_EXEC, p1, p2); truelight@0: if ((uint32)res >> 16 == 0x8000) { truelight@0: if (res & 0xFFFF) _error_message = res & 0xFFFF; truelight@0: goto error; truelight@0: } truelight@0: truelight@0: if (_docommand_recursive == 1) { truelight@0: if (!(flags&DC_QUERY_COST) && res != 0 && !CheckPlayerHasMoney(res)) truelight@0: goto error; truelight@0: } truelight@0: truelight@0: if (!(flags & DC_EXEC)) { truelight@0: _docommand_recursive--; truelight@0: return res; truelight@0: } truelight@0: } truelight@0: darkvater@889: /* Execute the command here. All cost-relevant functions set the expenses type darkvater@889: * themselves with "SET_EXPENSES_TYPE(...);" at the beginning of the function */ truelight@0: res = proc(x, y, flags, p1, p2); truelight@0: if ((uint32)res >> 16 == 0x8000) { truelight@0: if (res & 0xFFFF) _error_message = res & 0xFFFF; truelight@0: error: truelight@0: _docommand_recursive--; truelight@0: return CMD_ERROR; truelight@0: } truelight@0: truelight@0: // if toplevel, subtract the money. truelight@0: if (--_docommand_recursive == 0) { truelight@0: SubtractMoneyFromPlayer(res); truelight@0: } truelight@0: truelight@0: return res; truelight@0: } truelight@0: tron@1093: int32 GetAvailableMoneyForCommand(void) truelight@0: { truelight@0: uint pid = _current_player; darkvater@147: if (pid >= MAX_PLAYERS) return 0x7FFFFFFF; // max int truelight@0: return DEREF_PLAYER(pid)->player_money; truelight@0: } truelight@0: truelight@0: // toplevel network safe docommand function for the current player. must not be called recursively. truelight@0: // the callback is called when the command succeeded or failed. truelight@0: bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, CommandCallback *callback, uint32 cmd) truelight@0: { truelight@0: int32 res = 0,res2; truelight@0: CommandProc *proc; truelight@0: uint32 flags; truelight@0: bool notest; truelight@0: tron@926: int x = TileX(tile) * 16; tron@926: int y = TileY(tile) * 16; truelight@0: truelight@193: assert(_docommand_recursive == 0); truelight@0: truelight@0: _error_message = INVALID_STRING_ID; truelight@0: _error_message_2 = cmd >> 16; truelight@0: _additional_cash_required = 0; truelight@0: truelight@0: // spectator has no rights. darkvater@147: if (_current_player == OWNER_SPECTATOR) { truelight@0: ShowErrorMessage(_error_message, _error_message_2, x, y); truelight@0: return false; truelight@0: } truelight@0: truelight@0: flags = 0; truelight@0: if (cmd & CMD_AUTO) flags |= DC_AUTO; truelight@0: if (cmd & CMD_NO_WATER) flags |= DC_NO_WATER; truelight@0: truelight@0: // get pointer to command handler truelight@0: assert((cmd & 0xFF) < lengthof(_command_proc_table)); truelight@0: proc = _command_proc_table[cmd & 0xFF]; truelight@0: miham@826: // Some commands have a different output in dryrun than the realrun truelight@543: // e.g.: if you demolish a whole town, the dryrun would say okay. truelight@543: // but by really destroying, your rating drops and at a certain point truelight@543: // it will fail. so res and res2 are different pasky@467: // CMD_REMOVE_ROAD: This command has special local authority pasky@467: // restrictions which may cause the test run to fail (the previous pasky@467: // road fragments still stay there and the town won't let you pasky@467: // disconnect the road system), but the exec will succeed and this pasky@467: // fact will trigger an assertion failure. --pasky truelight@193: notest = truelight@193: (cmd & 0xFF) == CMD_CLEAR_AREA || truelight@193: (cmd & 0xFF) == CMD_CONVERT_RAIL || truelight@0: (cmd & 0xFF) == CMD_LEVEL_LAND || pasky@467: (cmd & 0xFF) == CMD_REMOVE_ROAD; truelight@0: truelight@0: _docommand_recursive = 1; truelight@0: truelight@0: // cost estimation only? bjarni@842: if (_shift_pressed && _current_player == _local_player && !(cmd & (CMD_NETWORK_COMMAND | CMD_SHOW_NO_ERROR))) { truelight@0: // estimate the cost. truelight@0: res = proc(x, y, flags, p1, p2); truelight@0: if ((uint32)res >> 16 == 0x8000) { truelight@0: if (res & 0xFFFF) _error_message = res & 0xFFFF; truelight@0: ShowErrorMessage(_error_message, _error_message_2, x, y); truelight@0: } else { truelight@0: ShowEstimatedCostOrIncome(res, x, y); truelight@0: } truelight@0: truelight@0: _docommand_recursive = 0; truelight@0: return false; truelight@0: } truelight@0: truelight@193: truelight@543: if (!((cmd & CMD_NO_TEST_IF_IN_NETWORK) && _networking)) { truelight@0: // first test if the command can be executed. truelight@0: res = proc(x,y, flags, p1, p2); truelight@0: if ((uint32)res >> 16 == 0x8000) { truelight@0: if (res & 0xFFFF) _error_message = res & 0xFFFF; truelight@0: goto show_error; truelight@0: } truelight@543: // no money? Only check if notest is off truelight@543: if (!notest && res != 0 && !CheckPlayerHasMoney(res)) goto show_error; truelight@0: } truelight@0: truelight@543: #ifdef ENABLE_NETWORK truelight@543: // If we are in network, and the command is not from the network truelight@543: // send it to the command-queue and abort execution truelight@543: if (_networking && !(cmd & CMD_NETWORK_COMMAND)) { truelight@543: NetworkSend_Command(tile, p1, p2, cmd, callback); truelight@543: _docommand_recursive = 0; truelight@543: return true; truelight@0: } truelight@543: #endif /* ENABLE_NETWORK */ truelight@0: truelight@0: // update last build coordinate of player. truelight@0: if ( tile != 0 && _current_player < MAX_PLAYERS) DEREF_PLAYER(_current_player)->last_build_coordinate = tile; truelight@0: darkvater@889: /* Actually try and execute the command. If no cost-type is given darkvater@889: * use the construction one */ darkvater@889: _yearly_expenses_type = EXPENSES_CONSTRUCTION; truelight@0: res2 = proc(x,y, flags|DC_EXEC, p1, p2); truelight@193: miham@826: // If notest is on, it means the result of the test can be different than truelight@543: // the real command.. so ignore the test truelight@652: if (!notest && !((cmd & CMD_NO_TEST_IF_IN_NETWORK) && _networking)) { truelight@0: assert(res == res2); // sanity check truelight@0: } else { truelight@0: if ((uint32)res2 >> 16 == 0x8000) { truelight@0: if (res2 & 0xFFFF) _error_message = res2 & 0xFFFF; truelight@0: goto show_error; truelight@0: } truelight@0: } truelight@0: truelight@0: SubtractMoneyFromPlayer(res2); truelight@0: truelight@0: if (_current_player == _local_player && _game_mode != GM_EDITOR) { truelight@0: if (res2 != 0) truelight@0: ShowCostOrIncomeAnimation(x, y, GetSlopeZ(x, y), res2); truelight@0: if (_additional_cash_required) { tron@534: SetDParam(0, _additional_cash_required); truelight@0: ShowErrorMessage(STR_0003_NOT_ENOUGH_CASH_REQUIRES, _error_message_2, x,y); truelight@0: if (res2 == 0) goto callb_err; truelight@0: } truelight@0: } truelight@0: truelight@0: _docommand_recursive = 0; truelight@193: truelight@0: if (callback) callback(true, tile, p1, p2); truelight@0: return true; truelight@0: truelight@0: show_error: truelight@0: // show error message if the command fails? truelight@0: if (_current_player == _local_player && _error_message_2 != 0) truelight@0: ShowErrorMessage(_error_message, _error_message_2, x,y); truelight@0: truelight@0: callb_err: truelight@0: _docommand_recursive = 0; truelight@193: truelight@0: if (callback) callback(false, tile, p1, p2); truelight@0: return false; truelight@0: }