1
0
Fork 0

(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.

release/1.0
rubidium 2010-01-11 20:42:07 +00:00
parent 2365819312
commit a6ebc1a77e
1 changed files with 17 additions and 27 deletions

View File

@ -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."); 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 */ /* Set the default callback to return a true/false result of the DoCommand */
if (callback == NULL) callback = &AIInstance::DoCommandReturn; if (callback == NULL) callback = &AIInstance::DoCommandReturn;
/* Make sure the last error is reset, so we don't give faulty warnings */ /* Are we only interested in the estimate costs? */
SetLastError(AIError::ERR_NONE); bool estimate_only = GetDoCommandMode() != NULL && !GetDoCommandMode()();
/* First, do a test-run to see if we can do this */ /* Try to perform the command. */
res = ::DoCommand(tile, p1, p2, CommandFlagsToDCFlags(GetCommandFlags(cmd)), cmd, text); CommandCost res = ::DoCommandPInternal(tile, p1, p2, cmd, _networking ? CcAI : NULL, text, false, estimate_only);
/* The command failed, so return */
/* We failed; set the error and bail out */
if (::CmdFailed(res)) { if (::CmdFailed(res)) {
res.SetGlobalErrorMessage();
SetLastError(AIError::StringToError(_error_message)); SetLastError(AIError::StringToError(_error_message));
return false; return false;
} }
/* Check what the callback wants us to do */ /* No error, then clear it. */
if (GetDoCommandMode() != NULL && !GetDoCommandMode()()) { SetLastError(AIError::ERR_NONE);
/* Estimates, update the cost for the estimate and be done */
if (estimate_only) {
IncreaseDoCommandCosts(res.GetCost()); IncreaseDoCommandCosts(res.GetCost());
return true; return true;
} }
#ifdef ENABLE_NETWORK /* Costs of this operation. */
/* Send the command */ SetLastCost(res.GetCost());
if (_networking) { SetLastCommandRes(true);
::NetworkSend_Command(tile, p1, p2, cmd, CcAI, text, _current_company);
SetLastCost(res.GetCost());
/* 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); throw AI_VMSuspend(-(int)GetDoCommandDelay(), callback);
} else { } 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()); IncreaseDoCommandCosts(res.GetCost());
/* Suspend the AI player for 1+ ticks, so it simulates multiplayer. This /* Suspend the AI player for 1+ ticks, so it simulates multiplayer. This