当前位置: 首页>>代码示例>>C++>>正文


C++ CommandCost::GetCost方法代码示例

本文整理汇总了C++中CommandCost::GetCost方法的典型用法代码示例。如果您正苦于以下问题:C++ CommandCost::GetCost方法的具体用法?C++ CommandCost::GetCost怎么用?C++ CommandCost::GetCost使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在CommandCost的用法示例。


在下文中一共展示了CommandCost::GetCost方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的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;
}
开发者ID:koreapyj,项目名称:openttd-yapp,代码行数:70,代码来源:terraform_cmd.cpp

示例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();
}
开发者ID:ShaunOfTheLive,项目名称:OpenCoasterTycoon,代码行数:54,代码来源:ai_object.cpp

示例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();
}
开发者ID:ComLock,项目名称:OpenTTD,代码行数:69,代码来源:command.cpp

示例4: CheckCompanyHasMoney

/**
 * Verify whether the company can pay the bill.
 * @param cost [inout] Money to pay, is changed to an error if the company does not have enough money.
 * @return Function returns \c true if the company has enough money, else it returns \c false.
 */
bool CheckCompanyHasMoney(CommandCost &cost)
{
	if (cost.GetCost() > 0) {
		const Company *c = Company::GetIfValid(_current_company);
		if (c != NULL && cost.GetCost() > c->money) {
			SetDParam(0, cost.GetCost());
			cost.MakeError(STR_ERROR_NOT_ENOUGH_CASH_REQUIRES_CURRENCY);
			return false;
		}
	}
	return true;
}
开发者ID:habnabit,项目名称:openttd-cargodist,代码行数:17,代码来源:company_cmd.cpp

示例5: 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());
	}
}
开发者ID:Ayutac,项目名称:OpenTTD,代码行数:13,代码来源:script_instance.cpp

示例6: 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();
}
开发者ID:oshepherd,项目名称:openttd-progsigs,代码行数:13,代码来源:ai_core.cpp

示例7: DoCommand

/*!
 * 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 cmd The command-id to execute (a value of the CMD_* enums)
 * @param text The text to pass
 * @see CommandProc
 * @return the cost
 */
CommandCost DoCommand(TileIndex tile, uint32 p1, uint32 p2, DoCommandFlag flags, uint32 cmd, const char *text)
{
	CommandCost res;

	/* Do not even think about executing out-of-bounds tile-commands */
	if (tile != 0 && (tile >= MapSize() || (!IsValidTile(tile) && (flags & DC_ALL_TILES) == 0))) return CMD_ERROR;

	/* Chop of any CMD_MSG or other flags; we don't need those here */
	CommandProc *proc = _command_proc_table[cmd & CMD_ID_MASK].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) ) {
		SetTownRatingTestMode(true);
		res = proc(tile, flags & ~DC_EXEC, p1, p2, text);
		SetTownRatingTestMode(false);
		if (CmdFailed(res)) {
			res.SetGlobalErrorMessage();
			goto error;
		}

		if (_docommand_recursive == 1 &&
				!(flags & DC_QUERY_COST) &&
				!(flags & DC_BANKRUPT) &&
				res.GetCost() != 0 &&
				!CheckCompanyHasMoney(res)) {
			goto error;
		}

		if (!(flags & DC_EXEC)) {
			_docommand_recursive--;
			return res;
		}
	}

	/* Execute the command here. All cost-relevant functions set the expenses type
	 * themselves to the cost object at some point */
	res = proc(tile, flags, p1, p2, text);
	if (CmdFailed(res)) {
		res.SetGlobalErrorMessage();
error:
		_docommand_recursive--;
		return CMD_ERROR;
	}

	/* if toplevel, subtract the money. */
	if (--_docommand_recursive == 0 && !(flags & DC_BANKRUPT)) {
		SubtractMoneyFromCompany(res);
	}

	return res;
}
开发者ID:Voxar,项目名称:OpenTTD,代码行数:68,代码来源:command.cpp

示例8: SubtractMoneyFromCompanyFract

/**
 * Subtract money from a company, including the money fraction.
 * @param company Company paying the bill.
 * @param cst     Cost of a command.
 */
