Changeset - r15282:8e9c51163c93
[Not reviewed]
master
0 17 0
frosch - 14 years ago 2010-06-05 12:16:12
frosch@openttd.org
(svn r19931) -Fix (r19914): Convert assertion in Backup<> destructor into DEBUG() output. It was triggered on exceptions, especially when aborting world generation.
17 files changed with 62 insertions and 44 deletions:
0 comments (0 inline, 0 general)
src/ai/ai_core.cpp
Show inline comments
 
@@ -60,25 +60,25 @@
 
}
 

	
 
/* static */ void AI::GameLoop()
 
{
 
	/* If we are in networking, only servers run this function, and that only if it is allowed */
 
	if (_networking && (!_network_server || !_settings_game.ai.ai_in_multiplayer)) return;
 

	
 
	/* The speed with which AIs go, is limited by the 'competitor_speed' */
 
	AI::frame_counter++;
 
	assert(_settings_game.difficulty.competitor_speed <= 4);
 
	if ((AI::frame_counter & ((1 << (4 - _settings_game.difficulty.competitor_speed)) - 1)) != 0) return;
 

	
 
	Backup<CompanyByte> cur_company(_current_company);
 
	Backup<CompanyByte> cur_company(_current_company, FILE_LINE);
 
	const Company *c;
 
	FOR_ALL_COMPANIES(c) {
 
		if (c->is_ai) {
 
			cur_company.Change(c->index);
 
			c->ai_instance->GameLoop();
 
		}
 
	}
 
	cur_company.Restore();
 

	
 
	/* Occasionally collect garbage; every 255 ticks do one company.
 
	 * Effectively collecting garbage once every two months per AI. */
 
	if ((AI::frame_counter & 255) == 0) {
 
@@ -87,41 +87,41 @@
 
	}
 
}
 

	
 
/* static */ uint AI::GetTick()
 
{
 
	return AI::frame_counter;
 
}
 

	
 
/* static */ void AI::Stop(CompanyID company)
 
{
 
	if (_networking && !_network_server) return;
 

	
 
	Backup<CompanyByte> cur_company(_current_company, company);
 
	Backup<CompanyByte> cur_company(_current_company, company, FILE_LINE);
 
	Company *c = Company::Get(company);
 

	
 
	delete c->ai_instance;
 
	c->ai_instance = NULL;
 

	
 
	cur_company.Restore();
 

	
 
	InvalidateWindowData(WC_AI_DEBUG, 0, -1);
 
	DeleteWindowById(WC_AI_SETTINGS, company);
 
}
 

	
 
/* static */ void AI::Suspend(CompanyID company)
 
{
 
	if (_networking && !_network_server) return;
 

	
 
	Backup<CompanyByte> cur_company(_current_company, company);
 
	Backup<CompanyByte> cur_company(_current_company, company, FILE_LINE);
 
	Company::Get(company)->ai_instance->Suspend();
 

	
 
	cur_company.Restore();
 
}
 

	
 
/* static */ void AI::KillAll()
 
{
 
	/* It might happen there are no companies .. than we have nothing to loop */
 
	if (Company::GetPoolSize() == 0) return;
 

	
 
	const Company *c;
 
	FOR_ALL_COMPANIES(c) {
 
@@ -192,25 +192,25 @@
 
	if (_networking && !_network_server) {
 
		event->Release();
 
		return;
 
	}
 

	
 
	/* Only AIs can have an event-queue */
 
	if (!Company::IsValidAiID(company)) {
 
		event->Release();
 
		return;
 
	}
 

	
 
	/* Queue the event */
 
	Backup<CompanyByte> cur_company(_current_company, company);
 
	Backup<CompanyByte> cur_company(_current_company, company, FILE_LINE);
 
	AIEventController::InsertEvent(event);
 
	cur_company.Restore();
 

	
 
	event->Release();
 
}
 

	
 
/* static */ void AI::BroadcastNewEvent(AIEvent *event, CompanyID skip_company)
 
{
 
	/* AddRef() and Release() need to be called at least once, so do it here */
 
	event->AddRef();
 

	
 
	/* Clients should ignore events */
 
@@ -238,39 +238,39 @@ void CcAI(const CommandCost &result, Til
 
		AIObject::SetLastCost(result.GetCost());
 
	}
 

	
 
	Company::Get(_current_company)->ai_instance->Continue();
 
}
 

	
 
/* static */ void AI::Save(CompanyID company)
 
{
 
	if (!_networking || _network_server) {
 
		Company *c = Company::GetIfValid(company);
 
		assert(c != NULL && c->ai_instance != NULL);
 

	
 
		Backup<CompanyByte> cur_company(_current_company, company);
 
		Backup<CompanyByte> cur_company(_current_company, company, FILE_LINE);
 
		c->ai_instance->Save();
 
		cur_company.Restore();
 
	} else {
 
		AIInstance::SaveEmpty();
 
	}
 
}
 

	
 
/* static */ void AI::Load(CompanyID company, int version)
 
{
 
	if (!_networking || _network_server) {
 
		Company *c = Company::GetIfValid(company);
 
		assert(c != NULL && c->ai_instance != NULL);
 

	
 
		Backup<CompanyByte> cur_company(_current_company, company);
 
		Backup<CompanyByte> cur_company(_current_company, company, FILE_LINE);
 
		c->ai_instance->Load(version);
 
		cur_company.Restore();
 
	} else {
 
		/* Read, but ignore, the load data */
 
		AIInstance::LoadEmpty();
 
	}
 
}
 

	
 
/* static */ int AI::GetStartNextTime()
 
{
 
	/* Find the first company which doesn't exist yet */
 
	for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) {
src/ai/ai_gui.cpp
Show inline comments
 
@@ -811,25 +811,25 @@ struct AIDebugWindow : public QueryStrin
 
				dirty = true;
 
			}
 

	
 
			/* Do we need a repaint? */
 
			if (dirty) this->SetDirty();
 
			/* Draw company icon only for valid AI companies */
 
			if (!valid) continue;
 

	
 
			byte offset = (i == ai_debug_company) ? 1 : 0;
 
			DrawCompanyIcon(i, button->pos_x + button->current_x / 2 - 7 + offset, this->GetWidget<NWidgetBase>(AID_WIDGET_COMPANY_BUTTON_START + i)->pos_y + 2 + offset);
 
		}
 

	
 
		Backup<CompanyByte> cur_company(_current_company, ai_debug_company);
 
		Backup<CompanyByte> cur_company(_current_company, ai_debug_company, FILE_LINE);
 
		AILog::LogData *log = (AILog::LogData *)AIObject::GetLogPointer();
 
		cur_company.Restore();
 

	
 
		int scroll_count = (log == NULL) ? 0 : log->used;
 
		if (this->vscroll.GetCount() != scroll_count) {
 
			this->vscroll.SetCount(scroll_count);
 

	
 
			/* We need a repaint */
 
			this->SetWidgetDirty(AID_WIDGET_SCROLLBAR);
 
		}
 

	
 
		if (log == NULL) return;
 
