summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorrubidium <rubidium@openttd.org>2010-01-11 20:42:07 +0000
committerrubidium <rubidium@openttd.org>2010-01-11 20:42:07 +0000
commita6ebc1a77e51f472c482e703eede9880e076bd56 (patch)
treecd468157c9a9898170d9f306b53d7f803b88a4e0 /src
parent23658193124f18a6efd6f74d2a704b32464c9973 (diff)
downloadopenttd-a6ebc1a77e51f472c482e703eede9880e076bd56.tar.xz
(svn r18786) -Fix [FS#3507]: NoAI's custom implementation of DoCommandP has several flaws (not masking of bits, not resetting town authority updates on checks/estimates, ...). Let it use DoCommandPInternal, DoCommandP without showing error messages and such, instead.
Diffstat (limited to 'src')
-rw-r--r--src/ai/api/ai_object.cpp44
1 files changed, 17 insertions, 27 deletions
diff --git a/src/ai/api/ai_object.cpp b/src/ai/api/ai_object.cpp
index 43103afb7..c6b0da1bc 100644
--- a/src/ai/api/ai_object.cpp
+++ b/src/ai/api/ai_object.cpp
@@ -205,49 +205,39 @@ bool AIObject::DoCommand(TileIndex tile, uint32 p1, uint32 p2, uint cmd, const c
throw AI_FatalError("You are not allowed to execute any DoCommand (even indirect) in your constructor, Save(), Load(), and any valuator.");
}
- CommandCost res;
-
/* Set the default callback to return a true/false result of the DoCommand */
if (callback == NULL) callback = &AIInstance::DoCommandReturn;
- /* Make sure the last error is reset, so we don't give faulty warnings */
- SetLastError(AIError::ERR_NONE);
+ /* Are we only interested in the estimate costs? */
+ bool estimate_only = GetDoCommandMode() != NULL && !GetDoCommandMode()();
- /* First, do a test-run to see if we can do this */
- res = ::DoCommand(tile, p1, p2, CommandFlagsToDCFlags(GetCommandFlags(cmd)), cmd, text);
- /* The command failed, so return */
+ /* Try to perform the command. */
+ CommandCost res = ::DoCommandPInternal(tile, p1, p2, cmd, _networking ? CcAI : NULL, text, false, estimate_only);
+
+ /* We failed; set the error and bail out */
if (::CmdFailed(res)) {
+ res.SetGlobalErrorMessage();
SetLastError(AIError::StringToError(_error_message));
return false;
}
- /* Check what the callback wants us to do */
- if (GetDoCommandMode() != NULL && !GetDoCommandMode()()) {
+ /* No error, then clear it. */
+ SetLastError(AIError::ERR_NONE);
+
+ /* Estimates, update the cost for the estimate and be done */
+ if (estimate_only) {
IncreaseDoCommandCosts(res.GetCost());
return true;
}
-#ifdef ENABLE_NETWORK
- /* Send the command */
- if (_networking) {
- ::NetworkSend_Command(tile, p1, p2, cmd, CcAI, text, _current_company);
- SetLastCost(res.GetCost());
+ /* Costs of this operation. */
+ SetLastCost(res.GetCost());
+ SetLastCommandRes(true);
- /* Suspend the AI till the command is really executed */
+ if (_networking) {
+ /* Suspend the AI till the command is really executed. */
throw AI_VMSuspend(-(int)GetDoCommandDelay(), callback);
} else {
-#else
- {
-#endif
- /* For SinglePlayer we execute the command immediatly */
- if (!::DoCommandP(tile, p1, p2, cmd, NULL, text)) res = CMD_ERROR;
- SetLastCommandRes(!::CmdFailed(res));
-
- if (::CmdFailed(res)) {
- SetLastError(AIError::StringToError(_error_message));
- return false;
- }
- SetLastCost(res.GetCost());
IncreaseDoCommandCosts(res.GetCost());
/* Suspend the AI player for 1+ ticks, so it simulates multiplayer. This