void SubtractMoneyFromCompanyFract(CompanyID company, CommandCost cst)
{
	Company *c = Company::Get(company);
	byte m = c->money_fraction;
	Money cost = cst.GetCost();

	c->money_fraction = m - (byte)cost;
	cost >>= 8;
	if (c->money_fraction > m) cost++;
	if (cost != 0) SubtractMoneyFromAnyCompany(c, CommandCost(cst.GetExpensesType(), cost));
}
开发者ID:habnabit,项目名称:openttd-cargodist,代码行数:16,代码来源:company_cmd.cpp

示例9: 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);
	}
}
开发者ID:koreapyj,项目名称:openttd-yapp,代码行数:41,代码来源:copypaste_cmd.cpp

示例10: DoCommand

/**
 * Call a given command as an ingredient of a paste operation.
 *
 * Costs and possible errors will be aggregated. After return, call PastingState::IsInterrupted to
 * test if the paste operation is disallowed to be continued.
 *
 * @param tile The tile to apply the command on.
 * @param p1 Additional data for the command.
 * @param p2 Additional data for the command.
 * @param cmd The command-id to execute (a value of the CMD_* enums) and the error summary message (CMD_MSG).
 * @return The cost of this operation or an error.
 *
 * @pre The command is not flagged with CMD_NO_TEST.
 * @pre The type of the command is CMDT_LANDSCAPE_CONSTRUCTION.
 *
 * @see PastingState::IsInterrupted
 * @see PastingState::CollectCost
 * @see PastingState::CollectError
 */
void PastingState::DoCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd)
{
	/* make sure we are still allowed to paste */
	if (this->IsInterrupted()) {
		this->last_result = CMD_ERROR; // mark that the command didn't succeed
		return;
	}

	/* PastingState::DoCommand can handle only fully predictable commands, those without
	 * CMD_NO_TEST flag. Unpredictable command have to be handled separately. */
	assert(!(GetCommandFlags(cmd) & CMD_NO_TEST));

	/* ignore some of the given flags, instead use those from the command proc table */
	DoCommandFlag flags = this->dc_flags;
	flags &= ~DC_AUTO & ~DC_NO_WATER & ~DC_ALL_TILES;
	flags |= CommandFlagsToDCFlags(GetCommandFlags(cmd));

	/* use given error message or the default one */
	StringID summary_error_msg = GB(cmd, 16, 16);
	if (summary_error_msg == 0) summary_error_msg = STR_ERROR_CAN_T_PASTE_HERE;

	/* test the command, output is the return value */
	CommandCost ret = ::DoCommand(tile, p1, p2, flags & ~DC_EXEC, cmd);

	/* apply if exec'ing */
	if (ret.Succeeded() && (flags & DC_EXEC)) {
		/* check if there is enough money */
		if (ret.GetCost() > 0 && this->GetAvailableMoney() < ret.GetCost()) {
			SetDParam(0, ret.GetCost());
			ret = CommandCost(STR_ERROR_NOT_ENOUGH_CASH_REQUIRES_CURRENCY);
		} else {
			CommandCost ret2 = ::DoCommand(tile, p1, p2, flags, cmd);
			assert(ret == ret2);
		}
	}

	/* aggregate costs */
	this->CollectCost(ret, tile, summary_error_msg);
}
开发者ID:koreapyj,项目名称:openttd-yapp,代码行数:58,代码来源:copypaste_cmd.cpp

示例11: SubtractMoneyFromAnyCompany

/**
 * Deduct costs of a command from the money of a company.
 * @param c Company to pay the bill.
 * @param cost Money to pay.
 */
static void SubtractMoneyFromAnyCompany(Company *c, CommandCost cost)
{
	if (cost.GetCost() == 0) return;
	assert(cost.GetExpensesType() != INVALID_EXPENSES);

	c->money -= cost.GetCost();
	c->yearly_expenses[0][cost.GetExpensesType()] += cost.GetCost();

	if (HasBit(1 << EXPENSES_TRAIN_INC    |
	           1 << EXPENSES_ROADVEH_INC  |
	           1 << EXPENSES_AIRCRAFT_INC |
	           1 << EXPENSES_SHIP_INC, cost.GetExpensesType())) {
		c->cur_economy.income -= cost.GetCost();
	} else if (HasBit(1 << EXPENSES_TRAIN_RUN    |
	                  1 << EXPENSES_ROADVEH_RUN  |
	                  1 << EXPENSES_AIRCRAFT_RUN |
	                  1 << EXPENSES_SHIP_RUN     |
	                  1 << EXPENSES_PROPERTY     |
	                  1 << EXPENSES_LOAN_INT, cost.GetExpensesType())) {
		c->cur_economy.expenses -= cost.GetCost();
	}

	InvalidateCompanyWindows(c);
}
开发者ID:habnabit,项目名称:openttd-cargodist,代码行数:29,代码来源:company_cmd.cpp