@@ -866,25 +866,25 @@ struct AIDebugWindow : public QueryStrin
 
					SetDParam(2, info->GetVersion());
 
				}
 
				break;
 
		}
 
	}
 

	
 
	virtual void DrawWidget(const Rect &r, int widget) const
 
	{
 
		if (ai_debug_company == INVALID_COMPANY) return;
 

	
 
		switch (widget) {
 
			case AID_WIDGET_LOG_PANEL: {
 
				Backup<CompanyByte> cur_company(_current_company, ai_debug_company);
 
				Backup<CompanyByte> cur_company(_current_company, ai_debug_company, FILE_LINE);
 
				AILog::LogData *log = (AILog::LogData *)AIObject::GetLogPointer();
 
				cur_company.Restore();
 
				if (log == NULL) return;
 

	
 
				int y = this->top_offset;
 
				for (int i = this->vscroll.GetPosition(); this->vscroll.IsVisible(i) && i < log->used; i++) {
 
					int pos = (i + log->pos + 1 - log->used + log->count) % log->count;
 
					if (log->lines[pos] == NULL) break;
 

	
 
					TextColour colour;
 
					switch (log->type[pos]) {
 
						case AILog::LOG_SQ_INFO:  colour = TC_BLACK;  break;
 
@@ -905,25 +905,25 @@ struct AIDebugWindow : public QueryStrin
 
					y += this->resize.step_height;
 
				}
 
				break;
 
			}
 
		}
 
	}
 

	
 
	void ChangeToAI(CompanyID show_ai)
 
	{
 
		this->RaiseWidget(ai_debug_company + AID_WIDGET_COMPANY_BUTTON_START);
 
		ai_debug_company = show_ai;
 

	
 
		Backup<CompanyByte> cur_company(_current_company, ai_debug_company);
 
		Backup<CompanyByte> cur_company(_current_company, ai_debug_company, FILE_LINE);
 
		AILog::LogData *log = (AILog::LogData *)AIObject::GetLogPointer();
 
		cur_company.Restore();
 
		this->vscroll.SetCount((log == NULL) ? 0 : log->used);
 

	
 
		this->LowerWidget(ai_debug_company + AID_WIDGET_COMPANY_BUTTON_START);
 
		this->autoscroll = true;
 
		this->last_vscroll_pos = this->vscroll.GetPosition();
 
		this->SetDirty();
 
		/* Close AI settings window to prevent confusion */
 
		DeleteWindowByClass(WC_AI_SETTINGS);
 
	}
 

	
 
@@ -1000,25 +1000,25 @@ struct AIDebugWindow : public QueryStrin
 
			 * was highlighted )*/
 
			if ((_pause_mode & PM_PAUSED_NORMAL) == PM_UNPAUSED && this->highlight_row != -1) {
 
				this->DisableWidget(AID_WIDGET_CONTINUE_BTN);
 
				this->SetWidgetDirty(AID_WIDGET_CONTINUE_BTN);
 
				this->SetWidgetDirty(AID_WIDGET_LOG_PANEL);
 
				this->highlight_row = -1;
 
			}
 
		}
 

	
 
		/* If the log message is related to the active company tab, check the break string */
 
		if (data == ai_debug_company && this->break_check_enabled && !StrEmpty(this->edit_str_buf)) {
 
			/* Get the log instance of the active company */
 
			Backup<CompanyByte> cur_company(_current_company, ai_debug_company);
 
			Backup<CompanyByte> cur_company(_current_company, ai_debug_company, FILE_LINE);
 
			AILog::LogData *log = (AILog::LogData *)AIObject::GetLogPointer();
 

	
 
			if (log != NULL && case_sensitive_break_check?
 
					strstr(log->lines[log->pos], this->edit_str_buf) != 0 :
 
					strcasestr(log->lines[log->pos], this->edit_str_buf) != 0) {
 

	
 
				AI::Suspend(ai_debug_company);
 
				if ((_pause_mode & PM_PAUSED_NORMAL) == PM_UNPAUSED) {
 
					DoCommandP(0, PM_PAUSED_NORMAL, 1, CMD_PAUSE);
 
				}
 

	
 
				/* Make it possible to click on the continue button */
src/aircraft_cmd.cpp
Show inline comments
 
@@ -1195,25 +1195,25 @@ void HandleMissingAircraftOrders(Aircraf
 
	 *    the holding pattern for the first airport, which can cause
 
	 *    the plane to go into an undefined state when building an
 
	 *    airport with the same StationID.
 
	 * 2) we are (still) heading to a (still) valid airport, then we
 
	 *    can continue going there. This can happen when you are
 
	 *    changing the aircraft's orders while in-flight or in for
 
	 *    example a depot. However, when we have a current order to
 
	 *    go to a depot, we have to keep that order so the aircraft
 
	 *    actually stops.
 
	 */
 
	const Station *st = GetTargetAirportIfValid(v);
 
	if (st == NULL) {
 
		Backup<CompanyByte> cur_company(_current_company, v->owner);
 
		Backup<CompanyByte> cur_company(_current_company, v->owner, FILE_LINE);
 
		CommandCost ret = DoCommand(v->tile, v->index, 0, DC_EXEC, CMD_SEND_AIRCRAFT_TO_HANGAR);
 
		cur_company.Restore();
 

	
 
		if (ret.Failed()) CrashAirplane(v);
 
	} else if (!v->current_order.IsType(OT_GOTO_DEPOT)) {
 
		v->current_order.Free();
 
	}
 
}
 

	
 

	
 
TileIndex Aircraft::GetOrderStationLocation(StationID station)
 
{
 
@@ -1501,25 +1501,25 @@ static void AircraftEventHandler_EndTake
 
}
 

	
 
static void AircraftEventHandler_HeliTakeOff(Aircraft *v, const AirportFTAClass *apc)
 
{
 
	v->state = FLYING;
 
	v->UpdateDeltaXY(INVALID_DIR);
 

	
 
	/* get the next position to go to, differs per airport */
 
	AircraftNextAirportPos_and_Order(v);
 

	
 
	/* Send the helicopter to a hangar if needed for replacement */
 
	if (v->NeedsAutomaticServicing()) {
 
		Backup<CompanyByte> cur_company(_current_company, v->owner);
 
		Backup<CompanyByte> cur_company(_current_company, v->owner, FILE_LINE);
 
		DoCommand(v->tile, v->index, DEPOT_SERVICE | DEPOT_LOCATE_HANGAR, DC_EXEC, CMD_SEND_AIRCRAFT_TO_HANGAR);
 
		cur_company.Restore();
 
	}
 
}
 

	
 
static void AircraftEventHandler_Flying(Aircraft *v, const AirportFTAClass *apc)
 
{
 
	Station *st = Station::Get(v->targetairport);
 

	
 
	/* runway busy or not allowed to use this airstation, circle */
 
	if ((apc->flags & (v->subtype == AIR_HELICOPTER ? AirportFTAClass::HELICOPTERS : AirportFTAClass::AIRPLANES)) &&
 
			st->airport.tile != INVALID_TILE &&
 
@@ -1553,25 +1553,25 @@ static void AircraftEventHandler_Flying(
 
	}
 
	v->state = FLYING;
 
	v->pos = apc->layout[v->pos].next_position;
 
}
 

	
 
static void AircraftEventHandler_Landing(Aircraft *v, const AirportFTAClass *apc)
 
{
 
	v->state = ENDLANDING;
 
	AircraftLandAirplane(v);  // maybe crash airplane
 

	
 
	/* check if the aircraft needs to be replaced or renewed and send it to a hangar if needed */
 
	if (v->NeedsAutomaticServicing()) {
 
		Backup<CompanyByte> cur_company(_current_company, v->owner);
 
		Backup<CompanyByte> cur_company(_current_company, v->owner, FILE_LINE);
 
		DoCommand(v->tile, v->index, DEPOT_SERVICE, DC_EXEC, CMD_SEND_AIRCRAFT_TO_HANGAR);
 
		cur_company.Restore();
 
	}
 
}
 

	
 
static void AircraftEventHandler_HeliLanding(Aircraft *v, const AirportFTAClass *apc)
 
{
 
	v->state = HELIENDLANDING;
 
	v->UpdateDeltaXY(INVALID_DIR);
 
}
 

	
 
static void AircraftEventHandler_EndLanding(Aircraft *v, const AirportFTAClass *apc)
src/core/backup_type.hpp
Show inline comments
 
@@ -3,56 +3,68 @@
 
/*
 
 * This file is part of OpenTTD.
 
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @file backup_type.hpp Class for backupping variables and making sure they are restored later. */
 

	
 
#ifndef BACKUP_TYPE_HPP
 
#define BACKUP_TYPE_HPP
 

	
 
#include "../debug.h"
 

	
 
/**
 
 * Class to backup a specific variable and restore it later.
 
 * The variable is not restored automatically, but assertions make sure it is restored.
 
 * You have to call either Trash() or Restore() exactly once.
 
 */
 
template <typename T>
 
struct Backup {
 
	/**
 
	 * Backup variable.
 
	 * @param original Variable to backup.
 
	 * @param file Filename for debug output. Use FILE_LINE macro.
 
	 * @param line Linenumber for debug output. Use FILE_LINE macro.
 
	 */
 
	Backup(T &original) : original(original), valid(true), original_value(original) {}
 
	Backup(T &original, const char * const file, const int line) : original(original), valid(true), original_value(original), file(file), line(line) {}
 

	
 
	/**
 
	 * Backup variable and switch to new value.
 
	 * @param original Variable to backup.
 
	 * @param new_value New value for variable.
 
	 * @param file Filename for debug output. Use FILE_LINE macro.
 
	 * @param line Linenumber for debug output. Use FILE_LINE macro.
 
	 */
 
	template <typename U>
 
	Backup(T &original, const U &new_value) : original(original), valid(true), original_value(original)
 
	Backup(T &original, const U &new_value, const char * const file, const int line) : original(original), valid(true), original_value(original), file(file), line(line)
 
	{
 
		/* Note: We use a separate typename U, so type conversions are handled by assignment operator. */
 
		original = new_value;
 
	}
 

	
 
	/**
 
	 * Check whether the variable was restored on object destruction.
 
	 */
 
	~Backup()
 
	{
 
		/* Check whether restoration was done */
 
		assert(!this->valid);
 
		if (this->valid)
 
		{
 
			/* We cannot assert here, as missing restoration is 'normal' when exceptions are thrown.
 
			 * Exceptions are especially used to abort world generation. */
 
			DEBUG(misc, 0, "%s:%d: Backupped value was not restored!", this->file, this->line);
 
			this->Restore();
 
		}
 
	}
 

	
 
	/**
 
	 * Checks whether the variable was already restored.
 
	 * @return true if variable has already been restored.
 
	 */
 
	bool IsValid() const
 
	{
 
		return this->valid;
 
	}
 

	
 
	/**
 
@@ -120,15 +132,18 @@ struct Backup {
 
	 * @return true if equal
 
	 */
 
	bool Verify() const
 
	{
 
		assert(this->valid);
 
		return this->original_value == this->original;
 
	}
 

	
 
private:
 
	T &original;
 
	bool valid;
 
	T original_value;
 

	
 
	const char * const file;
 
	const int line;
 
};
 

	
 
#endif /* BACKUP_TYPE_HPP */
src/debug.h
Show inline comments
 
@@ -44,24 +44,27 @@
 
	extern int _debug_freetype_level;
 
	extern int _debug_sl_level;
 
	extern int _debug_gamelog_level;
 
	extern int _debug_desync_level;
 
	extern int _debug_console_level;
 

	
 
	void CDECL debug(const char *dbg, const char *format, ...) WARN_FORMAT(2, 3);
 
#endif /* NO_DEBUG_MESSAGES */
 

	
 
void SetDebugString(const char *s);
 
const char *GetDebugString();
 

	
 
/* Shorter form for passing filename and linenumber */
 
#define FILE_LINE __FILE__, __LINE__
 

	
 
/* Used for profiling
 
 *
 
 * Usage:
 
 * TIC();
 
 *   --Do your code--
 
 * TOC("A name", 1);
 
 *
 
 * When you run the TIC() / TOC() multiple times, you can increase the '1'
 
 *  to only display average stats every N values. Some things to know:
 
 *
 
 * for (int i = 0; i < 5; i++) {
 
 *   TIC();
src/disaster_cmd.cpp
Show inline comments
 
@@ -64,35 +64,35 @@ enum DisasterSubType {
 
	ST_BIG_UFO_DESTROYER_SHADOW,
 
	ST_SMALL_SUBMARINE,
 
	ST_BIG_SUBMARINE,
 
};
 

	
 
static void DisasterClearSquare(TileIndex tile)
 
{
 
	if (EnsureNoVehicleOnGround(tile).Failed()) return;
 

	
 
	switch (GetTileType(tile)) {
 
		case MP_RAILWAY:
 
			if (Company::IsHumanID(GetTileOwner(tile))) {
 
				Backup<CompanyByte> cur_company(_current_company, OWNER_WATER);
 
				Backup<CompanyByte> cur_company(_current_company, OWNER_WATER, FILE_LINE);
 
				DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
 
				cur_company.Restore();
 

	
 
				/* update signals in buffer */
 
				UpdateSignalsInBuffer();
 
			}
 
			break;
 

	
 
		case MP_HOUSE: {
 
			Backup<CompanyByte> cur_company(_current_company, OWNER_NONE);
 
			Backup<CompanyByte> cur_company(_current_company, OWNER_NONE, FILE_LINE);
 
			DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
 
			cur_company.Restore();
 
			break;
 
		}
 

	
 
		case MP_TREES:
 
		case MP_CLEAR:
 
			DoClearSquare(tile);
 
			break;
 

	
 
		default:
 
			break;
src/economy.cpp
Show inline comments
 
@@ -296,47 +296,47 @@ int UpdateCompanyRatingAndValue(Company 
 
	return score;
 
}
 

	
 
/*  use INVALID_OWNER as new_owner to delete the company. */
 
void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner)
 
