|
@@ -8,25 +8,24 @@
|
|
|
#include "landscape.h"
|
|
|
#include "tile_map.h"
|
|
|
#include "gui.h"
|
|
|
#include "command_func.h"
|
|
|
#include "player.h"
|
|
|
#include "network/network.h"
|
|
|
#include "variables.h"
|
|
|
#include "genworld.h"
|
|
|
#include "newgrf_storage.h"
|
|
|
#include "strings_func.h"
|
|
|
#include "gfx_func.h"
|
|
|
#include "functions.h"
|
|
|
#include "town.h"
|
|
|
|
|
|
const char *_cmd_text = NULL;
|
|
|
|
|
|
/**
|
|
|
* Helper macro to define the header of all command handler macros.
|
|
|
*
|
|
|
* This macro create the function header for a given command handler function, as
|
|
|
* all command handler functions got the parameters from the #CommandProc callback
|
|
|
* type.
|
|
|
*
|
|
|
* @param yyyy The desired function name of the new command handler function.
|
|
|
*/
|
|
@@ -380,25 +379,25 @@ bool IsValidCommand(uint cmd)
|
|
|
*
|
|
|
* @param cmd The integer value of the command
|
|
|
* @return The flags for this command
|
|
|
* @bug integervalues which are less equals 0xFF and greater than the
|
|
|
* size of _command_proc_table can result in an index out of bounce
|
|
|
* error (which doesn't happend anyway). Check function #IsValidCommand(). (Progman)
|
|
|
*/
|
|
|
byte GetCommandFlags(uint cmd)
|
|
|
{
|
|
|
return _command_proc_table[cmd & 0xFF].flags;
|
|
|
}
|
|
|
|
|
|
static int _docommand_recursive = 0;
|
|
|
static int _docommand_recursive;
|
|
|
|
|
|
/*!
|
|
|
* This function executes a given command with the parameters from the #CommandProc parameter list.
|
|
|
* Depending on the flags parameter it execute or test a command.
|
|
|
*
|
|
|
* @param tile The tile to apply the command on (for the #CommandProc)
|
|
|
* @param p1 Additional data for the command (for the #CommandProc)
|
|
|
* @param p2 Additional data for the command (for the #CommandProc)
|
|
|
* @param flags Flags for the command and how to execute the command
|
|
|
* @param procc The command-id to execute (a value of the CMD_* enums)
|
|
|
* @see CommandProc
|
|
|
*/
|
|
@@ -412,27 +411,25 @@ CommandCost DoCommand(TileIndex tile, ui
|
|
|
_cmd_text = NULL;
|
|
|
return CMD_ERROR;
|
|
|
}
|
|
|
|
|
|
proc = _command_proc_table[procc].proc;
|
|
|
|
|
|
if (_docommand_recursive == 0) _error_message = INVALID_STRING_ID;
|
|
|
|
|
|
_docommand_recursive++;
|
|
|
|
|
|
/* only execute the test call if it's toplevel, or we're not execing. */
|
|
|
if (_docommand_recursive == 1 || !(flags & DC_EXEC) || (flags & DC_FORCETEST) ) {
|
|
|
SetTownRatingTestMode(true);
|
|
|
res = proc(tile, flags & ~DC_EXEC, p1, p2);
|
|
|
SetTownRatingTestMode(false);
|
|
|
if (CmdFailed(res)) {
|
|
|
res.SetGlobalErrorMessage();
|
|
|
goto error;
|
|
|
}
|
|
|
|
|
|
if (_docommand_recursive == 1 &&
|
|
|
!(flags & DC_QUERY_COST) &&
|
|
|
res.GetCost() != 0 &&
|
|
|
!CheckPlayerHasMoney(res)) {
|
|
|
goto error;
|
|
|
}
|
|
|
|
|
@@ -548,25 +545,25 @@ bool DoCommandP(TileIndex tile, uint32 p
|
|
|
* road fragments still stay there and the town won't let you
|
|
|
* disconnect the road system), but the exec will succeed and this
|
|
|
* fact will trigger an assertion failure. --pasky
|
|
|
* CMD_CLONE_VEHICLE: Both building new vehicles and refitting them can be
|
|
|
* influenced by newgrf callbacks, which makes it impossible to accurately
|
|
|
* estimate the cost of cloning a vehicle. */
|
|
|
notest =
|
|
|
(cmd & 0xFF) == CMD_CLEAR_AREA ||
|
|
|
(cmd & 0xFF) == CMD_LEVEL_LAND ||
|
|
|
(cmd & 0xFF) == CMD_REMOVE_ROAD ||
|
|
|
(cmd & 0xFF) == CMD_REMOVE_LONG_ROAD ||
|
|
|
(cmd & 0xFF) == CMD_CLONE_VEHICLE;
|
|
|
notest = false;
|
|
|
|
|
|
_docommand_recursive = 1;
|
|
|
|
|
|
/* cost estimation only? */
|
|
|
if (!IsGeneratingWorld() &&
|
|
|
_shift_pressed &&
|
|
|
IsLocalPlayer() &&
|
|
|
!(cmd & (CMD_NETWORK_COMMAND | CMD_SHOW_NO_ERROR)) &&
|
|
|
(cmd & 0xFF) != CMD_PAUSE) {
|
|
|
/* estimate the cost. */
|
|
|
res = proc(tile, flags, p1, p2);
|
|
|
if (CmdFailed(res)) {
|
|
|
res.SetGlobalErrorMessage();
|
|
@@ -575,27 +572,25 @@ bool DoCommandP(TileIndex tile, uint32 p
|
|
|
ShowEstimatedCostOrIncome(res.GetCost(), x, y);
|
|
|
}
|
|
|
|
|
|
_docommand_recursive = 0;
|
|
|
_cmd_text = NULL;
|
|
|
ClearStorageChanges(false);
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
|
|
|
if (!((cmd & CMD_NO_TEST_IF_IN_NETWORK) && _networking)) {
|
|
|
/* first test if the command can be executed. */
|
|
|
SetTownRatingTestMode(true);
|
|
|
res = proc(tile, flags, p1, p2);
|
|
|
SetTownRatingTestMode(false);
|
|
|
if (CmdFailed(res)) {
|
|
|
res.SetGlobalErrorMessage();
|
|
|
goto show_error;
|
|
|
}
|
|
|
/* no money? Only check if notest is off */
|
|
|
if (!notest && res.GetCost() != 0 && !CheckPlayerHasMoney(res)) goto show_error;
|
|
|
}
|
|
|
|
|
|
#ifdef ENABLE_NETWORK
|
|
|
/** If we are in network, and the command is not from the network
|
|
|
* send it to the command-queue and abort execution
|
|
|
* If we are a dedicated server temporarily switch local player, otherwise
|