示例12: OnInit

	virtual void OnInit()
	{
		Town *t = ClosestTownFromTile(tile, _settings_game.economy.dist_local_authority);

		/* Because build_date is not set yet in every TileDesc, we make sure it is empty */
		TileDesc td;

		td.build_date = INVALID_DATE;

		/* Most tiles have only one owner, but
		 *  - drivethrough roadstops can be build on town owned roads (up to 2 owners) and
		 *  - roads can have up to four owners (railroad, road, tram, 3rd-roadtype "highway").
		 */
		td.owner_type[0] = STR_LAND_AREA_INFORMATION_OWNER; // At least one owner is displayed, though it might be "N/A".
		td.owner_type[1] = STR_NULL;       // STR_NULL results in skipping the owner
		td.owner_type[2] = STR_NULL;
		td.owner_type[3] = STR_NULL;
		td.owner[0] = OWNER_NONE;
		td.owner[1] = OWNER_NONE;
		td.owner[2] = OWNER_NONE;
		td.owner[3] = OWNER_NONE;

		td.station_class = STR_NULL;
		td.station_name = STR_NULL;
		td.airport_class = STR_NULL;
		td.airport_name = STR_NULL;
		td.airport_tile_name = STR_NULL;
		td.rail_speed = 0;

		td.grf = NULL;

		CargoArray acceptance;
		AddAcceptedCargo(tile, acceptance, NULL);
		GetTileDesc(tile, &td);

		uint line_nr = 0;

		/* Tiletype */
		SetDParam(0, td.dparam[0]);
		GetString(this->landinfo_data[line_nr], td.str, lastof(this->landinfo_data[line_nr]));
		line_nr++;

		/* Up to four owners */
		for (uint i = 0; i < 4; i++) {
			if (td.owner_type[i] == STR_NULL) continue;

			SetDParam(0, STR_LAND_AREA_INFORMATION_OWNER_N_A);
			if (td.owner[i] != OWNER_NONE && td.owner[i] != OWNER_WATER) GetNameOfOwner(td.owner[i], tile);
			GetString(this->landinfo_data[line_nr], td.owner_type[i], lastof(this->landinfo_data[line_nr]));
			line_nr++;
		}

		/* Cost to clear/revenue when cleared */
		StringID str = STR_LAND_AREA_INFORMATION_COST_TO_CLEAR_N_A;
		Company *c = Company::GetIfValid(_local_company);
		if (c != NULL) {
			Money old_money = c->money;
			c->money = INT64_MAX;
			assert(_current_company == _local_company);
			CommandCost costclear = DoCommand(tile, 0, 0, DC_NONE, CMD_LANDSCAPE_CLEAR);
			c->money = old_money;
			if (costclear.Succeeded()) {
				Money cost = costclear.GetCost();
				if (cost < 0) {
					cost = -cost; // Negate negative cost to a positive revenue
					str = STR_LAND_AREA_INFORMATION_REVENUE_WHEN_CLEARED;
				} else {
					str = STR_LAND_AREA_INFORMATION_COST_TO_CLEAR;
				}
				SetDParam(0, cost);
			}
		}
		GetString(this->landinfo_data[line_nr], str, lastof(this->landinfo_data[line_nr]));
		line_nr++;

		/* Location */
		char tmp[16];
		snprintf(tmp, lengthof(tmp), "0x%.4X", tile);
		SetDParam(0, TileX(tile));
		SetDParam(1, TileY(tile));
		SetDParam(2, GetTileZ(tile));
		SetDParamStr(3, tmp);
		GetString(this->landinfo_data[line_nr], STR_LAND_AREA_INFORMATION_LANDINFO_COORDS, lastof(this->landinfo_data[line_nr]));
		line_nr++;

		/* Local authority */
		SetDParam(0, STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE);
		if (t != NULL) {
			SetDParam(0, STR_TOWN_NAME);
			SetDParam(1, t->index);
		}
		GetString(this->landinfo_data[line_nr], STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY, lastof(this->landinfo_data[line_nr]));
		line_nr++;

		/* Build date */
		if (td.build_date != INVALID_DATE) {
			SetDParam(0, td.build_date);
			GetString(this->landinfo_data[line_nr], STR_LAND_AREA_INFORMATION_BUILD_DATE, lastof(this->landinfo_data[line_nr]));
			line_nr++;
		}
//.........这里部分代码省略.........
开发者ID:gfarfl,项目名称:openttd-cargodist,代码行数:101,代码来源:misc_gui.cpp

示例13: 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();
}
开发者ID:sgzwiz,项目名称:OpenTTD,代码行数:70,代码来源:script_object.cpp