{
 
#ifdef ENABLE_NETWORK
 
	/* In all cases, make spectators of clients connected to that company */
 
	if (_networking) NetworkClientsToSpectators(old_owner);
 
#endif /* ENABLE_NETWORK */
 

	
 
	Town *t;
 
	Backup<CompanyByte> cur_company(_current_company, old_owner);
 
	Backup<CompanyByte> cur_company(_current_company, old_owner, FILE_LINE);
 

	
 
	assert(old_owner != new_owner);
 

	
 
	{
 
		Company *c;
 
		uint i;
 

	
 
		/* See if the old_owner had shares in other companies */
 
		FOR_ALL_COMPANIES(c) {
 
			for (i = 0; i < 4; i++) {
 
				if (c->share_owners[i] == old_owner) {
 
					/* Sell his shares */
 
					CommandCost res = DoCommand(0, c->index, 0, DC_EXEC, CMD_SELL_SHARE_IN_COMPANY);
 
					/* Because we are in a DoCommand, we can't just execute another one and
 
					 *  expect the money to be removed. We need to do it ourself! */
 
					SubtractMoneyFromCompany(res);
 
				}
 
			}
 
		}
 

	
 
		/* Sell all the shares that people have on this company */
 
		Backup<CompanyByte> cur_company2(_current_company);
 
		Backup<CompanyByte> cur_company2(_current_company, FILE_LINE);
 
		c = Company::Get(old_owner);
 
		for (i = 0; i < 4; i++) {
 
			cur_company2.Change(c->share_owners[i]);
 
			if (_current_company != INVALID_OWNER) {
 
				/* Sell the shares */
 
				CommandCost res = DoCommand(0, old_owner, 0, DC_EXEC, CMD_SELL_SHARE_IN_COMPANY);
 
				/* Because we are in a DoCommand, we can't just execute another one and
 
				 *  expect the money to be removed. We need to do it ourself! */
 
				SubtractMoneyFromCompany(res);
 
			}
 
		}
 
		cur_company2.Restore();
 
@@ -544,25 +544,25 @@ static void CompanyCheckBankrupt(Company
 

	
 
			CompanyID c_index = c->index;
 
			delete c;
 
			AI::BroadcastNewEvent(new AIEventCompanyBankrupt(c_index));
 
	}
 
}
 

	
 
static void CompaniesGenStatistics()
 
{
 
	Station *st;
 
	Company *c;
 

	
 
	Backup<CompanyByte> cur_company(_current_company);
 
	Backup<CompanyByte> cur_company(_current_company, FILE_LINE);
 
	FOR_ALL_STATIONS(st) {
 
		cur_company.Change(st->owner);
 
		CommandCost cost(EXPENSES_PROPERTY, _price[PR_STATION_VALUE] >> 1);
 
		SubtractMoneyFromCompany(cost);
 
	}
 
	cur_company.Restore();
 

	
 
	if (!HasBit(1 << 0 | 1 << 3 | 1 << 6 | 1 << 9, _cur_month))
 
		return;
 

	
 
	FOR_ALL_COMPANIES(c) {
 
		memmove(&c->old_economy[1], &c->old_economy[0], sizeof(c->old_economy) - sizeof(c->old_economy[0]));
 
@@ -679,25 +679,25 @@ void RecomputePrices()
 
	}
 

	
 
	SetWindowClassesDirty(WC_BUILD_VEHICLE);
 
	SetWindowClassesDirty(WC_REPLACE_VEHICLE);
 
	SetWindowClassesDirty(WC_VEHICLE_DETAILS);
 
	SetWindowDirty(WC_PAYMENT_RATES, 0);
 
}
 

	
 
static void CompaniesPayInterest()
 
{
 
	const Company *c;
 

	
 
	Backup<CompanyByte> cur_company(_current_company);
 
	Backup<CompanyByte> cur_company(_current_company, FILE_LINE);
 
	FOR_ALL_COMPANIES(c) {
 
		cur_company.Change(c->index);
 

	
 
		/* Over a year the paid interest should be "loan * interest percentage",
 
		 * but... as that number is likely not dividable by 12 (pay each month),
 
		 * one needs to account for that in the monthly fee calculations.
 
		 * To easily calculate what one should pay "this" month, you calculate
 
		 * what (total) should have been paid up to this month and you substract
 
		 * whatever has been paid in the previous months. This will mean one month
 
		 * it'll be a bit more and the other it'll be a bit less than the average
 
		 * monthly fee, but on average it will be exact. */
 
		Money yearly_fee = c->current_loan * _economy.interest_rate / 100;
 
@@ -1018,25 +1018,25 @@ CargoPayment::CargoPayment(Vehicle *fron
 
	current_station(front->last_station_visited)
 
{
 
}
 

	
 
CargoPayment::~CargoPayment()
 
{
 
	if (this->CleaningPool()) return;
 

	
 
	this->front->cargo_payment = NULL;
 

	
 
	if (this->visual_profit == 0) return;
 

	
 
	Backup<CompanyByte> cur_company(_current_company, this->front->owner);
 
	Backup<CompanyByte> cur_company(_current_company, this->front->owner, FILE_LINE);
 

	
 
	SubtractMoneyFromCompany(CommandCost(this->front->GetExpenseType(true), -this->route_profit));
 
	this->front->profit_this_year += this->visual_profit << 8;
 

	
 
	if (this->route_profit != 0) {
 
		if (IsLocalCompany() && !PlayVehicleSound(this->front, VSE_LOAD_UNLOAD)) {
 
			SndPlayVehicleFx(SND_14_CASHTILL, this->front);
 
		}
 

	
 
		ShowCostOrIncomeAnimation(this->front->x_pos, this->front->y_pos, this->front->z_pos, -this->visual_profit);
 
	} else {
 
		ShowFeederIncomeAnimation(this->front->x_pos, this->front->y_pos, this->front->z_pos, this->visual_profit);
 
@@ -1449,25 +1449,25 @@ static void DoAcquireCompany(Company *c)
 
	SetDParam(4, c->bankrupt_value);
 
	AddCompanyNewsItem(STR_MESSAGE_NEWS_FORMAT, NS_COMPANY_MERGER, cni);
 
	AI::BroadcastNewEvent(new AIEventCompanyMerger(ci, _current_company));
 

	
 
	ChangeOwnershipOfCompanyItems(ci, _current_company);
 

	
 
	if (c->bankrupt_value == 0) {
 
		owner = Company::Get(_current_company);
 
		owner->current_loan += c->current_loan;
 
	}
 

	
 
	value = CalculateCompanyValue(c) >> 2;
 
	Backup<CompanyByte> cur_company(_current_company);
 
	Backup<CompanyByte> cur_company(_current_company, FILE_LINE);
 
	for (i = 0; i != 4; i++) {
 
		if (c->share_owners[i] != COMPANY_SPECTATOR) {
 
			cur_company.Change(c->share_owners[i]);
 
			SubtractMoneyFromCompany(CommandCost(EXPENSES_OTHER, -value));
 
		}
 
	}
 
	cur_company.Restore();
 

	
 
	if (c->is_ai) AI::Stop(c->index);
 

	
 
	DeleteCompanyWindows(ci);
 
	InvalidateWindowClassesData(WC_TRAINS_LIST, 0);
src/industry_cmd.cpp
Show inline comments
 
@@ -1034,25 +1034,25 @@ void PlantRandomFarmField(const Industry
 

	
 
/**
 
 * Search callback function for ChopLumberMillTrees
 
 * @param tile to test
 
 * @param user_data that is passed by the caller.  In this case, nothing
 
 * @return the result of the test
 
 */
 
static bool SearchLumberMillTrees(TileIndex tile, void *user_data)
 
{
 
	if (IsTileType(tile, MP_TREES) && GetTreeGrowth(tile) > 2) { ///< 3 and up means all fully grown trees
 
		/* found a tree */
 

	
 
		Backup<CompanyByte> cur_company(_current_company, OWNER_NONE);
 
		Backup<CompanyByte> cur_company(_current_company, OWNER_NONE, FILE_LINE);
 

	
 
		_industry_sound_ctr = 1;
 
		_industry_sound_tile = tile;
 
		SndPlayTileFx(SND_38_CHAINSAW, tile);
 

	
 
		DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
 

	
 
		cur_company.Restore();
 
		return true;
 
	}
 
	return false;
 
}
 
@@ -1363,25 +1363,25 @@ static CommandCost CheckIfIndustryTilesA
 
			} else {
 
				Slope tileh = GetTileSlope(cur_tile, NULL);
 
				refused_slope |= IsSlopeRefused(tileh, its->slopes_refused);
 
			}
 

	
 
			if ((ind_behav & (INDUSTRYBEH_ONLY_INTOWN | INDUSTRYBEH_TOWN1200_MORE)) || // Tile must be a house
 
					((ind_behav & INDUSTRYBEH_ONLY_NEARTOWN) && IsTileType(cur_tile, MP_HOUSE))) { // Tile is allowed to be a house (and it is a house)
 
				if (!IsTileType(cur_tile, MP_HOUSE)) {
 
					return_cmd_error(STR_ERROR_CAN_ONLY_BE_BUILT_IN_TOWNS);
 
				}
 

	
 
				/* Clear the tiles as OWNER_TOWN to not affect town rating, and to not clear protected buildings */
 
				Backup<CompanyByte> cur_company(_current_company, OWNER_TOWN);
 
				Backup<CompanyByte> cur_company(_current_company, OWNER_TOWN, FILE_LINE);
 
				CommandCost ret = DoCommand(cur_tile, 0, 0, DC_NONE, CMD_LANDSCAPE_CLEAR);
 
				cur_company.Restore();
 

	
 
				if (ret.Failed()) return ret;
 
			} else {
 
				/* Clear the tiles, but do not affect town ratings */
 
				CommandCost ret = DoCommand(cur_tile, 0, 0, DC_AUTO | DC_NO_TEST_TOWN_RATING | DC_NO_MODIFY_TOWN_RATING, CMD_LANDSCAPE_CLEAR);
 

	
 
				if (ret.Failed()) return ret;
 
			}
 
		}
 
	} while ((++it)->ti.x != -0x80);
 
@@ -1475,25 +1475,25 @@ static bool CheckIfCanLevelIndustryPlatf
 
	if (TileX(tile) <= 1 || TileY(tile) <= 1) return false;
 
	/* Check that all tiles in area and surrounding are clear
 
	 * this determines that there are no obstructing items */
 
	cur_tile = tile + TileDiffXY(-1, -1);
 
	size_x = max_x + 4;
 
	size_y = max_y + 4;
 

	
 
	/* Check if we don't leave the map */
 
	if (TileX(cur_tile) + size_x >= MapMaxX() || TileY(cur_tile) + size_y >= MapMaxY()) return false;
 

	
 
	/* _current_company is OWNER_NONE for randomly generated industries and in editor, or the company who funded or prospected the industry.
 
	 * Perform terraforming as OWNER_TOWN to disable autoslope and town ratings. */
 
	Backup<CompanyByte> cur_company(_current_company, OWNER_TOWN);
 
	Backup<CompanyByte> cur_company(_current_company, OWNER_TOWN, FILE_LINE);
 

	
 
	TILE_LOOP(tile_walk, size_x, size_y, cur_tile) {
 
		curh = TileHeight(tile_walk);
 
		if (curh != h) {
 
			/* This tile needs terraforming. Check if we can do that without
 
			 *  damaging the surroundings too much. */
 
			if (!CheckCanTerraformSurroundingTiles(tile_walk, h, 0)) {
 
				cur_company.Restore();
 
				return false;
 
			}
 
			/* This is not 100% correct check, but the best we can do without modifying the map.
 
			 *  What is missing, is if the difference in height is more than 1.. */
 
@@ -1779,25 +1779,25 @@ CommandCost CmdBuildIndustry(TileIndex t
 
		return CMD_ERROR;
 
	}
 

	
 
	Randomizer randomizer;
 
	randomizer.SetSeed(p2);
 
	uint16 random_initial_bits = GB(p2, 0, 16);
 
	uint32 random_var8f = randomizer.Next();
 

	
 
	Industry *ind = NULL;
 
	if (_game_mode != GM_EDITOR && _settings_game.construction.raw_industry_construction == 2 && indspec->IsRawIndustry()) {
 
		if (flags & DC_EXEC) {
 
			/* Prospected industries are build as OWNER_TOWN to not e.g. be build on owned land of the founder */
 
			Backup<CompanyByte> cur_company(_current_company, OWNER_TOWN);
 
			Backup<CompanyByte> cur_company(_current_company, OWNER_TOWN, FILE_LINE);
 
			/* Prospecting has a chance to fail, however we cannot guarantee that something can
 
			 * be built on the map, so the chance gets lower when the map is fuller, but there
 
			 * is nothing we can really do about that. */
 
			if (Random() <= indspec->prospecting_chance) {
 
				for (int i = 0; i < 5000; i++) {
 
					/* We should not have more than one Random() in a function call
 
					 * because parameter evaluation order is not guaranteed in the c++ standard
 
					 */
 
					tile = RandomTile();
 
					CommandCost ret = CreateNewIndustryHelper(tile, it, flags, indspec, RandomRange(indspec->num_table), random_var8f, random_initial_bits, cur_company.GetOriginalValue(), &ind);
 
					if (ret.Succeeded()) break;
 
				}
 
@@ -1881,25 +1881,25 @@ static const byte _numof_industry_table[
 
	25,   // low
 
	55,   // normal
 
	80,   // high
 
};
 

	
 
/**
 
 * Try to build a industry on the map.
 
 * @param type IndustryType of the desired industry
 
 * @param try_hard Try very hard to find a place. (Used to place at least one industry per type)
 
 */
 
static void PlaceInitialIndustry(IndustryType type, bool try_hard)
 
{
 
	Backup<CompanyByte> cur_company(_current_company, OWNER_NONE);
 
	Backup<CompanyByte> cur_company(_current_company, OWNER_NONE, FILE_LINE);
 

	
 
	IncreaseGeneratingWorldProgress(GWP_INDUSTRY);
 

	
 
	for (uint i = 0; i < (try_hard ? 10000u : 2000u); i++) {
 
		if (CreateNewIndustry(RandomTile(), type) != NULL) break;
 
	}
 

	
 
	cur_company.Restore();
 
}
 

	
 
/**
 
 * This function will create random industries during game creation.
 
@@ -2405,50 +2405,50 @@ void IndustryDailyLoop()
 
	/* Bits 16-31 of industry_construction_counter contain the number of industries to change/create today,
 
	 * the lower 16 bit are a fractional part that might accumulate over several days until it
 
	 * is sufficient for an industry. */
 
	uint16 change_loop = _economy.industry_daily_change_counter >> 16;
 

	
 
	/* Reset the active part of the counter, just keeping the "factional part" */
 
	_economy.industry_daily_change_counter &= 0xFFFF;
 

	
 
	if (change_loop == 0) {
 
		return;  // Nothing to do? get out
 
	}
 

	
 
	Backup<CompanyByte> cur_company(_current_company, OWNER_NONE);
 
	Backup<CompanyByte> cur_company(_current_company, OWNER_NONE, FILE_LINE);
 

	
 
	/* perform the required industry changes for the day */
 
	for (uint16 j = 0; j < change_loop; j++) {
 
		/* 3% chance that we start a new industry */
 
		if (Chance16(3, 100)) {
 
			MaybeNewIndustry();
 
		} else {
 
			Industry *i = Industry::GetRandom();
 
			if (i != NULL) {
 
				ChangeIndustryProduction(i, false);
 
				SetWindowDirty(WC_INDUSTRY_VIEW, i->index);
 
			}
 
		}
 
	}
 

	
 
	cur_company.Restore();
 

	
 
	/* production-change */
 
	InvalidateWindowData(WC_INDUSTRY_DIRECTORY, 0, 1);
 
}
 

	
 
void IndustryMonthlyLoop()
 
{
 
	Industry *i;
 
	Backup<CompanyByte> cur_company(_current_company, OWNER_NONE);
 
	Backup<CompanyByte> cur_company(_current_company, OWNER_NONE, FILE_LINE);
 

	
 
	FOR_ALL_INDUSTRIES(i) {
 
		UpdateIndustryStatistics(i);
 
		if (i->prod_level == PRODLEVEL_CLOSURE) {
 
			delete i;
 
		} else {
 
			ChangeIndustryProduction(i, true);
 
			SetWindowDirty(WC_INDUSTRY_VIEW, i->index);
 
		}
 
	}
 

	
 
	cur_company.Restore();
src/industry_gui.cpp
Show inline comments
 
@@ -514,25 +514,25 @@ public:
 
		/* We do not need to protect ourselves against "Random Many Industries" in this mode */
 
		const IndustrySpec *indsp = GetIndustrySpec(this->selected_type);
 
		uint32 seed = InteractiveRandom();
 

	
 
		if (_game_mode == GM_EDITOR) {
 
			/* Show error if no town exists at all */
 
			if (Town::GetNumItems() == 0) {
 
				SetDParam(0, indsp->name);
 
				ShowErrorMessage(STR_ERROR_CAN_T_BUILD_HERE, STR_ERROR_MUST_FOUND_TOWN_FIRST, WL_INFO, pt.x, pt.y);
 
				return;
 
			}
 

	
 
			Backup<CompanyByte> cur_company(_current_company, OWNER_NONE);
 
			Backup<CompanyByte> cur_company(_current_company, OWNER_NONE, FILE_LINE);
 
			_generating_world = true;
 
			_ignore_restrictions = true;
 

	
 
			DoCommandP(tile, (InteractiveRandomRange(indsp->num_table) << 8) | this->selected_type, seed,
 
					CMD_BUILD_INDUSTRY | CMD_MSG(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY), &CcBuildIndustry);
 

	
 
			cur_company.Restore();
 
			_ignore_restrictions = false;
 
			_generating_world = false;
 
		} else {
 
			success = DoCommandP(tile, (InteractiveRandomRange(indsp->num_table) << 8) | this->selected_type, seed, CMD_BUILD_INDUSTRY | CMD_MSG(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY));
 
		}
src/misc_cmd.cpp
Show inline comments
 
@@ -221,20 +221,20 @@ CommandCost CmdGiveMoney(TileIndex tile,
 
	if (!_settings_game.economy.give_money) return CMD_ERROR;
 

	
 
	const Company *c = Company::Get(_current_company);
 
	CommandCost amount(EXPENSES_OTHER, min((Money)p1, (Money)20000000LL));
 
	CompanyID dest_company = (CompanyID)p2;
 

	
 
	/* You can only transfer funds that is in excess of your loan */
 
	if (c->money - c->current_loan < amount.GetCost() || amount.GetCost() < 0) return CMD_ERROR;
 
	if (!_networking || !Company::IsValidID(dest_company)) return CMD_ERROR;
 

	
 
	if (flags & DC_EXEC) {
 
		/* Add money to company */
 
		Backup<CompanyByte> cur_company(_current_company, dest_company);
 
		Backup<CompanyByte> cur_company(_current_company, dest_company, FILE_LINE);
 
		SubtractMoneyFromCompany(CommandCost(EXPENSES_OTHER, -amount.GetCost()));
 
		cur_company.Restore();
 
	}
 

	
 
	/* Subtract money from local-company */
 
	return amount;
 
}
src/openttd.cpp
Show inline comments
 
@@ -1207,25 +1207,25 @@ void StateGameLoop()
 
	} else {
 
		if (_debug_desync_level > 2 && _date_fract == 0 && (_date & 0x1F) == 0) {
 
			/* Save the desync savegame if needed. */
 
			char name[MAX_PATH];
 
			snprintf(name, lengthof(name), "dmp_cmds_%08x_%08x.sav", _settings_game.game_creation.generation_seed, _date);
 
			SaveOrLoad(name, SL_SAVE, AUTOSAVE_DIR);
 
		}
 

	
 
		CheckCaches();
 

	
 
		/* All these actions has to be done from OWNER_NONE
 
		 *  for multiplayer compatibility */
 
		Backup<CompanyByte> cur_company(_current_company, OWNER_NONE);
 
		Backup<CompanyByte> cur_company(_current_company, OWNER_NONE, FILE_LINE);
 

	
 
		AnimateAnimatedTiles();
 
		IncreaseDate();
 
		RunTileLoop();
 
		CallVehicleTicks();
 
		CallLandscapeTick();
 
		ClearStorageChanges(true);
 

	
 
		AI::GameLoop();
 

	
 
		CallWindowTickEvent();
 
		NewsLoop();
src/rail_cmd.cpp
Show inline comments
 
@@ -633,25 +633,25 @@ bool FloodHalftile(TileIndex t)
 

	
 
	bool flooded = false;
 
	if (GetRailGroundType(t) == RAIL_GROUND_WATER) return flooded;
 

	
 
	Slope tileh = GetTileSlope(t, NULL);
 
	TrackBits rail_bits = GetTrackBits(t);
 

	
 
	if (IsSlopeWithOneCornerRaised(tileh)) {
 
		TrackBits lower_track = CornerToTrackBits(OppositeCorner(GetHighestSlopeCorner(tileh)));
 

	
 
		TrackBits to_remove = lower_track & rail_bits;
 
		if (to_remove != 0) {
 
			Backup<CompanyByte> cur_company(_current_company, OWNER_WATER);
 
			Backup<CompanyByte> cur_company(_current_company, OWNER_WATER, FILE_LINE);
 
			flooded = DoCommand(t, 0, FIND_FIRST_BIT(to_remove), DC_EXEC, CMD_REMOVE_SINGLE_RAIL).Succeeded();
 
			cur_company.Restore();
 
			if (!flooded) return flooded; // not yet floodable
 
			rail_bits = rail_bits & ~to_remove;
 
			if (rail_bits == 0) {
 
				MakeShore(t);
 
				MarkTileDirtyByTile(t);
 
				return flooded;
 
			}
 
		}
 

	
 
		if (IsNonContinuousFoundation(GetRailFoundation(tileh, rail_bits))) {
src/roadveh_cmd.cpp
Show inline comments
 
@@ -1151,25 +1151,25 @@ static Trackdir FollowPreviousRoadVehicl
 
}
 

	
 
/**
 
 * Can a tram track build without destruction on the given tile?
 
 * @param c the company that would be building the tram tracks
 
 * @param t the tile to build on.
 
 * @param r the road bits needed.
 
 * @return true when a track track can be build on 't'
 
 */
 
static bool CanBuildTramTrackOnTile(CompanyID c, TileIndex t, RoadBits r)
 
{
 
	/* The 'current' company is not necessarily the owner of the vehicle. */
 
	Backup<CompanyByte> cur_company(_current_company, c);
 
	Backup<CompanyByte> cur_company(_current_company, c, FILE_LINE);
 

	
 
	CommandCost ret = DoCommand(t, ROADTYPE_TRAM << 4 | r, 0, DC_NONE, CMD_BUILD_ROAD);
 

	
 
	cur_company.Restore();
 
	return ret.Succeeded();
 
}
 

	
 
static bool IndividualRoadVehicleController(RoadVehicle *v, const RoadVehicle *prev)
 
{
 
	if (v->overtaking != 0)  {
 
		if (IsTileType(v->tile, MP_STATION)) {
 
			/* Force us to be not overtaking! */
src/saveload/afterload.cpp
Show inline comments
 
@@ -1562,25 +1562,25 @@ bool AfterLoadGame()
 
		for (TileIndex t = 0; t < map_size; t++) {
 
			/* skip oil rigs at borders! */
 
			if ((IsTileType(t, MP_WATER) || IsBuoyTile(t)) &&
 
					(TileX(t) == 0 || TileY(t) == 0 || TileX(t) == MapMaxX() - 1 || TileY(t) == MapMaxY() - 1)) {
 
				/* Some version 86 savegames have wrong water class at map borders (under buoy, or after removing buoy).
 
				 * This conversion has to be done before buoys with invalid owner are removed. */
 
				SetWaterClass(t, WATER_CLASS_SEA);
 
			}
 

	
 
			if (IsBuoyTile(t) || IsDriveThroughStopTile(t) || IsTileType(t, MP_WATER)) {
 
				Owner o = GetTileOwner(t);
 
				if (o < MAX_COMPANIES && !Company::IsValidID(o)) {
 
					Backup<CompanyByte> cur_company(_current_company, o);
 
					Backup<CompanyByte> cur_company(_current_company, o, FILE_LINE);
 
					ChangeTileOwner(t, o, INVALID_OWNER);
 
					cur_company.Restore();
 
				}
 
				if (IsBuoyTile(t)) {
 
					/* reset buoy owner to OWNER_NONE in the station struct
 
					 * (even if it is owned by active company) */
 
					Waypoint::GetByTile(t)->owner = OWNER_NONE;
 
				}
 
			} else if (IsTileType(t, MP_ROAD)) {
 
				/* works for all RoadTileType */
 
				for (RoadType rt = ROADTYPE_ROAD; rt < ROADTYPE_END; rt++) {
 
					/* update even non-existing road types to update tile owner too */
src/town_cmd.cpp
Show inline comments
 
@@ -507,25 +507,25 @@ static void TileLoop_Town(TileIndex tile
 
			t->new_act_pass += MoveGoodsToStation(CT_PASSENGERS, amt, ST_TOWN, t->index, stations.GetStations());
 
		}
 

	
 
		if (GB(r, 8, 8) < hs->mail_generation) {
 
			uint amt = GB(r, 8, 8) / 8 + 1;
 

	
 
			if (_economy.fluct <= 0) amt = (amt + 1) >> 1;
 
			t->new_max_mail += amt;
 
			t->new_act_mail += MoveGoodsToStation(CT_MAIL, amt, ST_TOWN, t->index, stations.GetStations());
 
		}
 
	}
 

	
 
	Backup<CompanyByte> cur_company(_current_company, OWNER_TOWN);
 
	Backup<CompanyByte> cur_company(_current_company, OWNER_TOWN, FILE_LINE);
 

	
 
	if ((hs->building_flags & BUILDING_HAS_1_TILE) &&
 
			HasBit(t->flags, TOWN_IS_FUNDED) &&
 
			CanDeleteHouse(tile) &&
 
			GetHouseAge(tile) >= hs->minimum_life &&
 
			--t->time_until_rebuild == 0) {
 
		t->time_until_rebuild = GB(r, 16, 8) + 192;
 

	
 
		ClearTownHouse(t, tile);
 

	
 
		/* Rebuild with another house? */
 
		if (GB(r, 24, 8) >= 12) BuildTownHouse(t, tile);
 
@@ -1288,25 +1288,25 @@ static bool GrowTown(Town *t)
 
		{-1,  0},
 
		{ 0,  2},
 
		{ 2,  0},
 
		{ 0, -2},
 
		{-1, -1},
 
		{-2,  2},
 
		{ 2,  2},
 
		{ 2, -2},
 
		{ 0,  0}
 
	};
 

	
 
	/* Current "company" is a town */
 
	Backup<CompanyByte> cur_company(_current_company, OWNER_TOWN);
 
	Backup<CompanyByte> cur_company(_current_company, OWNER_TOWN, FILE_LINE);
 

	
 
	TileIndex tile = t->xy; // The tile we are working with ATM
 

	
 
	/* Find a road that we can base the construction on. */
 
	const TileIndexDiffC *ptr;
 
	for (ptr = _town_coord_mod; ptr != endof(_town_coord_mod); ++ptr) {
 
		if (GetTownRoadBits(tile) != ROAD_NONE) {
 
			int r = GrowTownAtRoad(t, tile);
 
			cur_company.Restore();
 
			return r != 0;
 
		}
 
		tile = TILE_ADD(tile, ToTileIndexDiff(*ptr));
 
@@ -2374,25 +2374,25 @@ static bool DoBuildStatueOfCompany(TileI
 
{
 
	/* Statues can be build on slopes, just like houses. Only the steep slopes is a no go. */
 
	if (IsSteepSlope(GetTileSlope(tile, NULL))) return false;
 
	/* Don't build statues under bridges. */
 
	if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) return false;
 

	
 
	if (!IsTileType(tile, MP_HOUSE) &&
 
			!IsTileType(tile, MP_CLEAR) &&
 
			!IsTileType(tile, MP_TREES)) {
 
		return false;
 
	}
 

	
 
	Backup<CompanyByte> cur_company(_current_company, OWNER_NONE);
 
	Backup<CompanyByte> cur_company(_current_company, OWNER_NONE, FILE_LINE);
 
	CommandCost r = DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
 
	cur_company.Restore();
 

	
 
	if (r.Failed()) return false;
 

	
 
	MakeStatue(tile, _current_company, town_id);
 
	MarkTileDirtyByTile(tile);
 

	
 
	return true;
 
}
 

	
 
/**
src/vehicle.cpp
Show inline comments
 
@@ -764,25 +764,25 @@ void CallVehicleTicks()
 
				if (v->type == VEH_AIRCRAFT && v->subtype != AIR_HELICOPTER) continue;
 
				if (v->type == VEH_ROAD && !RoadVehicle::From(v)->IsRoadVehFront()) continue;
 

	
 
				v->motion_counter += v->cur_speed;
 
				/* Play a running sound if the motion counter passes 256 (Do we not skip sounds?) */
 
				if (GB(v->motion_counter, 0, 8) < v->cur_speed) PlayVehicleSound(v, VSE_RUNNING);
 

	
 
				/* Play an alterate running sound every 16 ticks */
 
				if (GB(v->tick_counter, 0, 4) == 0) PlayVehicleSound(v, v->cur_speed > 0 ? VSE_RUNNING_16 : VSE_STOPPED_16);
 
		}
 
	}
 

	
 
	Backup<CompanyByte> cur_company(_current_company);
 
	Backup<CompanyByte> cur_company(_current_company, FILE_LINE);
 
	for (AutoreplaceMap::iterator it = _vehicles_to_autoreplace.Begin(); it != _vehicles_to_autoreplace.End(); it++) {
 
		v = it->first;
 
		/* Autoreplace needs the current company set as the vehicle owner */
 
		cur_company.Change(v->owner);
 

	
 
		/* Start vehicle if we stopped them in VehicleEnteredDepotThisTick()
 
		 * We need to stop them between VehicleEnteredDepotThisTick() and here or we risk that
 
		 * they are already leaving the depot again before being replaced. */
 
		if (it->second) v->vehstatus &= ~VS_STOPPED;
 

	
 
		/* Store the position of the effect as the vehicle pointer will become invalid later */
 
		int x = v->x_pos;
 
@@ -1103,25 +1103,25 @@ void VehicleEnterDepot(Vehicle *v)
 
		v->current_order.MakeDummy();
 

	
 
		/* Test whether we are heading for this depot. If not, do nothing.
 
		 * Note: The target depot for nearest-/manual-depot-orders is only updated on junctions, but we want to accept every depot. */
 
		if ((t.GetDepotOrderType() & ODTFB_PART_OF_ORDERS) &&
 
				real_order != NULL && !(real_order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) &&
 
				(v->type == VEH_AIRCRAFT ? t.GetDestination() != GetStationIndex(v->tile) : v->dest_tile != v->tile)) {
 
			/* We are heading for another depot, keep driving. */
 
			return;
 
		}
 

	
 
		if (t.IsRefit()) {
 
			Backup<CompanyByte> cur_company(_current_company, v->owner);
 
			Backup<CompanyByte> cur_company(_current_company, v->owner, FILE_LINE);
 
			CommandCost cost = DoCommand(v->tile, v->index, t.GetRefitCargo() | t.GetRefitSubtype() << 8, DC_EXEC, GetCmdRefitVeh(v));
 
			cur_company.Restore();
 

	
 
			if (cost.Failed()) {
 
				_vehicles_to_autoreplace[v] = false;
 
				if (v->owner == _local_company) {
 
					/* Notify the user that we stopped the vehicle */
 
					SetDParam(0, v->index);
 
					AddVehicleNewsItem(STR_NEWS_ORDER_REFIT_FAILED, NS_ADVICE, v->index);
 
				}
 
			} else if (v->owner == _local_company && cost.GetCost() != 0) {
 
				ShowCostOrIncomeAnimation(v->x_pos, v->y_pos, v->z_pos, cost.GetCost());
src/water_cmd.cpp
Show inline comments
 
@@ -873,25 +873,25 @@ static FloodingBehaviour GetFloodingBeha
 
	}
 
}
 

	
 
/**
 
 * Floods a tile.
 
 */
 
void DoFloodTile(TileIndex target)
 
{
 
	assert(!IsTileType(target, MP_WATER));
 

	
 
	bool flooded = false; // Will be set to true if something is changed.
 

	
 
	Backup<CompanyByte> cur_company(_current_company, OWNER_WATER);
 
	Backup<CompanyByte> cur_company(_current_company, OWNER_WATER, FILE_LINE);
 

	
 
	Slope tileh = GetTileSlope(target, NULL);
 
	if (tileh != SLOPE_FLAT) {
 
		/* make coast.. */
 
		switch (GetTileType(target)) {
 
			case MP_RAILWAY: {
 
				if (!IsPlainRail(target)) break;
 
				FloodVehicles(target);
 
				flooded = FloodHalftile(target);
 
				break;
 
			}
 

	
 
@@ -933,25 +933,25 @@ void DoFloodTile(TileIndex target)
 
		/* update signals if needed */
 
		UpdateSignalsInBuffer();
 
	}
 

	
 
	cur_company.Restore();
 
}
 

	
 
/**
 
 * Drys a tile up.
 
 */
 
static void DoDryUp(TileIndex tile)
 
{
 
	Backup<CompanyByte> cur_company(_current_company, OWNER_WATER);
 
	Backup<CompanyByte> cur_company(_current_company, OWNER_WATER, FILE_LINE);
 

	
 
	switch (GetTileType(tile)) {
 
		case MP_RAILWAY:
 
			assert(IsPlainRail(tile));
 
			assert(GetRailGroundType(tile) == RAIL_GROUND_WATER);
 

	
 
			RailGroundType new_ground;
 
			switch (GetTrackBits(tile)) {
 
				case TRACK_BIT_UPPER: new_ground = RAIL_GROUND_FENCE_HORIZ1; break;
 
				case TRACK_BIT_LOWER: new_ground = RAIL_GROUND_FENCE_HORIZ2; break;
 
				case TRACK_BIT_LEFT:  new_ground = RAIL_GROUND_FENCE_VERT1;  break;
 
				case TRACK_BIT_RIGHT: new_ground = RAIL_GROUND_FENCE_VERT2;  break;
0 comments (0 inline, 0 general)