本文整理汇总了C++中CommandCost::GetErrorMessage方法的典型用法代码示例。如果您正苦于以下问题:C++ CommandCost::GetErrorMessage方法的具体用法?C++ CommandCost::GetErrorMessage怎么用?C++ CommandCost::GetErrorMessage使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类CommandCost
的用法示例。
在下文中一共展示了CommandCost::GetErrorMessage方法的9个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: TerraformTiles
/**
* Terraform multiple tiles.
*
* @param iter Iterator pointing tiles to terraform and their target heights.
* @return The cost of all successfull operations and the last error.
*
* @note _terraform_err_tile will be set to the tile where the last error occured
*
* @warning Note non-standard return behaviour - booth the cost \b and the error combined.
*/
static TerraformTilesResult TerraformTiles(TerraformingIterator *iter, DoCommandFlag flags, Money available_money)
{
TerraformTilesResult result = {
0, // cost
false, // had_success
STR_NULL // last_error
};
TileIndex last_err_tile = INVALID_TILE;
const Company *c = Company::GetIfValid(_current_company);
int limit = (c == NULL ? INT32_MAX : GB(c->terraform_limit, 16, 16));
if (limit == 0) result.last_error = STR_ERROR_TERRAFORM_LIMIT_REACHED;
for (; *iter != INVALID_TILE && limit > 0; ++(*iter)) {
int h = iter->GetTileTargetHeight();
TileIndex t = *iter;
for (int curh = TileHeight(t); curh != h; curh += (curh > h) ? -1 : 1) {
CommandCost ret = DoCommand(t, SLOPE_N, (curh > h) ? 0 : 1, flags & ~DC_EXEC, CMD_TERRAFORM_LAND);
if (ret.Failed()) {
result.last_error = ret.GetErrorMessage();
last_err_tile = _terraform_err_tile;
/* Did we reach the limit? */
if (ret.GetErrorMessage() == STR_ERROR_TERRAFORM_LIMIT_REACHED) limit = 0;
break;
}
if (flags & DC_EXEC) {
available_money -= ret.GetCost();
if (available_money < 0) {
_additional_cash_required = ret.GetCost();
_terraform_err_tile = t;
return result;
}
DoCommand(t, SLOPE_N, (curh > h) ? 0 : 1, flags, CMD_TERRAFORM_LAND);
} else {
/* When we're at the terraform limit we better bail (unneeded) testing as well.
* This will probably cause the terraforming cost to be underestimated, but only
* when it's near the terraforming limit. Even then, the estimation is
* completely off due to it basically counting terraforming double, so it being
* cut off earlier might even give a better estimate in some cases. */
if (--limit <= 0) {
result.had_success = true;
break;
}
}
result.cost += ret.GetCost();
result.had_success = true;
}
}
if (!result.had_success && result.last_error == STR_NULL) {
result.last_error = STR_ERROR_ALREADY_LEVELLED;
last_err_tile = INVALID_TILE;
}
_terraform_err_tile = last_err_tile;
return result;
}
示例2: DoCommand
bool AIObject::DoCommand(TileIndex tile, uint32 p1, uint32 p2, uint cmd, const char *text, AISuspendCallbackProc *callback)
{
if (!AIObject::CanSuspend()) {
throw AI_FatalError("You are not allowed to execute any DoCommand (even indirect) in your constructor, Save(), Load(), and any valuator.");
}
/* Set the default callback to return a true/false result of the DoCommand */
if (callback == NULL) callback = &AIInstance::DoCommandReturn;
/* Are we only interested in the estimate costs? */
bool estimate_only = GetDoCommandMode() != NULL && !GetDoCommandMode()();
#ifdef ENABLE_NETWORK
/* Only set p2 when the command does not come from the network. */
if (GetCommandFlags(cmd) & CMD_CLIENT_ID && p2 == 0) p2 = UINT32_MAX;
#endif
/* 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 (res.Failed()) {
SetLastError(AIError::StringToError(res.GetErrorMessage()));
return false;
}
/* 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;
}
/* Costs of this operation. */
SetLastCost(res.GetCost());
SetLastCommandRes(true);
if (_networking) {
/* Suspend the AI till the command is really executed. */
throw AI_VMSuspend(-(int)GetDoCommandDelay(), callback);
} else {
IncreaseDoCommandCosts(res.GetCost());
/* Suspend the AI player for 1+ ticks, so it simulates multiplayer. This
* both avoids confusion when a developer launched his AI in a
* multiplayer game, but also gives time for the GUI and human player
* to interact with the game. */
throw AI_VMSuspend(GetDoCommandDelay(), callback);
}
NOT_REACHED();
}
示例3: DoCommandP
/*!
* Toplevel network safe docommand function for the current company. Must not be called recursively.
* The callback is called when the command succeeded or failed. The parameters
* \a tile, \a p1, and \a p2 are from the #CommandProc function. The parameter \a cmd is the command to execute.
* The parameter \a my_cmd is used to indicate if the command is from a company or the server.
*
* @param tile The tile to perform a command on (see #CommandProc)
* @param p1 Additional data for the command (see #CommandProc)
* @param p2 Additional data for the command (see #CommandProc)
* @param cmd The command to execute (a CMD_* value)
* @param callback A callback function to call after the command is finished
* @param text The text to pass
* @param my_cmd indicator if the command is from a company or server (to display error messages for a user)
* @return \c true if the command succeeded, else \c false.
*/
bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const char *text, bool my_cmd)
{
/* Cost estimation is generally only done when the
* local user presses shift while doing somthing.
* However, in case of incoming network commands,
* map generation or the pause button we do want
* to execute. */
bool estimate_only = _shift_pressed && IsLocalCompany() &&
!_generating_world &&
!(cmd & CMD_NETWORK_COMMAND) &&
(cmd & CMD_ID_MASK) != CMD_PAUSE;
/* We're only sending the command, so don't do
* fancy things for 'success'. */
bool only_sending = _networking && !(cmd & CMD_NETWORK_COMMAND);
/* Where to show the message? */
int x = TileX(tile) * TILE_SIZE;
int y = TileY(tile) * TILE_SIZE;
if (_pause_mode != PM_UNPAUSED && !IsCommandAllowedWhilePaused(cmd)) {
ShowErrorMessage(GB(cmd, 16, 16), STR_ERROR_NOT_ALLOWED_WHILE_PAUSED, WL_INFO, x, y);
return false;
}
#ifdef ENABLE_NETWORK
/* Only set p2 when the command does not come from the network. */
if (!(cmd & CMD_NETWORK_COMMAND) && GetCommandFlags(cmd) & CMD_CLIENT_ID && p2 == 0) p2 = CLIENT_ID_SERVER;
#endif
CommandCost res = DoCommandPInternal(tile, p1, p2, cmd, callback, text, my_cmd, estimate_only);
if (res.Failed()) {
/* Only show the error when it's for us. */
StringID error_part1 = GB(cmd, 16, 16);
if (estimate_only || (IsLocalCompany() && error_part1 != 0 && my_cmd)) {
ShowErrorMessage(error_part1, res.GetErrorMessage(), WL_INFO, x, y, res.GetTextRefStackSize(), res.GetTextRefStack());
}
} else if (estimate_only) {
ShowEstimatedCostOrIncome(res.GetCost(), x, y);
} else if (!only_sending && res.GetCost() != 0 && tile != 0 && IsLocalCompany() && _game_mode != GM_EDITOR) {
/* Only show the cost animation when we did actually
* execute the command, i.e. we're not sending it to
* the server, when it has cost the local company
* something. Furthermore in the editor there is no
* concept of cost, so don't show it there either. */
ShowCostOrIncomeAnimation(x, y, GetSlopePixelZ(x, y), res.GetCost());
}
if (!estimate_only && !only_sending && callback != NULL) {
callback(res, tile, p1, p2);
}
return res.Succeeded();
}
示例4: DoCommandCallback
void ScriptInstance::DoCommandCallback(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2)
{
ScriptObject::ActiveInstance active(this);
ScriptObject::SetLastCommandRes(result.Succeeded());
if (result.Failed()) {
ScriptObject::SetLastError(ScriptError::StringToError(result.GetErrorMessage()));
} else {
ScriptObject::IncreaseDoCommandCosts(result.GetCost());
ScriptObject::SetLastCost(result.GetCost());
}
}
示例5: CcAI
void CcAI(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2)
{
AIObject::SetLastCommandRes(result.Succeeded());
if (result.Failed()) {
AIObject::SetLastError(AIError::StringToError(result.GetErrorMessage()));
} else {
AIObject::IncreaseDoCommandCosts(result.GetCost());
AIObject::SetLastCost(result.GetCost());
}
Company::Get(_current_company)->ai_instance->Continue();
}
示例6: CmdDepotMassAutoReplace
/** Autoreplace all vehicles in the depot
* Note: this command can make incorrect cost estimations
* Luckily the final price can only drop, not increase. This is due to the fact that
* estimation can't predict wagon removal so it presumes worst case which is no income from selling wagons.
* @param tile Tile of the depot where the vehicles are
* @param flags type of operation
* @param p1 Type of vehicle
* @param p2 If bit 0 is set, then either replace all or nothing (instead of replacing until money runs out)
* @param text unused
* @return the cost of this operation or an error
*/
CommandCost CmdDepotMassAutoReplace(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
VehicleList list;
CommandCost cost = CommandCost(EXPENSES_NEW_VEHICLES);
VehicleType vehicle_type = (VehicleType)GB(p1, 0, 8);
bool all_or_nothing = HasBit(p2, 0);
if (!IsDepotTile(tile) || !IsTileOwner(tile, _current_company)) return CMD_ERROR;
/* Get the list of vehicles in the depot */
BuildDepotVehicleList(vehicle_type, tile, &list, &list, true);
bool did_something = false;
for (uint i = 0; i < list.Length(); i++) {
const Vehicle *v = list[i];
/* Ensure that the vehicle completely in the depot */
if (!v->IsInDepot()) continue;
CommandCost ret = DoCommand(0, v->index, 0, flags, CMD_AUTOREPLACE_VEHICLE);
if (CmdSucceeded(ret)) {
did_something = true;
cost.AddCost(ret);
} else {
if (ret.GetErrorMessage() != STR_ERROR_AUTOREPLACE_NOTHING_TO_DO && all_or_nothing) {
/* We failed to replace a vehicle even though we set all or nothing.
* We should never reach this if DC_EXEC is set since then it should
* have failed the estimation guess. */
assert(!(flags & DC_EXEC));
/* Now we will have to return an error. */
return CMD_ERROR;
}
}
}
if (!did_something) {
/* Either we didn't replace anything or something went wrong.
* Either way we want to return an error and not execute this command. */
cost = CMD_ERROR;
}
return cost;
}
示例7: CollectCost
/**
* Aggreagate paste command costs without calling PastingState::DoCommand.
*
* The function works similarly to the PastingState::DoCommand but doesn't actually execute any
* commands, it just collects a given result.
*
* When collecting a success, cost must be of type EXPENSES_CONSTRUCTION. A success also makes
* STR_ERROR_NOTHING_TO_DO no more applies (we "did" something).
*
* Call PastingState::IsInterrupted to test whether the paste operation can be continued.
*
* @param cost The return value of the command, a cost or an error.
* @param tile The tile the error concerns.
* @param error_message Summary message of the error.
*
* @pre The company has enough money if DC_EXEC'ing.
*
* @see PastingState::IsInterrupted
* @see PastingState::CollectError
* @see PastingState::DoCommand
*/
void PastingState::CollectCost(const CommandCost &cost, TileIndex tile, StringID error_summary)
{
if (cost.Succeeded()) {
assert(!this->IsInterrupted());
/* Currently only EXPENSES_CONSTRUCTION expenses are allowed when copy/pasting. If this
* is not sufficient, some upgrade will be required. To allow proper update of finacial
* statistics, the overal cost of paste operation will have to be stored separatly for
* each supported type of expenses. */
assert(cost.GetExpensesType() == EXPENSES_CONSTRUCTION);
/* make sure we are not expending too much */
assert(!(this->dc_flags & DC_EXEC) || cost.GetCost() <= 0 || this->GetAvailableMoney() >= 0);
this->had_success = true; // mark that we had a succes and STR_ERROR_NOTHING_TO_DO no more applies
this->overal_cost += cost.GetCost();
this->last_result = cost;
} else {
this->CollectError(tile, cost.GetErrorMessage(), error_summary);
}
}
示例8: Script_FatalError
/* static */ bool ScriptObject::DoCommand(TileIndex tile, uint32 p1, uint32 p2, uint cmd, const char *text, Script_SuspendCallbackProc *callback)
{
if (!ScriptObject::CanSuspend()) {
throw Script_FatalError("You are not allowed to execute any DoCommand (even indirect) in your constructor, Save(), Load(), and any valuator.");
}
if (ScriptObject::GetCompany() != OWNER_DEITY && !::Company::IsValidID(ScriptObject::GetCompany())) {
ScriptObject::SetLastError(ScriptError::ERR_PRECONDITION_INVALID_COMPANY);
return false;
}
assert(StrEmpty(text) || (GetCommandFlags(cmd) & CMD_STR_CTRL) != 0 || StrValid(text, text + strlen(text)));
/* Set the default callback to return a true/false result of the DoCommand */
if (callback == NULL) callback = &ScriptInstance::DoCommandReturn;
/* Are we only interested in the estimate costs? */
bool estimate_only = GetDoCommandMode() != NULL && !GetDoCommandMode()();
#ifdef ENABLE_NETWORK
/* Only set p2 when the command does not come from the network. */
if (GetCommandFlags(cmd) & CMD_CLIENT_ID && p2 == 0) p2 = UINT32_MAX;
#endif
/* Try to perform the command. */
CommandCost res = ::DoCommandPInternal(tile, p1, p2, cmd, (_networking && !_generating_world) ? ScriptObject::GetActiveInstance()->GetDoCommandCallback() : NULL, text, false, estimate_only);
/* We failed; set the error and bail out */
if (res.Failed()) {
SetLastError(ScriptError::StringToError(res.GetErrorMessage()));
return false;
}
/* No error, then clear it. */
SetLastError(ScriptError::ERR_NONE);
/* Estimates, update the cost for the estimate and be done */
if (estimate_only) {
IncreaseDoCommandCosts(res.GetCost());
return true;
}
/* Costs of this operation. */
SetLastCost(res.GetCost());
SetLastCommandRes(true);
if (_generating_world) {
IncreaseDoCommandCosts(res.GetCost());
if (callback != NULL) {
/* Insert return value into to stack and throw a control code that
* the return value in the stack should be used. */
callback(GetActiveInstance());
throw SQInteger(1);
}
return true;
} else if (_networking) {
/* Suspend the script till the command is really executed. */
throw Script_Suspend(-(int)GetDoCommandDelay(), callback);
} else {
IncreaseDoCommandCosts(res.GetCost());
/* Suspend the script player for 1+ ticks, so it simulates multiplayer. This
* both avoids confusion when a developer launched his script in a
* multiplayer game, but also gives time for the GUI and human player
* to interact with the game. */
throw Script_Suspend(GetDoCommandDelay(), callback);
}
NOT_REACHED();
}
示例9: ReplaceChain
/**
* Replace a whole vehicle chain
* @param chain vehicle chain to let autoreplace/renew operator on
* @param flags command flags
* @param wagon_removal remove wagons when the resulting chain occupies more tiles than the old did
* @param nothing_to_do is set to 'false' when something was done (only valid when not failed)
* @return cost or error
*/
static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon_removal, bool *nothing_to_do)
{
Vehicle *old_head = *chain;
assert(old_head->IsPrimaryVehicle());
CommandCost cost = CommandCost(EXPENSES_NEW_VEHICLES, 0);
if (old_head->type == VEH_TRAIN) {
/* Store the length of the old vehicle chain, rounded up to whole tiles */
uint16 old_total_length = CeilDiv(Train::From(old_head)->gcache.cached_total_length, TILE_SIZE) * TILE_SIZE;
int num_units = 0; ///< Number of units in the chain
for (Train *w = Train::From(old_head); w != NULL; w = w->GetNextUnit()) num_units++;
Train **old_vehs = CallocT<Train *>(num_units); ///< Will store vehicles of the old chain in their order
Train **new_vehs = CallocT<Train *>(num_units); ///< New vehicles corresponding to old_vehs or NULL if no replacement
Money *new_costs = MallocT<Money>(num_units); ///< Costs for buying and refitting the new vehicles
/* Collect vehicles and build replacements
* Note: The replacement vehicles can only successfully build as long as the old vehicles are still in their chain */
int i;
Train *w;
for (w = Train::From(old_head), i = 0; w != NULL; w = w->GetNextUnit(), i++) {
assert(i < num_units);
old_vehs[i] = w;
CommandCost ret = BuildReplacementVehicle(old_vehs[i], (Vehicle**)&new_vehs[i], true);
cost.AddCost(ret);
if (cost.Failed()) break;
new_costs[i] = ret.GetCost();
if (new_vehs[i] != NULL) *nothing_to_do = false;
}
Train *new_head = (new_vehs[0] != NULL ? new_vehs[0] : old_vehs[0]);
/* Note: When autoreplace has already failed here, old_vehs[] is not completely initialized. But it is also not needed. */
if (cost.Succeeded()) {
/* Separate the head, so we can start constructing the new chain */
Train *second = Train::From(old_head)->GetNextUnit();
if (second != NULL) cost.AddCost(CmdMoveVehicle(second, NULL, DC_EXEC | DC_AUTOREPLACE, true));
assert(Train::From(new_head)->GetNextUnit() == NULL);
/* Append engines to the new chain
* We do this from back to front, so that the head of the temporary vehicle chain does not change all the time.
* That way we also have less trouble when exceeding the unitnumber limit.
* OTOH the vehicle attach callback is more expensive this way :s */
Train *last_engine = NULL; ///< Shall store the last engine unit after this step
if (cost.Succeeded()) {
for (int i = num_units - 1; i > 0; i--) {
Train *append = (new_vehs[i] != NULL ? new_vehs[i] : old_vehs[i]);
if (RailVehInfo(append->engine_type)->railveh_type == RAILVEH_WAGON) continue;
if (new_vehs[i] != NULL) {
/* Move the old engine to a separate row with DC_AUTOREPLACE. Else
* moving the wagon in front may fail later due to unitnumber limit.
* (We have to attach wagons without DC_AUTOREPLACE.) */
CmdMoveVehicle(old_vehs[i], NULL, DC_EXEC | DC_AUTOREPLACE, false);
}
if (last_engine == NULL) last_engine = append;
cost.AddCost(CmdMoveVehicle(append, new_head, DC_EXEC, false));
if (cost.Failed()) break;
}
if (last_engine == NULL) last_engine = new_head;
}
/* When wagon removal is enabled and the new engines without any wagons are already longer than the old, we have to fail */
if (cost.Succeeded() && wagon_removal && new_head->gcache.cached_total_length > old_total_length) cost = CommandCost(STR_ERROR_TRAIN_TOO_LONG_AFTER_REPLACEMENT);
/* Append/insert wagons into the new vehicle chain
* We do this from back to front, so we can stop when wagon removal or maximum train length (i.e. from mammoth-train setting) is triggered.
*/
if (cost.Succeeded()) {
for (int i = num_units - 1; i > 0; i--) {
assert(last_engine != NULL);
Vehicle *append = (new_vehs[i] != NULL ? new_vehs[i] : old_vehs[i]);
if (RailVehInfo(append->engine_type)->railveh_type == RAILVEH_WAGON) {
/* Insert wagon after 'last_engine' */
CommandCost res = CmdMoveVehicle(append, last_engine, DC_EXEC, false);
/* When we allow removal of wagons, either the move failing due
* to the train becoming too long, or the train becoming longer
* would move the vehicle to the empty vehicle chain. */
if (wagon_removal && (res.Failed() ? res.GetErrorMessage() == STR_ERROR_TRAIN_TOO_LONG : new_head->gcache.cached_total_length > old_total_length)) {
CmdMoveVehicle(append, NULL, DC_EXEC | DC_AUTOREPLACE, false);
break;
}
cost.AddCost(res);
//.........这里部分代码省略.........