示例14: CmdAutoreplaceVehicle

/**
 * Autoreplaces a vehicle
 * Trains are replaced as a whole chain, free wagons in depot are replaced on their own
 * @param tile not used
 * @param flags type of operation
 * @param p1 Index of vehicle
 * @param p2 not used
 * @param text unused
 * @return the cost of this operation or an error
 */
CommandCost CmdAutoreplaceVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
	Vehicle *v = Vehicle::GetIfValid(p1);
	if (v == NULL) return CMD_ERROR;

	CommandCost ret = CheckOwnership(v->owner);
	if (ret.Failed()) return ret;

	if (!v->IsInDepot()) return CMD_ERROR;
	if (v->vehstatus & VS_CRASHED) return CMD_ERROR;

	bool free_wagon = false;
	if (v->type == VEH_TRAIN) {
		Train *t = Train::From(v);
		if (t->IsArticulatedPart() || t->IsRearDualheaded()) return CMD_ERROR;
		free_wagon = !t->IsFrontEngine();
		if (free_wagon && t->First()->IsFrontEngine()) return CMD_ERROR;
	} else {
		if (!v->IsPrimaryVehicle()) return CMD_ERROR;
	}

	const Company *c = Company::Get(_current_company);
	bool wagon_removal = c->settings.renew_keep_length;

	/* Test whether any replacement is set, before issuing a whole lot of commands that would end in nothing changed */
	Vehicle *w = v;
	bool any_replacements = false;
	while (w != NULL) {
		EngineID e;
		CommandCost cost = GetNewEngineType(w, c, e);
		if (cost.Failed()) return cost;
		any_replacements |= (e != INVALID_ENGINE);
		w = (!free_wagon && w->type == VEH_TRAIN ? Train::From(w)->GetNextUnit() : NULL);
	}

	CommandCost cost = CommandCost(EXPENSES_NEW_VEHICLES, 0);
	bool nothing_to_do = true;

	if (any_replacements) {
		bool was_stopped = free_wagon || ((v->vehstatus & VS_STOPPED) != 0);

		/* Stop the vehicle */
		if (!was_stopped) cost.AddCost(CmdStartStopVehicle(v, true));
		if (cost.Failed()) return cost;

		assert(v->IsStoppedInDepot());

		/* We have to construct the new vehicle chain to test whether it is valid.
		 * Vehicle construction needs random bits, so we have to save the random seeds
		 * to prevent desyncs and to replay newgrf callbacks during DC_EXEC */
		SavedRandomSeeds saved_seeds;
		SaveRandomSeeds(&saved_seeds);
		if (free_wagon) {
			cost.AddCost(ReplaceFreeUnit(&v, flags & ~DC_EXEC, &nothing_to_do));
		} else {
			cost.AddCost(ReplaceChain(&v, flags & ~DC_EXEC, wagon_removal, &nothing_to_do));
		}
		RestoreRandomSeeds(saved_seeds);

		if (cost.Succeeded() && (flags & DC_EXEC) != 0) {
			CommandCost ret;
			if (free_wagon) {
				ret = ReplaceFreeUnit(&v, flags, &nothing_to_do);
			} else {
				ret = ReplaceChain(&v, flags, wagon_removal, &nothing_to_do);
			}
			assert(ret.Succeeded() && ret.GetCost() == cost.GetCost());
		}

		/* Restart the vehicle */
		if (!was_stopped) cost.AddCost(CmdStartStopVehicle(v, false));
	}

	if (cost.Succeeded() && nothing_to_do) cost = CommandCost(STR_ERROR_AUTOREPLACE_NOTHING_TO_DO);
	return cost;
}
开发者ID:benjeffery,项目名称:openttd,代码行数:86,代码来源:autoreplace_cmd.cpp

示例15: 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);
//.........这里部分代码省略.........
开发者ID:benjeffery,项目名称:openttd,代码行数:101,代码来源:autoreplace_cmd.cpp


注:本文中的CommandCost::GetCost方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。