Changeset - r13024:48c81d0b078a
[Not reviewed]
master
! ! !
frosch - 15 years ago 2009-09-13 19:15:59
frosch@openttd.org
(svn r17532) -Codechange: Rename several Invalidate functions to SetDirty for more consistency and distinguishability.
61 files changed with 323 insertions and 323 deletions:
0 comments (0 inline, 0 general)
src/ai/ai_gui.cpp
Show inline comments
 
@@ -144,25 +144,25 @@ struct AIListWindow : public Window {
 
		}
 
	}
 

	
 
	void ChangeAI()
 
	{
 
		if (this->selected == -1) {
 
			AIConfig::GetConfig(slot)->ChangeAI(NULL);
 
		} else {
 
			AIInfoList::const_iterator it = this->ai_info_list->begin();
 
			for (int i = 0; i < this->selected; i++) it++;
 
			AIConfig::GetConfig(slot)->ChangeAI((*it).second->GetName(), (*it).second->GetVersion());
 
		}
 
		InvalidateWindow(WC_GAME_OPTIONS, 0);
 
		SetWindowDirty(WC_GAME_OPTIONS, 0);
 
	}
 

	
 
	virtual void OnClick(Point pt, int widget)
 
	{
 
		switch (widget) {
 
			case AIL_WIDGET_LIST: { // Select one of the AIs
 
				int sel = (pt.y - this->nested_array[AIL_WIDGET_LIST]->pos_y) / this->line_height + this->vscroll.GetPosition() - 1;
 
				if (sel < (int)this->ai_info_list->size()) {
 
					this->selected = sel;
 
					this->SetDirty();
 
				}
 
				break;
 
@@ -758,42 +758,42 @@ struct AIDebugWindow : public Window {
 
		}
 

	
 
		CompanyID old_company = _current_company;
 
		_current_company = ai_debug_company;
 
		AILog::LogData *log = (AILog::LogData *)AIObject::GetLogPointer();
 
		_current_company = old_company;
 

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

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

	
 
		if (log == NULL) return;
 

	
 
		/* Detect when the user scrolls the window. Enable autoscroll when the
 
		 * bottom-most line becomes visible. */
 
		if (this->last_vscroll_pos != this->vscroll.GetPosition()) {
 
			this->autoscroll = this->vscroll.GetPosition() >= log->used - this->vscroll.GetCapacity();
 
		}
 
		if (this->autoscroll) {
 
			int scroll_pos = max(0, log->used - this->vscroll.GetCapacity());
 
			if (scroll_pos != this->vscroll.GetPosition()) {
 
				this->vscroll.SetPosition(scroll_pos);
 

	
 
				/* We need a repaint */
 
				this->InvalidateWidget(AID_WIDGET_SCROLLBAR);
 
				this->InvalidateWidget(AID_WIDGET_LOG_PANEL);
 
				this->SetWidgetDirty(AID_WIDGET_SCROLLBAR);
 
				this->SetWidgetDirty(AID_WIDGET_LOG_PANEL);
 
			}
 
		}
 
		this->last_vscroll_pos = this->vscroll.GetPosition();
 

	
 
	}
 

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

	
 
		switch (widget) {
 
			case AID_WIDGET_NAME_TEXT: {
src/aircraft_cmd.cpp
Show inline comments
 
@@ -424,25 +424,25 @@ CommandCost CmdBuildAircraft(TileIndex t
 
			w->cur_image = SPR_ROTOR_STOPPED;
 
			w->random_bits = VehicleRandomBits();
 
			/* Use rotor's air.state to store the rotor animation frame */
 
			w->state = HRS_ROTOR_STOPPED;
 
			w->UpdateDeltaXY(INVALID_DIR);
 

	
 
			u->SetNext(w);
 
			VehicleMove(w, false);
 
		}
 

	
 
		InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
 
		InvalidateWindowClassesData(WC_AIRCRAFT_LIST, 0);
 
		InvalidateWindow(WC_COMPANY, v->owner);
 
		SetWindowDirty(WC_COMPANY, v->owner);
 
		if (IsLocalCompany())
 
			InvalidateAutoreplaceWindow(v->engine_type, v->group_id); // updates the replace Aircraft window
 

	
 
		Company::Get(_current_company)->num_engines[p1]++;
 
	}
 

	
 
	return value;
 
}
 

	
 

	
 
/** Sell an aircraft.
 
 * @param tile unused
 
@@ -571,54 +571,54 @@ CommandCost CmdRefitAircraft(TileIndex t
 
	if (flags & DC_EXEC) {
 
		v->cargo_cap = pass;
 

	
 
		Vehicle *u = v->Next();
 
		uint mail = IsCargoInClass(new_cid, CC_PASSENGERS) ? avi->mail_capacity : 0;
 
		u->cargo_cap = mail;
 
		v->cargo.Truncate(v->cargo_type == new_cid ? pass : 0);
 
		u->cargo.Truncate(v->cargo_type == new_cid ? mail : 0);
 
		v->cargo_type = new_cid;
 
		v->cargo_subtype = new_subtype;
 
		v->colourmap = PAL_NONE; // invalidate vehicle colour map
 
		v->InvalidateNewGRFCacheOfChain();
 
		InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 
		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
 
		SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
 
		SetWindowDirty(WC_VEHICLE_DEPOT, v->tile);
 
		InvalidateWindowClassesData(WC_AIRCRAFT_LIST, 0);
 
	}
 

	
 
	return cost;
 
}
 

	
 

	
 
static void CheckIfAircraftNeedsService(Aircraft *v)
 
{
 
	if (Company::Get(v->owner)->settings.vehicle.servint_aircraft == 0 || !v->NeedsAutomaticServicing()) return;
 
	if (v->IsInDepot()) {
 
		VehicleServiceInDepot(v);
 
		return;
 
	}
 

	
 
	const Station *st = Station::Get(v->current_order.GetDestination());
 

	
 
	assert(st != NULL);
 

	
 
	/* only goto depot if the target airport has terminals (eg. it is airport) */
 
	if (st->airport_tile != INVALID_TILE && st->Airport()->terminals != NULL) {
 
//		printf("targetairport = %d, st->index = %d\n", v->targetairport, st->index);
 
//		v->targetairport = st->index;
 
		v->current_order.MakeGoToDepot(st->index, ODTFB_SERVICE);
 
		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
		SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
	} else if (v->current_order.IsType(OT_GOTO_DEPOT)) {
 
		v->current_order.MakeDummy();
 
		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
		SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
	}
 
}
 

	
 
Money Aircraft::GetRunningCost() const
 
{
 
	return GetVehicleProperty(this, 0x0E, AircraftVehInfo(this->engine_type)->running_cost) * _price.aircraft_running;
 
}
 

	
 
void Aircraft::OnNewDay()
 
{
 
	if (!this->IsNormalAircraft()) return;
 

	
 
@@ -630,26 +630,26 @@ void Aircraft::OnNewDay()
 
	AgeVehicle(this);
 
	CheckIfAircraftNeedsService(this);
 

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

	
 
	CommandCost cost(EXPENSES_AIRCRAFT_RUN, this->GetRunningCost() * this->running_ticks / (DAYS_IN_YEAR * DAY_TICKS));
 

	
 
	this->profit_this_year -= cost.GetCost();
 
	this->running_ticks = 0;
 

	
 
	SubtractMoneyFromCompanyFract(this->owner, cost);
 

	
 
	InvalidateWindow(WC_VEHICLE_DETAILS, this->index);
 
	InvalidateWindowClasses(WC_AIRCRAFT_LIST);
 
	SetWindowDirty(WC_VEHICLE_DETAILS, this->index);
 
	SetWindowClassesDirty(WC_AIRCRAFT_LIST);
 
}
 

	
 
static void HelicopterTickHandler(Aircraft *v)
 
{
 
	Aircraft *u = v->Next()->Next();
 

	
 
	if (u->vehstatus & VS_HIDDEN) return;
 

	
 
	/* if true, helicopter rotors do not rotate. This should only be the case if a helicopter is
 
	 * loading/unloading at a terminal or stopped */
 
	if (v->current_order.IsType(OT_LOADING) || (v->vehstatus & VS_STOPPED)) {
 
		if (u->cur_speed != 0) {
 
@@ -807,25 +807,25 @@ static int UpdateAircraftSpeed(Aircraft 
 
		speed_limit = v->cur_speed - max(1, ((v->cur_speed * v->cur_speed) / 16384) / _settings_game.vehicle.plane_speed);
 
	}
 

	
 
	spd = min(v->cur_speed + (spd >> 8) + (v->subspeed < t), speed_limit);
 

	
 
	/* adjust speed for broken vehicles */
 
	if (v->vehstatus & VS_AIRCRAFT_BROKEN) spd = min(spd, SPEED_LIMIT_BROKEN);
 

	
 
	/* updates statusbar only if speed have changed to save CPU time */
 
	if (spd != v->cur_speed) {
 
		v->cur_speed = spd;
 
		if (_settings_client.gui.vehicle_speed)
 
			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
			SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
	}
 

	
 
	/* Adjust distance moved by plane speed setting */
 
	if (_settings_game.vehicle.plane_speed > 1) spd /= _settings_game.vehicle.plane_speed;
 

	
 
	if (!(v->direction & 1)) spd = spd * 3 / 4;
 

	
 
	spd += v->progress;
 
	v->progress = (byte)spd;
 
	return spd >> 8;
 
}
 

	
 
@@ -1210,26 +1210,26 @@ static bool HandleCrashedAircraft(Aircra
 

	
 
	return true;
 
}
 

	
 
static void HandleBrokenAircraft(Aircraft *v)
 
{
 
	if (v->breakdown_ctr != 1) {
 
		v->breakdown_ctr = 1;
 
		v->vehstatus |= VS_AIRCRAFT_BROKEN;
 

	
 
		if (v->breakdowns_since_last_service != 255)
 
			v->breakdowns_since_last_service++;
 
		InvalidateWindow(WC_VEHICLE_VIEW, v->index);
 
		InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 
		SetWindowDirty(WC_VEHICLE_VIEW, v->index);
 
		SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
 
	}
 
}
 

	
 

	
 
static void HandleAircraftSmoke(Aircraft *v)
 
{
 
	static const struct {
 
		int8 x;
 
		int8 y;
 
	} smoke_pos[] = {
 
		{  5,  5 },
 
		{  6,  0 },
 
@@ -1307,25 +1307,25 @@ void Aircraft::MarkDirty()
 
{
 
	this->UpdateViewport(false, false);
 
	if (this->subtype == AIR_HELICOPTER) this->Next()->Next()->cur_image = GetRotorImage(this);
 
}
 

	
 
static void CrashAirplane(Aircraft *v)
 
{
 
	v->vehstatus |= VS_CRASHED;
 
	v->crashed_counter = 0;
 

	
 
	CreateEffectVehicleRel(v, 4, 4, 8, EV_EXPLOSION_LARGE);
 

	
 
	InvalidateWindow(WC_VEHICLE_VIEW, v->index);
 
	SetWindowDirty(WC_VEHICLE_VIEW, v->index);
 

	
 
	uint amt = 2;
 
	if (IsCargoInClass(v->cargo_type, CC_PASSENGERS)) amt += v->cargo.Count();
 
	SetDParam(0, amt);
 

	
 
	v->cargo.Truncate(0);
 
	v->Next()->cargo.Truncate(0);
 
	const Station *st = GetTargetAirportIfValid(v);
 
	StringID newsitem;
 
	AIEventVehicleCrashed::CrashReason crash_reason;
 
	if (st == NULL) {
 
		newsitem = STR_NEWS_PLANE_CRASH_OUT_OF_FUEL;
 
@@ -1430,25 +1430,25 @@ void AircraftLeaveHangar(Aircraft *v)
 

	
 
		/* Rotor blades */
 
		u = u->Next();
 
		if (u != NULL) {
 
			u->vehstatus &= ~VS_HIDDEN;
 
			u->cur_speed = 80;
 
		}
 
	}
 

	
 
	VehicleServiceInDepot(v);
 
	SetAircraftPosition(v, v->x_pos, v->y_pos, v->z_pos);
 
	InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
 
	InvalidateWindowClasses(WC_AIRCRAFT_LIST);
 
	SetWindowClassesDirty(WC_AIRCRAFT_LIST);
 
}
 

	
 
/** Checks if an aircraft should head towards a hangar because it needs replacement
 
 * @param *v the vehicle to test
 
 * @return true if the aircraft should head towards a hangar
 
 */
 
static inline bool CheckSendAircraftToHangarForReplacement(const Vehicle *v)
 
{
 
	EngineID new_engine;
 
	Company *c = Company::Get(v->owner);
 

	
 
	if (VehicleHasDepotOrders(v)) return false; // The aircraft will end up in the hangar eventually on it's own
 
@@ -1541,25 +1541,25 @@ static void AircraftEventHandler_AtTermi
 
{
 
	/* if we just arrived, execute EnterTerminal first */
 
	if (v->previous_pos != v->pos) {
 
		AircraftEventHandler_EnterTerminal(v, apc);
 
		/* on an airport with helipads, a helicopter will always land there
 
		 * and get serviced at the same time - setting */
 
		if (_settings_game.order.serviceathelipad) {
 
			if (v->subtype == AIR_HELICOPTER && apc->helipads != NULL) {
 
				/* an exerpt of ServiceAircraft, without the invisibility stuff */
 
				v->date_of_last_service = _date;
 
				v->breakdowns_since_last_service = 0;
 
				v->reliability = Engine::Get(v->engine_type)->reliability;
 
				InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 
				SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
 
			}
 
		}
 
		return;
 
	}
 

	
 
	if (v->current_order.IsType(OT_NOTHING)) return;
 

	
 
	/* if the block of the next position is busy, stay put */
 
	if (AirportHasBlock(v, &apc->layout[v->pos], apc)) return;
 

	
 
	/* airport-road is free. We either have to go to another airport, or to the hangar
 
	 * ---> start moving */
src/bridge_gui.cpp
Show inline comments
 
@@ -112,26 +112,26 @@ private:
 
					CMD_BUILD_BRIDGE | CMD_MSG(STR_ERROR_CAN_T_BUILD_BRIDGE_HERE), CcBuildBridge);
 
	}
 

	
 
	/** Sort the builable bridges */
 
	void SortBridgeList()
 
	{
 
		this->bridges->Sort();
 

	
 
		/* Display the current sort variant */
 
		this->nested_array[BBSW_DROPDOWN_CRITERIA]->widget_data = this->sorter_names[this->bridges->SortType()];
 

	
 
		/* Set the modified widgets dirty */
 
		this->InvalidateWidget(BBSW_DROPDOWN_CRITERIA);
 
		this->InvalidateWidget(BBSW_BRIDGE_LIST);
 
		this->SetWidgetDirty(BBSW_DROPDOWN_CRITERIA);
 
		this->SetWidgetDirty(BBSW_BRIDGE_LIST);
 
	}
 

	
 
public:
 
	BuildBridgeWindow(const WindowDesc *desc, TileIndex start, TileIndex end, uint32 br_type, GUIBridgeList *bl) : Window(),
 
		start_tile(start),
 
		end_tile(end),
 
		type(br_type),
 
		bridges(bl)
 
	{
 
		this->CreateNestedTree(desc);
 
		/* Change the data, or the caption of the gui. Set it to road or rail, accordingly. */
 
		this->nested_array[BBSW_CAPTION]->widget_data = (GB(this->type, 15, 2) == TRANSPORT_ROAD) ? STR_SELECT_ROAD_BRIDGE_CAPTION : STR_SELECT_RAIL_BRIDGE_CAPTION;
src/cheat_gui.cpp
Show inline comments
 
@@ -58,25 +58,25 @@ static int32 ClickChangeCompanyCheat(int
 
		p1 += p2;
 
	}
 

	
 
	return _local_company;
 
}
 

	
 
/**
 
 * @param p1 new value
 
 * @param p2 unused
 
 */
 
static int32 ClickSetProdCheat(int32 p1, int32 p2)
 
{
 
	InvalidateWindowClasses(WC_INDUSTRY_VIEW);
 
	SetWindowClassesDirty(WC_INDUSTRY_VIEW);
 
	return p1;
 
}
 

	
 
/**
 
 * @param p1 new climate
 
 * @param p2 unused
 
 */
 
static int32 ClickChangeClimateCheat(int32 p1, int32 p2)
 
{
 
	if (p1 == -1) p1 = 3;
 
	if (p1 ==  4) p1 = 0;
 
	_settings_game.game_creation.landscape = p1;
 
@@ -95,25 +95,25 @@ extern void EnginesMonthlyLoop();
 
 * @param p1 unused
 
 * @param p2 1 (increase) or -1 (decrease)
 
 */
 
static int32 ClickChangeDateCheat(int32 p1, int32 p2)
 
{
 
	YearMonthDay ymd;
 
	ConvertDateToYMD(_date, &ymd);
 

	
 
	if ((ymd.year == MIN_YEAR && p2 == -1) || (ymd.year == MAX_YEAR && p2 == 1)) return _cur_year;
 

	
 
	SetDate(ConvertYMDToDate(_cur_year + p2, ymd.month, ymd.day));
 
	EnginesMonthlyLoop();
 
	InvalidateWindow(WC_STATUS_BAR, 0);
 
	SetWindowDirty(WC_STATUS_BAR, 0);
 
	InvalidateWindowClassesData(WC_BUILD_STATION, 0);
 
	ResetSignalVariant();
 
	return _cur_year;
 
}
 

	
 
typedef int32 CheckButtonClick(int32, int32);
 

	
 
struct CheatEntry {
 
	VarType type;          ///< type of selector
 
	StringID str;          ///< string with descriptive text
 
	void *variable;        ///< pointer to the variable
 
	bool *been_used;       ///< has this cheat been used before?
src/company_cmd.cpp
Show inline comments
 
@@ -140,26 +140,26 @@ bool IsValidCompanyManagerFace(CompanyMa
 
			default: break;
 
		}
 
		if (!AreCompanyManagerFaceBitsValid(cmf, cmfv, ge)) return false;
 
	}
 

	
 
	return true;
 
}
 

	
 
void InvalidateCompanyWindows(const Company *company)
 
{
 
	CompanyID cid = company->index;
 

	
 
	if (cid == _local_company) InvalidateWindow(WC_STATUS_BAR, 0);
 
	InvalidateWindow(WC_FINANCES, cid);
 
	if (cid == _local_company) SetWindowDirty(WC_STATUS_BAR, 0);
 
	SetWindowDirty(WC_FINANCES, cid);
 
}
 

	
 
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());
 
			_error_message = STR_ERROR_NOT_ENOUGH_CASH_REQUIRES_CURRENCY;
 
			return false;
 
		}
 
	}
 
@@ -450,27 +450,27 @@ Company *DoStartupNewCompany(bool is_ai,
 

	
 
	c->share_owners[0] = c->share_owners[1] = c->share_owners[2] = c->share_owners[3] = INVALID_OWNER;
 

	
 
	c->avail_railtypes = GetCompanyRailtypes(c->index);
 
	c->avail_roadtypes = GetCompanyRoadtypes(c->index);
 
	c->inaugurated_year = _cur_year;
 
	RandomCompanyManagerFaceBits(c->face, (GenderEthnicity)Random(), false); // create a random company manager face
 

	
 
	SetDefaultCompanySettings(c->index);
 

	
 
	GeneratePresidentName(c);
 

	
 
	InvalidateWindow(WC_GRAPH_LEGEND, 0);
 
	InvalidateWindow(WC_TOOLBAR_MENU, 0);
 
	InvalidateWindow(WC_CLIENT_LIST, 0);
 
	SetWindowDirty(WC_GRAPH_LEGEND, 0);
 
	SetWindowDirty(WC_TOOLBAR_MENU, 0);
 
	SetWindowDirty(WC_CLIENT_LIST, 0);
 

	
 
	if (is_ai && (!_networking || _network_server)) AI::StartNew(c->index);
 

	
 
	c->num_engines = CallocT<uint16>(Engine::GetPoolSize());
 

	
 
	return c;
 
}
 

	
 
void StartupCompanies()
 
{
 
	_next_competitor_start = 0;
 
}
 
@@ -586,25 +586,25 @@ void OnTick_Companies()
 

	
 
	_cur_company_tick_index = (_cur_company_tick_index + 1) % MAX_COMPANIES;
 
}
 

	
 
void CompaniesYearlyLoop()
 
{
 
	Company *c;
 

	
 
	/* Copy statistics */
 
	FOR_ALL_COMPANIES(c) {
 
		memmove(&c->yearly_expenses[1], &c->yearly_expenses[0], sizeof(c->yearly_expenses) - sizeof(c->yearly_expenses[0]));
 
		memset(&c->yearly_expenses[0], 0, sizeof(c->yearly_expenses[0]));
 
		InvalidateWindow(WC_FINANCES, c->index);
 
		SetWindowDirty(WC_FINANCES, c->index);
 
	}
 

	
 
	if (_settings_client.gui.show_finances && _local_company != COMPANY_SPECTATOR) {
 
		ShowCompanyFinances(_local_company);
 
		c = Company::Get(_local_company);
 
		if (c->num_valid_stat_ent > 5 && c->old_economy[0].performance_history < c->old_economy[4].performance_history) {
 
			SndPlayFx(SND_01_BAD_YEAR);
 
		} else {
 
			SndPlayFx(SND_00_GOOD_YEAR);
 
		}
 
	}
 
}
src/company_gui.cpp
Show inline comments
 
@@ -1656,40 +1656,40 @@ struct CompanyWindow : Window
 
				this->query_widget = CW_WIDGET_COMPANY_NAME;
 
				SetDParam(0, this->window_number);
 
				ShowQueryString(STR_COMPANY_NAME, STR_COMPANY_VIEW_COMPANY_NAME_QUERY_CAPTION, MAX_LENGTH_COMPANY_NAME_BYTES, MAX_LENGTH_COMPANY_NAME_PIXELS, this, CS_ALPHANUMERAL, QSF_ENABLE_DEFAULT);
 
				break;
 

	
 
			case CW_WIDGET_BUILD_VIEW_HQ: {
 
				TileIndex tile = Company::Get((CompanyID)this->window_number)->location_of_HQ;
 
				if (tile == INVALID_TILE) {
 
					if ((byte)this->window_number != _local_company) return;
 
					SetObjectToPlaceWnd(SPR_CURSOR_HQ, PAL_NONE, HT_RECT, this);
 
					SetTileSelectSize(2, 2);
 
					this->LowerWidget(CW_WIDGET_BUILD_VIEW_HQ);
 
					this->InvalidateWidget(CW_WIDGET_BUILD_VIEW_HQ);
 
					this->SetWidgetDirty(CW_WIDGET_BUILD_VIEW_HQ);
 
				} else {
 
					if (_ctrl_pressed) {
 
						ShowExtraViewPortWindow(tile);
 
					} else {
 
						ScrollMainWindowToTile(tile);
 
					}
 
				}
 
				break;
 
			}
 

	
 
			case CW_WIDGET_RELOCATE_HQ:
 
				SetObjectToPlaceWnd(SPR_CURSOR_HQ, PAL_NONE, HT_RECT, this);
 
				SetTileSelectSize(2, 2);
 
				this->LowerWidget(CW_WIDGET_RELOCATE_HQ);
 
				this->InvalidateWidget(CW_WIDGET_RELOCATE_HQ);
 
				this->SetWidgetDirty(CW_WIDGET_RELOCATE_HQ);
 
				break;
 

	
 
			case CW_WIDGET_BUY_SHARE:
 
				DoCommandP(0, this->window_number, 0, CMD_BUY_SHARE_IN_COMPANY | CMD_MSG(STR_ERROR_CAN_T_BUY_25_SHARE_IN_THIS));
 
				break;
 

	
 
			case CW_WIDGET_SELL_SHARE:
 
				DoCommandP(0, this->window_number, 0, CMD_SELL_SHARE_IN_COMPANY | CMD_MSG(STR_ERROR_CAN_T_SELL_25_SHARE_IN));
 
				break;
 

	
 
#ifdef ENABLE_NETWORK
 
			case CW_WIDGET_COMPANY_PASSWORD:
src/console_cmds.cpp
Show inline comments
 
@@ -374,25 +374,25 @@ DEF_CONSOLE_CMD(ConPrintWorkingDirectory
 
	IConsolePrint(CC_DEFAULT, path);
 
	return true;
 
}
 

	
 
DEF_CONSOLE_CMD(ConClearBuffer)
 
{
 
	if (argc == 0) {
 
		IConsoleHelp("Clear the console buffer. Usage: 'clear'");
 
		return true;
 
	}
 

	
 
	IConsoleClearBuffer();
 
	InvalidateWindow(WC_CONSOLE, 0);
 
	SetWindowDirty(WC_CONSOLE, 0);
 
	return true;
 
}
 

	
 

	
 
/**********************************
 
 * Network Core Console Commands
 
 **********************************/
 
#ifdef ENABLE_NETWORK
 

	
 
DEF_CONSOLE_CMD(ConBan)
 
{
 
	NetworkClientInfo *ci;
src/console_gui.cpp
Show inline comments
 
@@ -132,25 +132,25 @@ IConsoleModes _iconsole_mode;
 

	
 
/* *************** *
 
 *  end of header  *
 
 * *************** */
 

	
 
static void IConsoleClearCommand()
 
{
 
	memset(_iconsole_cmdline.buf, 0, ICON_CMDLN_SIZE);
 
	_iconsole_cmdline.size = 1; // only terminating zero
 
	_iconsole_cmdline.width = 0;
 
	_iconsole_cmdline.caretpos = 0;
 
	_iconsole_cmdline.caretxoffs = 0;
 
	InvalidateWindow(WC_CONSOLE, 0);
 
	SetWindowDirty(WC_CONSOLE, 0);
 
}
 

	
 
static inline void IConsoleResetHistoryPos() {_iconsole_historypos = ICON_HISTORY_SIZE - 1;}
 

	
 

	
 
static void IConsoleHistoryAdd(const char *cmd);
 
static void IConsoleHistoryNavigate(int direction);
 

	
 
/** Widgets of the console window. */
 
enum ConsoleWidgets {
 
	CW_BACKGROUND, ///< Background of the console
 
};
 
@@ -461,14 +461,14 @@ static void IConsoleHistoryNavigate(int 
 
/**
 
 * Handle the printing of text entered into the console or redirected there
 
 * by any other means. Text can be redirected to other clients in a network game
 
 * as well as to a logfile. If the network server is a dedicated server, all activities
 
 * are also logged. All lines to print are added to a temporary buffer which can be
 
 * used as a history to print them onscreen
 
 * @param colour_code the colour of the command. Red in case of errors, etc.
 
 * @param string the message entered or output on the console (notice, error, etc.)
 
 */
 
void IConsoleGUIPrint(ConsoleColour colour_code, char *str)
 
{
 
	new IConsoleLine(str, (TextColour)colour_code);
 
	InvalidateWindow(WC_CONSOLE, 0);
 
	SetWindowDirty(WC_CONSOLE, 0);
 
}
src/date.cpp
Show inline comments
 
@@ -231,49 +231,49 @@ static void OnNewMonth()
 
{
 
	if (_debug_desync_level > 2) {
 
		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);
 
	}
 

	
 
	if (_settings_client.gui.autosave != 0 && (_cur_month % _autosave_months[_settings_client.gui.autosave]) == 0) {
 
		_do_autosave = true;
 
		RedrawAutosave();
 
	}
 

	
 
	InvalidateWindowClasses(WC_CHEATS);
 
	SetWindowClassesDirty(WC_CHEATS);
 
	CompaniesMonthlyLoop();
 
	SubsidyMonthlyLoop();
 
	EnginesMonthlyLoop();
 
	TownsMonthlyLoop();
 
	IndustryMonthlyLoop();
 
	StationMonthlyLoop();
 
#ifdef ENABLE_NETWORK
 
	if (_network_server) NetworkServerMonthlyLoop();
 
#endif /* ENABLE_NETWORK */
 
}
 

	
 
/**
 
 * Runs various procedures that have to be done daily
 
 */
 
static void OnNewDay()
 
{
 
#ifdef ENABLE_NETWORK
 
	NetworkChatMessageDailyLoop();
 
#endif /* ENABLE_NETWORK */
 

	
 
	DisasterDailyLoop();
 
	IndustryDailyLoop();
 

	
 
	InvalidateWindowWidget(WC_STATUS_BAR, 0, 0);
 
	SetWindowWidgetDirty(WC_STATUS_BAR, 0, 0);
 
	EnginesDailyLoop();
 
}
 

	
 
/**
 
 * Increases the tick counter, increases date  and possibly calls
 
 * procedures that have to be called daily, monthly or yearly.
 
 */
 
void IncreaseDate()
 
{
 
	/* increase day, and check if a new day is there? */
 
	_tick_counter++;
 

	
src/depot_gui.cpp
Show inline comments
 
@@ -717,25 +717,25 @@ struct DepotWindow : Window {
 
	{
 
		switch (widget) {
 
			case DEPOT_WIDGET_MATRIX: // List
 
				this->DepotClick(pt.x, pt.y);
 
				break;
 

	
 
			case DEPOT_WIDGET_BUILD: // Build vehicle
 
				ResetObjectToPlace();
 
				ShowBuildVehicleWindow(this->window_number, this->type);
 
				break;
 

	
 
			case DEPOT_WIDGET_CLONE: // Clone button
 
				this->InvalidateWidget(DEPOT_WIDGET_CLONE);
 
				this->SetWidgetDirty(DEPOT_WIDGET_CLONE);
 
				this->ToggleWidgetLoweredState(DEPOT_WIDGET_CLONE);
 

	
 
				if (this->IsWidgetLowered(DEPOT_WIDGET_CLONE)) {
 
					static const CursorID clone_icons[] = {
 
						SPR_CURSOR_CLONE_TRAIN, SPR_CURSOR_CLONE_ROADVEH,
 
						SPR_CURSOR_CLONE_SHIP, SPR_CURSOR_CLONE_AIRPLANE
 
					};
 

	
 
					_place_clicked_vehicle = NULL;
 
					SetObjectToPlaceWnd(clone_icons[this->type], PAL_NONE, HT_RECT, this);
 
				} else {
 
					ResetObjectToPlace();
 
@@ -841,29 +841,29 @@ struct DepotWindow : Window {
 

	
 
	virtual void OnPlaceObject(Point pt, TileIndex tile)
 
	{
 
		const Vehicle *v = CheckMouseOverVehicle();
 

	
 
		if (v != NULL) this->HandleCloneVehClick(v);
 
	}
 

	
 
	virtual void OnPlaceObjectAbort()
 
	{
 
		/* abort clone */
 
		this->RaiseWidget(DEPOT_WIDGET_CLONE);
 
		this->InvalidateWidget(DEPOT_WIDGET_CLONE);
 
		this->SetWidgetDirty(DEPOT_WIDGET_CLONE);
 

	
 
		/* abort drag & drop */
 
		this->sel = INVALID_VEHICLE;
 
		this->InvalidateWidget(DEPOT_WIDGET_MATRIX);
 
		this->SetWidgetDirty(DEPOT_WIDGET_MATRIX);
 
	};
 

	
 
	/* check if a vehicle in a depot was clicked.. */
 
	virtual void OnMouseLoop()
 
	{
 
		const Vehicle *v = _place_clicked_vehicle;
 

	
 
		/* since OTTD checks all open depot windows, we will make sure that it triggers the one with a clicked clone button */
 
		if (v != NULL && this->IsWidgetLowered(DEPOT_WIDGET_CLONE)) {
 
			_place_clicked_vehicle = NULL;
 
			this->HandleCloneVehClick(v);
 
		}
 
@@ -926,45 +926,45 @@ struct DepotWindow : Window {
 
				break;
 
			default:
 
				this->sel = INVALID_VEHICLE;
 
				this->SetDirty();
 
		}
 
		_cursor.vehchain = false;
 
	}
 

	
 
	virtual void OnTimeout()
 
	{
 
		if (!this->IsWidgetDisabled(DEPOT_WIDGET_SELL)) {
 
			this->RaiseWidget(DEPOT_WIDGET_SELL);
 
			this->InvalidateWidget(DEPOT_WIDGET_SELL);
 
			this->SetWidgetDirty(DEPOT_WIDGET_SELL);
 
		}
 
		if (!this->IsWidgetDisabled(DEPOT_WIDGET_SELL_CHAIN)) {
 
			this->RaiseWidget(DEPOT_WIDGET_SELL_CHAIN);
 
			this->InvalidateWidget(DEPOT_WIDGET_SELL_CHAIN);
 
			this->SetWidgetDirty(DEPOT_WIDGET_SELL_CHAIN);
 
		}
 
	}
 

	
 
	virtual void OnResize(Point delta)
 
	{
 
		this->vscroll.UpdateCapacity(delta.y / (int)this->resize.step_height);
 
		this->hscroll.UpdateCapacity(delta.x / (int)this->resize.step_width);
 
		this->widget[DEPOT_WIDGET_MATRIX].data = (this->vscroll.GetCapacity() << MAT_ROW_START) + ((this->type == VEH_TRAIN ? 1 : this->hscroll.GetCapacity()) << MAT_COL_START);
 
		this->ResizeDepotButtons();
 
	}
 

	
 
	virtual EventState OnCTRLStateChange()
 
	{
 
		if (this->sel != INVALID_VEHICLE) {
 
			_cursor.vehchain = _ctrl_pressed;
 
			this->InvalidateWidget(DEPOT_WIDGET_MATRIX);
 
			this->SetWidgetDirty(DEPOT_WIDGET_MATRIX);
 
			return ES_HANDLED;
 
		}
 

	
 
		return ES_NOT_HANDLED;
 
	}
 
};
 

	
 
static void DepotSellAllConfirmationCallback(Window *win, bool confirmed)
 
{
 
	if (confirmed) {
 
		DepotWindow *w = (DepotWindow*)win;
 
		TileIndex tile = w->window_number;
src/economy.cpp
Show inline comments
 
@@ -272,25 +272,25 @@ int UpdateCompanyRatingAndValue(Company 
 
		_score_part[owner][SCORE_TOTAL] = score;
 

	
 
		/*  We always want the score scaled to SCORE_MAX (1000) */
 
		if (total_score != SCORE_MAX) score = score * SCORE_MAX / total_score;
 
	}
 

	
 
	if (update) {
 
		c->old_economy[0].performance_history = score;
 
		UpdateCompanyHQ(c, score);
 
		c->old_economy[0].company_value = CalculateCompanyValue(c);
 
	}
 

	
 
	InvalidateWindow(WC_PERFORMANCE_DETAIL, 0);
 
	SetWindowDirty(WC_PERFORMANCE_DETAIL, 0);
 
	return score;
 
}
 

	
 
/*  use INVALID_OWNER as new_owner to delete the company. */
 
void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner)
 
{
 
	Town *t;
 
	CompanyID old = _current_company;
 

	
 
	assert(old_owner != new_owner);
 

	
 
	{
 
@@ -567,30 +567,30 @@ static void CompaniesGenStatistics()
 
	FOR_ALL_COMPANIES(c) {
 
		memmove(&c->old_economy[1], &c->old_economy[0], sizeof(c->old_economy) - sizeof(c->old_economy[0]));
 
		c->old_economy[0] = c->cur_economy;
 
		memset(&c->cur_economy, 0, sizeof(c->cur_economy));
 

	
 
		if (c->num_valid_stat_ent != MAX_HISTORY_MONTHS) c->num_valid_stat_ent++;
 

	
 
		UpdateCompanyRatingAndValue(c, true);
 
		if (c->block_preview != 0) c->block_preview--;
 
		CompanyCheckBankrupt(c);
 
	}
 

	
 
	InvalidateWindow(WC_INCOME_GRAPH, 0);
 
	InvalidateWindow(WC_OPERATING_PROFIT, 0);
 
	InvalidateWindow(WC_DELIVERED_CARGO, 0);
 
	InvalidateWindow(WC_PERFORMANCE_HISTORY, 0);
 
	InvalidateWindow(WC_COMPANY_VALUE, 0);
 
	InvalidateWindow(WC_COMPANY_LEAGUE, 0);
 
	SetWindowDirty(WC_INCOME_GRAPH, 0);
 
	SetWindowDirty(WC_OPERATING_PROFIT, 0);
 
	SetWindowDirty(WC_DELIVERED_CARGO, 0);
 
	SetWindowDirty(WC_PERFORMANCE_HISTORY, 0);
 
	SetWindowDirty(WC_COMPANY_VALUE, 0);
 
	SetWindowDirty(WC_COMPANY_LEAGUE, 0);
 
}
 

	
 
/**
 
 * Add monthly inflation
 
 * @param check_year Shall the inflation get stopped after 170 years?
 
 */
 
void AddInflation(bool check_year)
 
{
 
	/* The cargo payment inflation differs from the normal inflation, so the
 
	 * relative amount of money you make with a transport decreases slowly over
 
	 * the 170 years. After a few hundred years we reach a level in which the
 
	 * games will become unplayable as the maximum income will be less than
 
@@ -661,28 +661,28 @@ void RecomputePrices()
 
		}
 

	
 
		/* Store value */
 
		((Money *)&_price)[i] = price;
 
	}
 

	
 
	/* Setup cargo payment */
 
	CargoSpec *cs;
 
	FOR_ALL_CARGOSPECS(cs) {
 
		cs->current_payment = ((int64)cs->initial_payment * _economy.inflation_payment) >> 16;
 
	}
 

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

	
 
static void CompaniesPayInterest()
 
{
 
	const Company *c;
 

	
 
	FOR_ALL_COMPANIES(c) {
 
		_current_company = 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.
 
@@ -957,25 +957,25 @@ static Money DeliverGoods(int num_pieces
 
static void TriggerIndustryProduction(Industry *i)
 
{
 
	const IndustrySpec *indspec = GetIndustrySpec(i->type);
 
	uint16 callback = indspec->callback_flags;
 

	
 
	i->was_cargo_delivered = true;
 
	i->last_cargo_accepted_at = _date;
 

	
 
	if (HasBit(callback, CBM_IND_PRODUCTION_CARGO_ARRIVAL) || HasBit(callback, CBM_IND_PRODUCTION_256_TICKS)) {
 
		if (HasBit(callback, CBM_IND_PRODUCTION_CARGO_ARRIVAL)) {
 
			IndustryProductionCallback(i, 0);
 
		} else {
 
			InvalidateWindow(WC_INDUSTRY_VIEW, i->index);
 
			SetWindowDirty(WC_INDUSTRY_VIEW, i->index);
 
		}
 
	} else {
 
		for (uint cargo_index = 0; cargo_index < lengthof(i->incoming_cargo_waiting); cargo_index++) {
 
			uint cargo_waiting = i->incoming_cargo_waiting[cargo_index];
 
			if (cargo_waiting == 0) continue;
 

	
 
			i->produced_cargo_waiting[0] = min(i->produced_cargo_waiting[0] + (cargo_waiting * indspec->input_cargo_multiplier[cargo_index][0] / 256), 0xFFFF);
 
			i->produced_cargo_waiting[1] = min(i->produced_cargo_waiting[1] + (cargo_waiting * indspec->input_cargo_multiplier[cargo_index][1] / 256), 0xFFFF);
 

	
 
			i->incoming_cargo_waiting[cargo_index] = 0;
 
		}
 
	}
 
@@ -1345,31 +1345,31 @@ static void LoadUnloadVehicle(Vehicle *v
 
			UpdateFillingPercent(v->fill_percent_te_id, percent, percent_up_down);
 
		}
 
	}
 

	
 
	/* Always wait at least 1, otherwise we'll wait 'infinitively' long. */
 
	v->load_unload_time_rem = max(1, unloading_time);
 

	
 
	if (completely_emptied) {
 
		TriggerVehicle(v, VEHICLE_TRIGGER_EMPTY);
 
	}
 

	
 
	if (result != 0) {
 
		InvalidateWindow(GetWindowClassForVehicleType(v->type), v->owner);
 
		InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 
		SetWindowDirty(GetWindowClassForVehicleType(v->type), v->owner);
 
		SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
 

	
 
		st->MarkTilesDirty(true);
 
		v->MarkDirty();
 

	
 
		if (result & 2) InvalidateWindow(WC_STATION_VIEW, last_visited);
 
		if (result & 2) SetWindowDirty(WC_STATION_VIEW, last_visited);
 
	}
 
}
 

	
 
/**
 
 * Load/unload the vehicles in this station according to the order
 
 * they entered.
 
 * @param st the station to do the loading/unloading for
 
 */
 
void LoadUnloadStation(Station *st)
 
{
 
	/* No vehicle is here... */
 
	if (st->loading_vehicles.empty()) return;
 
@@ -1486,25 +1486,25 @@ CommandCost CmdBuyShareInCompany(TileInd
 
		int i;
 

	
 
		while (*b != COMPANY_SPECTATOR) b++; // share owners is guaranteed to contain at least one COMPANY_SPECTATOR
 
		*b = _current_company;
 

	
 
		for (i = 0; c->share_owners[i] == _current_company;) {
 
			if (++i == 4) {
 
				c->bankrupt_value = 0;
 
				DoAcquireCompany(c);
 
				break;
 
			}
 
		}
 
		InvalidateWindow(WC_COMPANY, p1);
 
		SetWindowDirty(WC_COMPANY, p1);
 
	}
 
	return cost;
 
}
 

	
 
/** Sell shares in an opposing company.
 
 * @param tile unused
 
 * @param flags type of operation
 
 * @param p1 company to sell the shares from
 
 * @param p2 unused
 
 */
 
CommandCost CmdSellShareInCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
 
{
 
@@ -1516,25 +1516,25 @@ CommandCost CmdSellShareInCompany(TileIn
 

	
 
	/* Those lines are here for network-protection (clients can be slow) */
 
	if (GetAmountOwnedBy(c, _current_company) == 0) return CommandCost();
 

	
 
	/* adjust it a little to make it less profitable to sell and buy */
 
	Money cost = CalculateCompanyValue(c) >> 2;
 
	cost = -(cost - (cost >> 7));
 

	
 
	if (flags & DC_EXEC) {
 
		OwnerByte *b = c->share_owners;
 
		while (*b != _current_company) b++; // share owners is guaranteed to contain company
 
		*b = COMPANY_SPECTATOR;
 
		InvalidateWindow(WC_COMPANY, p1);
 
		SetWindowDirty(WC_COMPANY, p1);
 
	}
 
	return CommandCost(EXPENSES_OTHER, cost);
 
}
 

	
 
/** Buy up another company.
 
 * When a competing company is gone bankrupt you get the chance to purchase
 
 * that company.
 
 * @todo currently this only works for AI companies
 
 * @param tile unused
 
 * @param flags type of operation
 
 * @param p1 company to buy up
 
 * @param p2 unused
src/engine.cpp
Show inline comments
 
@@ -427,26 +427,26 @@ static void CalcEngineReliability(Engine
 
		e->reliability = e->reliability_max;
 
	} else if ((age -= e->duration_phase_2) < e->duration_phase_3) {
 
		uint max = e->reliability_max;
 
		e->reliability = (int)age * (int)(e->reliability_final - max) / e->duration_phase_3 + max;
 
	} else {
 
		/* time's up for this engine.
 
		 * We will now completely retire this design */
 
		e->company_avail = 0;
 
		e->reliability = e->reliability_final;
 
		/* Kick this engine out of the lists */
 
		AddRemoveEngineFromAutoreplaceAndBuildWindows(e->type);
 
	}
 
	InvalidateWindowClasses(WC_BUILD_VEHICLE); // Update to show the new reliability
 
	InvalidateWindowClasses(WC_REPLACE_VEHICLE);
 
	SetWindowClassesDirty(WC_BUILD_VEHICLE); // Update to show the new reliability
 
	SetWindowClassesDirty(WC_REPLACE_VEHICLE);
 
}
 

	
 
void SetYearEngineAgingStops()
 
{
 
	/* Determine last engine aging year, default to 2050 as previously. */
 
	_year_engine_aging_stops = 2050;
 

	
 
	const Engine *e;
 
	FOR_ALL_ENGINES(e) {
 
		const EngineInfo *ei = &e->info;
 

	
 
		/* Exclude certain engines */
src/genworld_gui.cpp
Show inline comments
 
@@ -45,26 +45,26 @@ enum glwp_modes {
 
	GLWP_GENERATE,
 
	GLWP_HEIGHTMAP,
 
	GLWP_SCENARIO,
 
	GLWP_END
 
};
 

	
 
extern void SwitchToMode(SwitchMode new_mode);
 
extern void MakeNewgameSettingsLive();
 

	
 
static inline void SetNewLandscapeType(byte landscape)
 
{
 
	_settings_newgame.game_creation.landscape = landscape;
 
	InvalidateWindowClasses(WC_SELECT_GAME);
 
	InvalidateWindowClasses(WC_GENERATE_LANDSCAPE);
 
	SetWindowClassesDirty(WC_SELECT_GAME);
 
	SetWindowClassesDirty(WC_GENERATE_LANDSCAPE);
 
}
 

	
 
enum GenerateLandscapeWindowWidgets {
 
	GLAND_CLOSEBOX,
 
	GLAND_TITLEBAR,
 
	GLAND_BACKGROUND,
 

	
 
	GLAND_TEMPERATE,
 
	GLAND_ARCTIC,
 
	GLAND_TROPICAL,
 
	GLAND_TOYLAND,
 

	
 
@@ -793,25 +793,25 @@ struct GenerateLandscapeWindow : public 
 
				_settings_newgame.game_creation.water_borders = (_settings_newgame.game_creation.water_borders == BORDERS_RANDOM) ? 0 : BORDERS_RANDOM;
 
				this->SetDirty();
 
				break;
 
		}
 
	}
 

	
 
	virtual void OnTimeout()
 
	{
 
		static const int raise_widgets[] = {GLAND_START_DATE_DOWN, GLAND_START_DATE_UP, GLAND_SNOW_LEVEL_UP, GLAND_SNOW_LEVEL_DOWN, WIDGET_LIST_END};
 
		for (const int *widget = raise_widgets; *widget != WIDGET_LIST_END; widget++) {
 
			if (this->IsWidgetLowered(*widget)) {
 
				this->RaiseWidget(*widget);
 
				this->InvalidateWidget(*widget);
 
				this->SetWidgetDirty(*widget);
 
			}
 
		}
 
	}
 

	
 
	virtual void OnMouseLoop()
 
	{
 
		this->HandleEditBox(GLAND_RANDOM_EDITBOX);
 
	}
 

	
 
	virtual EventState OnKeyPress(uint16 key, uint16 keycode)
 
	{
 
		EventState state;
 
@@ -871,30 +871,30 @@ struct GenerateLandscapeWindow : public 
 
			}
 
		}
 
		this->SetDirty();
 
	}
 

	
 
	virtual void OnQueryTextFinished(char *str)
 
	{
 
		if (!StrEmpty(str)) {
 
			int32 value = atoi(str);
 

	
 
			switch (this->widget_id) {
 
				case GLAND_START_DATE_TEXT:
 
					this->InvalidateWidget(GLAND_START_DATE_TEXT);
 
					this->SetWidgetDirty(GLAND_START_DATE_TEXT);
 
					_settings_newgame.game_creation.starting_year = Clamp(value, MIN_YEAR, MAX_YEAR);
 
					break;
 

	
 
				case GLAND_SNOW_LEVEL_TEXT:
 
					this->InvalidateWidget(GLAND_SNOW_LEVEL_TEXT);
 
					this->SetWidgetDirty(GLAND_SNOW_LEVEL_TEXT);
 
					_settings_newgame.game_creation.snow_line_height = Clamp(value, 2, MAX_SNOWLINE_HEIGHT);
 
					break;
 

	
 
				case GLAND_TOWN_PULLDOWN:
 
					_settings_newgame.game_creation.custom_town_number = Clamp(value, 1, CUSTOM_TOWN_MAX_NUMBER);
 
					break;
 
			}
 

	
 
			this->SetDirty();
 
		}
 
	}
 
};
 
@@ -927,25 +927,25 @@ static void _ShowGenerateLandscape(glwp_
 
		/* If the function returns negative, it means there was a problem loading the heightmap */
 
		if (!GetHeightmapDimensions(_file_to_saveload.name, &x, &y)) return;
 
	}
 

	
 
	GenerateLandscapeWindow *w = AllocateWindowDescFront<GenerateLandscapeWindow>((mode == GLWP_HEIGHTMAP) ? &_heightmap_load_desc : &_generate_landscape_desc, mode);
 

	
 
	if (mode == GLWP_HEIGHTMAP) {
 
		w->x = x;
 
		w->y = y;
 
		strecpy(w->name, _file_to_saveload.title, lastof(w->name));
 
	}
 

	
 
	InvalidateWindow(WC_GENERATE_LANDSCAPE, mode);
 
	SetWindowDirty(WC_GENERATE_LANDSCAPE, mode);
 
}
 

	
 
void ShowGenerateLandscape()
 
{
 
	_ShowGenerateLandscape(GLWP_GENERATE);
 
}
 

	
 
void ShowHeightmapLoad()
 
{
 
	_ShowGenerateLandscape(GLWP_HEIGHTMAP);
 
}
 

	
 
@@ -1091,30 +1091,30 @@ struct CreateScenarioWindow : public Win
 
			case CSCEN_MAPSIZE_Y_PULLDOWN: _settings_newgame.game_creation.map_y = index; break;
 
		}
 
		this->SetDirty();
 
	}
 

	
 
	virtual void OnQueryTextFinished(char *str)
 
	{
 
		if (!StrEmpty(str)) {
 
			int32 value = atoi(str);
 

	
 
			switch (this->widget_id) {
 
				case CSCEN_START_DATE_TEXT:
 
					this->InvalidateWidget(CSCEN_START_DATE_TEXT);
 
					this->SetWidgetDirty(CSCEN_START_DATE_TEXT);
 
					_settings_newgame.game_creation.starting_year = Clamp(value, MIN_YEAR, MAX_YEAR);
 
					break;
 

	
 
				case CSCEN_FLAT_LAND_HEIGHT_TEXT:
 
					this->InvalidateWidget(CSCEN_FLAT_LAND_HEIGHT_TEXT);
 
					this->SetWidgetDirty(CSCEN_FLAT_LAND_HEIGHT_TEXT);
 
					_settings_newgame.game_creation.se_flat_world_height = Clamp(value, 0, MAX_TILE_HEIGHT);
 
					break;
 
			}
 

	
 
			this->SetDirty();
 
		}
 
	}
 
};
 

	
 
static const Widget _create_scenario_widgets[] = {
 
{   WWT_CLOSEBOX, RESIZE_NONE, COLOUR_BROWN,    0,  10,   0,  13, STR_BLACK_CROSS,         STR_TOOLTIP_CLOSE_WINDOW},                 // CSCEN_CLOSEBOX
 
{    WWT_CAPTION, RESIZE_NONE, COLOUR_BROWN,   11, 337,   0,  13, STR_SE_MAPGEN_CAPTION,          STR_NULL},                                 // CSCEN_CAPTION
 
@@ -1387,25 +1387,25 @@ static void _SetGeneratingWorldProgress(
 
		/* Display every 5%, but 6% is also very valid.. just not smaller steps than 5% */
 
		if (_tp.percent % 5 != 0 && _tp.percent <= last_percent + 5) return;
 
		/* Never show steps smaller than 2%, even if it is a mod 5% */
 
		if (_tp.percent <= last_percent + 2) return;
 

	
 
		DEBUG(net, 1, "Map generation percentage complete: %d", _tp.percent);
 
		last_percent = _tp.percent;
 

	
 
		/* Don't continue as dedicated never has a thread running */
 
		return;
 
	}
 

	
 
	InvalidateWindow(WC_GENERATE_PROGRESS_WINDOW, 0);
 
	SetWindowDirty(WC_GENERATE_PROGRESS_WINDOW, 0);
 
	MarkWholeScreenDirty();
 

	
 
	/* Release the rights to the map generator, and acquire the rights to the
 
	 * paint thread. The 'other' thread already has the paint thread rights so
 
	 * this ensures us that we are waiting until the paint thread is done
 
	 * before we reacquire the mapgen rights */
 
	_genworld_mapgen_mutex->EndCritical();
 
	_genworld_paint_mutex->BeginCritical();
 
	_genworld_mapgen_mutex->BeginCritical();
 
	_genworld_paint_mutex->EndCritical();
 

	
 
	_tp.timer = _realtime_tick;
src/graph_gui.cpp
Show inline comments
 
@@ -78,29 +78,29 @@ struct GraphLegendWindow : Window {
 
		SetDParam(0, cid);
 
		SetDParam(1, cid);
 
		DrawString(r.left + 19, r.right - 2, r.top + 1, STR_COMPANY_NAME_COMPANY_NUM, HasBit(_legend_excluded_companies, cid) ? TC_BLACK : TC_WHITE);
 
	}
 

	
 
	virtual void OnClick(Point pt, int widget)
 
	{
 
		if (!IsInsideMM(widget, GLW_FIRST_COMPANY, MAX_COMPANIES + GLW_FIRST_COMPANY)) return;
 

	
 
		ToggleBit(_legend_excluded_companies, widget - GLW_FIRST_COMPANY);
 
		this->ToggleWidgetLoweredState(widget);
 
		this->SetDirty();
 
		InvalidateWindow(WC_INCOME_GRAPH, 0);
 
		InvalidateWindow(WC_OPERATING_PROFIT, 0);
 
		InvalidateWindow(WC_DELIVERED_CARGO, 0);
 
		InvalidateWindow(WC_PERFORMANCE_HISTORY, 0);
 
		InvalidateWindow(WC_COMPANY_VALUE, 0);
 
		SetWindowDirty(WC_INCOME_GRAPH, 0);
 
		SetWindowDirty(WC_OPERATING_PROFIT, 0);
 
		SetWindowDirty(WC_DELIVERED_CARGO, 0);
 
		SetWindowDirty(WC_PERFORMANCE_HISTORY, 0);
 
		SetWindowDirty(WC_COMPANY_VALUE, 0);
 
	}
 

	
 
	virtual void OnInvalidateData(int data)
 
	{
 
		if (Company::IsValidID(data)) return;
 

	
 
		SetBit(_legend_excluded_companies, data);
 
		this->RaiseWidget(data + GLW_FIRST_COMPANY);
 
	}
 
};
 

	
 
/**
 
@@ -394,25 +394,25 @@ protected:
 
					x += GRAPH_X_POSITION_SEPARATION;
 
				}
 
			}
 
		}
 
	}
 

	
 

	
 
	BaseGraphWindow(const WindowDesc *desc, WindowNumber window_number, int left,
 
									int top, int height, bool has_negative_values, StringID format_str_y_axis) :
 
			Window(desc, window_number), has_negative_values(has_negative_values),
 
			format_str_y_axis(format_str_y_axis)
 
	{
 
		InvalidateWindow(WC_GRAPH_LEGEND, 0);
 
		SetWindowDirty(WC_GRAPH_LEGEND, 0);
 
		this->num_vert_lines = 24;
 

	
 
		this->graph_location.left   = left;
 
		this->graph_location.right  = left + GRAPH_X_POSITION_BEGINNING + this->num_vert_lines * GRAPH_X_POSITION_SEPARATION - 1;
 

	
 
		this->graph_location.top    = top;
 
		this->graph_location.bottom = top + height - 1;
 
	}
 

	
 
	void InitializeWindow(const WindowDesc *desc)
 
	{
 
		this->FindWindowPlacementAndResize(desc);
src/group_cmd.cpp
Show inline comments
 
@@ -219,25 +219,25 @@ CommandCost CmdAddVehicleGroup(TileIndex
 
			case VEH_TRAIN:
 
				SetTrainGroupID(Train::From(v), new_g);
 
				break;
 
			case VEH_ROAD:
 
			case VEH_SHIP:
 
			case VEH_AIRCRAFT:
 
				if (v->IsEngineCountable()) UpdateNumEngineGroup(v->engine_type, v->group_id, new_g);
 
				v->group_id = new_g;
 
				break;
 
		}
 

	
 
		/* Update the Replace Vehicle Windows */
 
		InvalidateWindow(WC_REPLACE_VEHICLE, v->type);
 
		SetWindowDirty(WC_REPLACE_VEHICLE, v->type);
 
		InvalidateWindowData(GetWindowClassForVehicleType(v->type), (v->type << 11) | VLW_GROUP_LIST | _current_company);
 
	}
 

	
 
	return CommandCost();
 
}
 

	
 
/**
 
 * Add all shared vehicles of all vehicles from a group
 
 * @param tile unused
 
 * @param p1   index of group array
 
 *  - p1 bit 0-15 : GroupID
 
 * @param p2   type of vehicles
 
@@ -353,48 +353,48 @@ void SetTrainGroupID(Train *v, GroupID n
 
{
 
	if (!Group::IsValidID(new_g) && !IsDefaultGroupID(new_g)) return;
 

	
 
	assert(v->IsFrontEngine());
 

	
 
	for (Vehicle *u = v; u != NULL; u = u->Next()) {
 
		if (u->IsEngineCountable()) UpdateNumEngineGroup(u->engine_type, u->group_id, new_g);
 

	
 
		u->group_id = new_g;
 
	}
 

	
 
	/* Update the Replace Vehicle Windows */
 
	InvalidateWindow(WC_REPLACE_VEHICLE, VEH_TRAIN);
 
	SetWindowDirty(WC_REPLACE_VEHICLE, VEH_TRAIN);
 
}
 

	
 

	
 
/**
 
 * Recalculates the groupID of a train. Should be called each time a vehicle is added
 
 * to/removed from the chain,.
 
 * @note this needs to be called too for 'wagon chains' (in the depot, without an engine)
 
 * @note Called in CmdBuildRailVehicle, CmdBuildRailWagon, CmdMoveRailVehicle, CmdSellRailWagon
 
 * @param v First vehicle of the chain.
 
 */
 
void UpdateTrainGroupID(Train *v)
 
{
 
	assert(v->IsFrontEngine() || v->IsFreeWagon());
 

	
 
	GroupID new_g = v->IsFrontEngine() ? v->group_id : (GroupID)DEFAULT_GROUP;
 
	for (Vehicle *u = v; u != NULL; u = u->Next()) {
 
		if (u->IsEngineCountable()) UpdateNumEngineGroup(u->engine_type, u->group_id, new_g);
 

	
 
		u->group_id = new_g;
 
	}
 

	
 
	/* Update the Replace Vehicle Windows */
 
	InvalidateWindow(WC_REPLACE_VEHICLE, VEH_TRAIN);
 
	SetWindowDirty(WC_REPLACE_VEHICLE, VEH_TRAIN);
 
}
 

	
 
uint GetGroupNumEngines(CompanyID company, GroupID id_g, EngineID id_e)
 
{
 
	if (Group::IsValidID(id_g)) return Group::Get(id_g)->num_engines[id_e];
 

	
 
	uint num = Company::Get(company)->num_engines[id_e];
 
	if (!IsDefaultGroupID(id_g)) return num;
 

	
 
	const Group *g;
 
	FOR_ALL_GROUPS(g) {
 
		if (g->owner == company) num -= g->num_engines[id_e];
src/group_gui.cpp
Show inline comments
 
@@ -667,25 +667,25 @@ public:
 
	virtual void OnTick()
 
	{
 
		if (_pause_mode != PM_UNPAUSED) return;
 
		if (this->groups.NeedResort() || this->vehicles.NeedResort()) {
 
			this->SetDirty();
 
		}
 
	}
 

	
 
	virtual void OnPlaceObjectAbort()
 
	{
 
		/* abort drag & drop */
 
		this->vehicle_sel = INVALID_VEHICLE;
 
		this->InvalidateWidget(GRP_WIDGET_LIST_VEHICLE);
 
		this->SetWidgetDirty(GRP_WIDGET_LIST_VEHICLE);
 
	}
 

	
 
	void ShowRenameGroupWindow(GroupID group)
 
	{
 
		assert(Group::IsValidID(group));
 
		this->group_rename = group;
 
		SetDParam(0, group);
 
		ShowQueryString(STR_GROUP_NAME, STR_GROUP_RENAME_CAPTION, MAX_LENGTH_GROUP_NAME_BYTES, MAX_LENGTH_GROUP_NAME_PIXELS, this, CS_ALPHANUMERAL, QSF_ENABLE_DEFAULT);
 
	}
 

	
 
	/**
 
	 * Tests whether a given vehicle is selected in the window, and unselects it if necessary.
src/industry_cmd.cpp
Show inline comments
 
@@ -1885,25 +1885,25 @@ static void UpdateIndustryStatistics(Ind
 
			}
 
			i->last_month_pct_transported[j] = pct;
 

	
 
			i->last_month_production[j] = i->this_month_production[j];
 
			i->this_month_production[j] = 0;
 

	
 
			i->last_month_transported[j] = i->this_month_transported[j];
 
			i->this_month_transported[j] = 0;
 
			refresh = true;
 
		}
 
	}
 

	
 
	if (refresh) InvalidateWindow(WC_INDUSTRY_VIEW, i->index);
 
	if (refresh) SetWindowDirty(WC_INDUSTRY_VIEW, i->index);
 
}
 

	
 
/** Simple helper that will collect data for the generation of industries */
 
struct ProbabilityHelper {
 
	uint16 prob;      ///< probability
 
	IndustryType ind; ///< industry id correcponding
 
};
 

	
 
/**
 
 * Try to create a random industry, during gameplay
 
 */
 
static void MaybeNewIndustry()
src/industry_gui.cpp
Show inline comments
 
@@ -797,25 +797,25 @@ protected:
 
			const Industry *i;
 
			FOR_ALL_INDUSTRIES(i) {
 
				*this->industries.Append() = i;
 
			}
 

	
 
			this->industries.Compact();
 
			this->industries.RebuildDone();
 
			this->vscroll.SetCount(this->industries.Length()); // Update scrollbar as well.
 
		}
 

	
 
		if (!this->industries.Sort()) return;
 
		IndustryDirectoryWindow::last_industry = NULL; // Reset name sorter sort cache
 
		this->InvalidateWidget(IDW_INDUSTRY_LIST); // Set the modified widget dirty
 
		this->SetWidgetDirty(IDW_INDUSTRY_LIST); // Set the modified widget dirty
 
	}
 

	
 
	/**
 
	 * Returns percents of cargo transported if industry produces this cargo, else -1
 
	 *
 
	 * @param i industry to check
 
	 * @param id cargo slot
 
	 * @return percents of cargo transported, or -1 if industry doesn't use this cargo slot
 
	 */
 
	static inline int GetCargoTransportedPercentsIfValid(const Industry *i, uint id)
 
	{
 
		assert(id < lengthof(i->produced_cargo));
src/intro_gui.cpp
Show inline comments
 
@@ -26,25 +26,25 @@
 
#include "settings_type.h"
 
#include "functions.h"
 
#include "newgrf_config.h"
 
#include "ai/ai_gui.hpp"
 
#include "gfx_func.h"
 

	
 
#include "table/strings.h"
 
#include "table/sprites.h"
 

	
 
static inline void SetNewLandscapeType(byte landscape)
 
{
 
	_settings_newgame.game_creation.landscape = landscape;
 
	InvalidateWindowClasses(WC_SELECT_GAME);
 
	SetWindowClassesDirty(WC_SELECT_GAME);
 
}
 

	
 
enum SelectGameIntroWidgets {
 
	SGI_CLOSE,
 
	SGI_CAPTION,
 
	SGI_GENERATE_GAME,
 
	SGI_LOAD_GAME,
 
	SGI_PLAY_SCENARIO,
 
	SGI_PLAY_HEIGHTMAP,
 
	SGI_EDIT_SCENARIO,
 
	SGI_PLAY_NETWORK,
 
	SGI_TEMPERATE_LANDSCAPE,
src/misc_cmd.cpp
Show inline comments
 
@@ -345,26 +345,26 @@ CommandCost CmdPause(TileIndex tile, DoC
 
				STR_NEWGRF_UNPAUSE_WARNING,
 
				NULL,
 
				AskUnsafeUnpauseCallback
 
			);
 
		} else {
 
			if (p2 == 0) {
 
				_pause_mode = _pause_mode & ~p1;
 
			} else {
 
				_pause_mode = _pause_mode | p1;
 
			}
 
		}
 

	
 
		InvalidateWindow(WC_STATUS_BAR, 0);
 
		InvalidateWindow(WC_MAIN_TOOLBAR, 0);
 
		SetWindowDirty(WC_STATUS_BAR, 0);
 
		SetWindowDirty(WC_MAIN_TOOLBAR, 0);
 
	}
 
	return CommandCost();
 
}
 

	
 
/** Change the financial flow of your company.
 
 * This is normally only enabled in offline mode, but if there is a debug
 
 * build, you can cheat (to test).
 
 * @param tile unused
 
 * @param flags operation to perform
 
 * @param p1 the amount of money to receive (if negative), or spend (if positive)
 
 * @param p2 unused
 
 */
src/misc_gui.cpp
Show inline comments
 
@@ -1132,55 +1132,55 @@ bool QueryString::HasEditBoxFocus(const 
 
HandleEditBoxResult QueryString::HandleEditBoxKey(Window *w, int wid, uint16 key, uint16 keycode, Window::EventState &state)
 
{
 
	if (!QueryString::HasEditBoxFocus(w, wid)) return HEBR_NOT_FOCUSED;
 

	
 
	state = Window::ES_HANDLED;
 

	
 
	switch (keycode) {
 
		case WKC_ESC: return HEBR_CANCEL;
 

	
 
		case WKC_RETURN: case WKC_NUM_ENTER: return HEBR_CONFIRM;
 

	
 
		case (WKC_CTRL | 'V'):
 
			if (InsertTextBufferClipboard(&this->text)) w->InvalidateWidget(wid);
 
			if (InsertTextBufferClipboard(&this->text)) w->SetWidgetDirty(wid);
 
			break;
 

	
 
		case (WKC_CTRL | 'U'):
 
			DeleteTextBufferAll(&this->text);
 
			w->InvalidateWidget(wid);
 
			w->SetWidgetDirty(wid);
 
			break;
 

	
 
		case WKC_BACKSPACE: case WKC_DELETE:
 
			if (DeleteTextBufferChar(&this->text, keycode)) w->InvalidateWidget(wid);
 
			if (DeleteTextBufferChar(&this->text, keycode)) w->SetWidgetDirty(wid);
 
			break;
 

	
 
		case WKC_LEFT: case WKC_RIGHT: case WKC_END: case WKC_HOME:
 
			if (MoveTextBufferPos(&this->text, keycode)) w->InvalidateWidget(wid);
 
			if (MoveTextBufferPos(&this->text, keycode)) w->SetWidgetDirty(wid);
 
			break;
 

	
 
		default:
 
			if (IsValidChar(key, this->afilter)) {
 
				if (InsertTextBufferChar(&this->text, key)) w->InvalidateWidget(wid);
 
				if (InsertTextBufferChar(&this->text, key)) w->SetWidgetDirty(wid);
 
			} else {
 
				state = Window::ES_NOT_HANDLED;
 
			}
 
	}
 

	
 
	return HEBR_EDITING;
 
}
 

	
 
void QueryString::HandleEditBox(Window *w, int wid)
 
{
 
	if (HasEditBoxFocus(w, wid) && HandleCaret(&this->text)) {
 
		w->InvalidateWidget(wid);
 
		w->SetWidgetDirty(wid);
 
		/* When we're not the OSK, notify 'our' OSK to redraw the widget,
 
		 * so the caret changes appropriately. */
 
		if (w->window_class != WC_OSK) {
 
			Window *w_osk = FindWindowById(WC_OSK, 0);
 
			if (w_osk != NULL && w_osk->parent == w) w_osk->OnInvalidateData();
 
		}
 
	}
 
}
 

	
 
void QueryString::DrawEditBox(Window *w, int wid)
 
{
 
	int left;
 
@@ -1923,25 +1923,25 @@ public:
 
						delete this;
 
					} else if (_saveload_mode == SLD_LOAD_HEIGHTMAP) {
 
						SetFiosType(file->type);
 
						strecpy(_file_to_saveload.name, name, lastof(_file_to_saveload.name));
 
						strecpy(_file_to_saveload.title, file->title, lastof(_file_to_saveload.title));
 

	
 
						delete this;
 
						ShowHeightmapLoad();
 
					} else {
 
						/* SLD_SAVE_GAME, SLD_SAVE_SCENARIO copy clicked name to editbox */
 
						ttd_strlcpy(this->text.buf, file->title, this->text.maxsize);
 
						UpdateTextBufferSize(&this->text);
 
						this->InvalidateWidget(SLWW_SAVE_OSK_TITLE);
 
						this->SetWidgetDirty(SLWW_SAVE_OSK_TITLE);
 
					}
 
				} else {
 
					/* Changed directory, need repaint. */
 
					this->SetDirty();
 
					BuildFileList();
 
				}
 
				break;
 
			}
 

	
 
			case SLWW_CONTENT_DOWNLOAD:
 
				if (!_network_available) {
 
					ShowErrorMessage(INVALID_STRING_ID, STR_NETWORK_ERROR_NOTAVAILABLE, 0, 0);
 
@@ -2069,25 +2069,25 @@ void ShowSaveLoadDialog(SaveLoadDialogMo
 
		default:
 
			sld = &_load_dialog_desc; break;
 
	}
 

	
 
	_saveload_mode = mode;
 
	_file_to_saveload.filetype = _file_modetotype[mode];
 

	
 
	new SaveLoadWindow(sld, mode);
 
}
 

	
 
void RedrawAutosave()
 
{
 
	InvalidateWindow(WC_STATUS_BAR, 0);
 
	SetWindowDirty(WC_STATUS_BAR, 0);
 
}
 

	
 
void SetFiosType(const byte fiostype)
 
{
 
	switch (fiostype) {
 
		case FIOS_TYPE_FILE:
 
		case FIOS_TYPE_SCENARIO:
 
			_file_to_saveload.mode = SL_LOAD;
 
			break;
 

	
 
		case FIOS_TYPE_OLDFILE:
 
		case FIOS_TYPE_OLD_SCENARIO:
src/music_gui.cpp
Show inline comments
 
@@ -139,46 +139,46 @@ static void SelectSongToPlay()
 
				*a = *b;
 
				*b = t;
 
			}
 
		} while (--i);
 
	}
 
}
 

	
 
static void StopMusic()
 
{
 
	_music_wnd_cursong = 0;
 
	DoStopMusic();
 
	_song_is_active = false;
 
	InvalidateWindowWidget(WC_MUSIC_WINDOW, 0, 9);
 
	SetWindowWidgetDirty(WC_MUSIC_WINDOW, 0, 9);
 
}
 

	
 
static void PlayPlaylistSong()
 
{
 
	if (_cur_playlist[0] == 0) {
 
		SelectSongToPlay();
 
		/* if there is not songs in the playlist, it may indicate
 
		 * no file on the gm folder, or even no gm folder.
 
		 * Stop the playback, then */
 
		if (_cur_playlist[0] == 0) {
 
			_song_is_active = false;
 
			_music_wnd_cursong = 0;
 
			msf.playing = false;
 
			return;
 
		}
 
	}
 
	_music_wnd_cursong = _cur_playlist[0];
 
	DoPlaySong();
 
	_song_is_active = true;
 

	
 
	InvalidateWindowWidget(WC_MUSIC_WINDOW, 0, 9);
 
	SetWindowWidgetDirty(WC_MUSIC_WINDOW, 0, 9);
 
}
 

	
 
void ResetMusic()
 
{
 
	_music_wnd_cursong = 1;
 
	DoPlaySong();
 
}
 

	
 
void MusicLoop()
 
{
 
	if (!msf.playing && _song_is_active) {
 
		StopMusic();
 
@@ -591,48 +591,48 @@ struct MusicWindow : public Window {
 
				if (new_vol != *vol) {
 
					*vol = new_vol;
 
					if (widget == MW_MUSIC_VOL) MusicVolumeChanged(new_vol);
 
					this->SetDirty();
 
				}
 

	
 
				_left_button_clicked = false;
 
			} break;
 

	
 
			case MW_SHUFFLE: // toggle shuffle
 
				msf.shuffle ^= 1;
 
				this->SetWidgetLoweredState(MW_SHUFFLE, msf.shuffle);
 
				this->InvalidateWidget(MW_SHUFFLE);
 
				this->SetWidgetDirty(MW_SHUFFLE);
 
				StopMusic();
 
				SelectSongToPlay();
 
				this->SetDirty();
 
				break;
 

	
 
			case MW_PROGRAMME: // show track selection
 
				ShowMusicTrackSelection();
 
				break;
 

	
 
			case MW_ALL: case MW_OLD: case MW_NEW:
 
			case MW_EZY: case MW_CUSTOM1: case MW_CUSTOM2: // playlist
 
				SelectPlaylist(widget - MW_ALL);
 
				StopMusic();
 
				SelectSongToPlay();
 
				this->SetDirty();
 
				break;
 
		}
 
	}
 

	
 
#if 0
 
	virtual void OnTick()
 
	{
 
		this->InvalidateWidget(MW_GAUGE);
 
		this->SetWidgetDirty(MW_GAUGE);
 
	}
 
#endif
 
};
 

	
 
static const NWidgetPart _nested_music_window_widgets[] = {
 
	NWidget(NWID_HORIZONTAL),
 
		NWidget(WWT_CLOSEBOX, COLOUR_GREY, MW_CLOSE),
 
		NWidget(WWT_CAPTION, COLOUR_GREY, MW_CAPTION), SetDataTip(STR_MUSIC_JAZZ_JUKEBOX_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
 
	EndContainer(),
 

	
 
	NWidget(NWID_HORIZONTAL),
 
		NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, MW_PREV), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_SKIP_TO_PREV, STR_MUSIC_TOOLTIP_SKIP_TO_PREVIOUS_TRACK),
src/network/network.cpp
Show inline comments
 
@@ -432,25 +432,25 @@ static NetworkClientSocket *NetworkAlloc
 
	NetworkClientSocket *cs = new NetworkClientSocket(INVALID_CLIENT_ID);
 
	cs->sock = s;
 
	cs->last_frame = _frame_counter;
 
	cs->last_frame_server = _frame_counter;
 

	
 
	if (_network_server) {
 
		cs->client_id = _network_client_id++;
 
		NetworkClientInfo *ci = new NetworkClientInfo(cs->client_id);
 
		cs->SetInfo(ci);
 
		ci->client_playas = COMPANY_INACTIVE_CLIENT;
 
		ci->join_date = _date;
 

	
 
		InvalidateWindow(WC_CLIENT_LIST, 0);
 
		SetWindowDirty(WC_CLIENT_LIST, 0);
 
	}
 

	
 
	return cs;
 
}
 

	
 
/* Close a connection */
 
void NetworkCloseClient(NetworkClientSocket *cs, bool error)
 
{
 
	/*
 
	 * Sending a message just before leaving the game calls cs->Send_Packets.
 
	 * This might invoke this function, which means that when we close the
 
	 * connection after cs->Send_Packets we will close an already closed
 
@@ -480,25 +480,25 @@ void NetworkCloseClient(NetworkClientSoc
 

	
 
	/* When the client was PRE_ACTIVE, the server was in pause mode, so unpause */
 
	if (cs->status == STATUS_PRE_ACTIVE && (_pause_mode & PM_PAUSED_JOIN)) {
 
		DoCommandP(0, PM_PAUSED_JOIN, 0, CMD_PAUSE);
 
		NetworkServerSendChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_BROADCAST, 0, "", CLIENT_ID_SERVER, NETWORK_SERVER_MESSAGE_GAME_UNPAUSED_CONNECT_FAIL);
 
	}
 

	
 
	if (_network_server) {
 
		/* We just lost one client :( */
 
		if (cs->status >= STATUS_AUTH) _network_game_info.clients_on--;
 
		_network_clients_connected--;
 

	
 
		InvalidateWindow(WC_CLIENT_LIST, 0);
 
		SetWindowDirty(WC_CLIENT_LIST, 0);
 
	}
 

	
 
	delete cs->GetInfo();
 
	delete cs;
 
}
 

	
 
/* For the server, to accept new clients */
 
static void NetworkAcceptClients(SOCKET ls)
 
{
 
	for (;;) {
 
		struct sockaddr_storage sin;
 
		memset(&sin, 0, sizeof(sin));
src/network/network_client.cpp
Show inline comments
 
@@ -115,46 +115,46 @@ void HashCurrentCompanyPassword(const ch
 
 ************/
 

	
 
DEF_CLIENT_SEND_COMMAND(PACKET_CLIENT_COMPANY_INFO)
 
{
 
	/*
 
	 * Packet: CLIENT_COMPANY_INFO
 
	 * Function: Request company-info (in detail)
 
	 * Data:
 
	 *    <none>
 
	 */
 
	Packet *p;
 
	_network_join_status = NETWORK_JOIN_STATUS_GETTING_COMPANY_INFO;
 
	InvalidateWindow(WC_NETWORK_STATUS_WINDOW, 0);
 
	SetWindowDirty(WC_NETWORK_STATUS_WINDOW, 0);
 

	
 
	p = NetworkSend_Init(PACKET_CLIENT_COMPANY_INFO);
 
	MY_CLIENT->Send_Packet(p);
 
}
 

	
 
DEF_CLIENT_SEND_COMMAND(PACKET_CLIENT_JOIN)
 
{
 
	/*
 
	 * Packet: CLIENT_JOIN
 
	 * Function: Try to join the server
 
	 * Data:
 
	 *    String: OpenTTD Revision (norev000 if no revision)
 
	 *    String: Client Name (max NETWORK_NAME_LENGTH)
 
	 *    uint8:  Play as Company id (1..MAX_COMPANIES)
 
	 *    uint8:  Language ID
 
	 *    String: Unique id to find the client back in server-listing
 
	 */
 

	
 
	Packet *p;
 
	_network_join_status = NETWORK_JOIN_STATUS_AUTHORIZING;
 
	InvalidateWindow(WC_NETWORK_STATUS_WINDOW, 0);
 
	SetWindowDirty(WC_NETWORK_STATUS_WINDOW, 0);
 

	
 
	p = NetworkSend_Init(PACKET_CLIENT_JOIN);
 
	p->Send_string(_openttd_revision);
 
	p->Send_string(_settings_client.network.client_name); // Client name
 
	p->Send_uint8 (_network_join_as);     // PlayAs
 
	p->Send_uint8 (NETLANG_ANY);          // Language
 
	p->Send_string(_settings_client.network.network_id);
 
	MY_CLIENT->Send_Packet(p);
 
}
 

	
 
DEF_CLIENT_SEND_COMMAND(PACKET_CLIENT_NEWGRFS_CHECKED)
 
{
 
@@ -390,25 +390,25 @@ DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER
 
		company_info->money            = p->Recv_uint64();
 
		company_info->income           = p->Recv_uint64();
 
		company_info->performance      = p->Recv_uint16();
 
		company_info->use_password     = p->Recv_bool();
 
		for (int i = 0; i < NETWORK_VEHICLE_TYPES; i++)
 
			company_info->num_vehicle[i] = p->Recv_uint16();
 
		for (int i = 0; i < NETWORK_STATION_TYPES; i++)
 
			company_info->num_station[i] = p->Recv_uint16();
 
		company_info->ai               = p->Recv_bool();
 

	
 
		p->Recv_string(company_info->clients, sizeof(company_info->clients));
 

	
 
		InvalidateWindow(WC_NETWORK_WINDOW, 0);
 
		SetWindowDirty(WC_NETWORK_WINDOW, 0);
 

	
 
		return NETWORK_RECV_STATUS_OKAY;
 
	}
 

	
 
	return NETWORK_RECV_STATUS_CLOSE_QUERY;
 
}
 

	
 
/* This packet contains info about the client (playas and name)
 
 *  as client we save this in NetworkClientInfo, linked via 'client_id'
 
 *  which is always an unique number on a server. */
 
DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_CLIENT_INFO)
 
{
 
@@ -425,37 +425,37 @@ DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER
 
	if (ci != NULL) {
 
		if (playas == ci->client_playas && strcmp(name, ci->client_name) != 0) {
 
			/* Client name changed, display the change */
 
			NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, name);
 
		} else if (playas != ci->client_playas) {
 
			/* The client changed from client-player..
 
			 * Do not display that for now */
 
		}
 

	
 
		ci->client_playas = playas;
 
		strecpy(ci->client_name, name, lastof(ci->client_name));
 

	
 
		InvalidateWindow(WC_CLIENT_LIST, 0);
 
		SetWindowDirty(WC_CLIENT_LIST, 0);
 

	
 
		return NETWORK_RECV_STATUS_OKAY;
 
	}
 

	
 
	/* We don't have this client_id yet, find an empty client_id, and put the data there */
 
	ci = new NetworkClientInfo(client_id);
 
	ci->client_playas = playas;
 
	if (client_id == _network_own_client_id) MY_CLIENT->SetInfo(ci);
 

	
 
	strecpy(ci->client_name, name, lastof(ci->client_name));
 

	
 
	InvalidateWindow(WC_CLIENT_LIST, 0);
 
	SetWindowDirty(WC_CLIENT_LIST, 0);
 

	
 
	return NETWORK_RECV_STATUS_OKAY;
 
}
 

	
 
DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_ERROR)
 
{
 
	NetworkErrorCode error = (NetworkErrorCode)p->Recv_uint8();
 

	
 
	switch (error) {
 
		/* We made an error in the protocol, and our connection is closed.... */
 
		case NETWORK_ERROR_NOT_AUTHORIZED:
 
		case NETWORK_ERROR_NOT_EXPECTED:
 
@@ -551,25 +551,25 @@ DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER
 
	_password_game_seed = p->Recv_uint32();
 
	p->Recv_string(_password_server_unique_id, sizeof(_password_server_unique_id));
 

	
 
	/* Start receiving the map */
 
	SEND_COMMAND(PACKET_CLIENT_GETMAP)();
 
	return NETWORK_RECV_STATUS_OKAY;
 
}
 

	
 
DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_WAIT)
 
{
 
	_network_join_status = NETWORK_JOIN_STATUS_WAITING;
 
	_network_join_waiting = p->Recv_uint8();
 
	InvalidateWindow(WC_NETWORK_STATUS_WINDOW, 0);
 
	SetWindowDirty(WC_NETWORK_STATUS_WINDOW, 0);
 

	
 
	/* We are put on hold for receiving the map.. we need GUI for this ;) */
 
	DEBUG(net, 1, "The server is currently busy sending the map to someone else, please wait..." );
 
	DEBUG(net, 1, "There are %d clients in front of you", _network_join_waiting);
 

	
 
	return NETWORK_RECV_STATUS_OKAY;
 
}
 

	
 
DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_MAP)
 
{
 
	static FILE *file_pointer;
 

	
 
@@ -592,47 +592,47 @@ DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER
 
		_network_join_bytes = 0;
 
		_network_join_bytes_total = p->Recv_uint32();
 

	
 
		/* If the network connection has been closed due to loss of connection
 
		 * or when _network_join_kbytes_total is 0, the join status window will
 
		 * do a division by zero. When the connection is lost, we just return
 
		 * that. If kbytes_total is 0, the packet must be malformed as a
 
		 * savegame less than 1 kilobyte is practically impossible. */
 
		if (MY_CLIENT->HasClientQuit()) return NETWORK_RECV_STATUS_CONN_LOST;
 
		if (_network_join_bytes_total == 0) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
 

	
 
		_network_join_status = NETWORK_JOIN_STATUS_DOWNLOADING;
 
		InvalidateWindow(WC_NETWORK_STATUS_WINDOW, 0);
 
		SetWindowDirty(WC_NETWORK_STATUS_WINDOW, 0);
 

	
 
		/* The first packet does not contain any more data */
 
		return NETWORK_RECV_STATUS_OKAY;
 
	}
 

	
 
	if (maptype == MAP_PACKET_NORMAL) {
 
		/* We are still receiving data, put it to the file */
 
		if (fwrite(p->buffer + p->pos, 1, p->size - p->pos, file_pointer) != (size_t)(p->size - p->pos)) {
 
			_switch_mode_errorstr = STR_NETWORK_ERROR_SAVEGAMEERROR;
 
			return NETWORK_RECV_STATUS_SAVEGAME;
 
		}
 

	
 
		_network_join_bytes = ftell(file_pointer);
 
		InvalidateWindow(WC_NETWORK_STATUS_WINDOW, 0);
 
		SetWindowDirty(WC_NETWORK_STATUS_WINDOW, 0);
 
	}
 

	
 
	/* Check if this was the last packet */
 
	if (maptype == MAP_PACKET_END) {
 
		fclose(file_pointer);
 

	
 
		_network_join_status = NETWORK_JOIN_STATUS_PROCESSING;
 
		InvalidateWindow(WC_NETWORK_STATUS_WINDOW, 0);
 
		SetWindowDirty(WC_NETWORK_STATUS_WINDOW, 0);
 

	
 
		/* The map is done downloading, load it */
 
		if (!SafeSaveOrLoad("network_client.tmp", SL_LOAD, GM_NORMAL, AUTOSAVE_DIR)) {
 
			DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0);
 
			_switch_mode_errorstr = STR_NETWORK_ERROR_SAVEGAMEERROR;
 
			return NETWORK_RECV_STATUS_SAVEGAME;
 
		}
 
		/* If the savegame has successfully loaded, ALL windows have been removed,
 
		 * only toolbar/statusbar and gamefield are visible */
 

	
 
		/* Say we received the map and loaded it correctly! */
 
		SEND_COMMAND(PACKET_CLIENT_MAP_OK)();
 
@@ -766,58 +766,58 @@ DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER
 
}
 

	
 
DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_ERROR_QUIT)
 
{
 
	ClientID client_id = (ClientID)p->Recv_uint32();
 

	
 
	NetworkClientInfo *ci = NetworkFindClientInfoFromClientID(client_id);
 
	if (ci != NULL) {
 
		NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, ci->client_name, NULL, GetNetworkErrorMsg((NetworkErrorCode)p->Recv_uint8()));
 
		delete ci;
 
	}
 

	
 
	InvalidateWindow(WC_CLIENT_LIST, 0);
 
	SetWindowDirty(WC_CLIENT_LIST, 0);
 

	
 
	return NETWORK_RECV_STATUS_OKAY;
 
}
 

	
 
DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_QUIT)
 
{
 
	NetworkClientInfo *ci;
 

	
 
	ClientID client_id = (ClientID)p->Recv_uint32();
 

	
 
	ci = NetworkFindClientInfoFromClientID(client_id);
 
	if (ci != NULL) {
 
		NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, ci->client_name, NULL, STR_NETWORK_MESSAGE_CLIENT_LEAVING);
 
		delete ci;
 
	} else {
 
		DEBUG(net, 0, "Unknown client (%d) is leaving the game", client_id);
 
	}
 

	
 
	InvalidateWindow(WC_CLIENT_LIST, 0);
 
	SetWindowDirty(WC_CLIENT_LIST, 0);
 

	
 
	/* If we come here it means we could not locate the client.. strange :s */
 
	return NETWORK_RECV_STATUS_OKAY;
 
}
 

	
 
DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_JOIN)
 
{
 
	ClientID client_id = (ClientID)p->Recv_uint32();
 

	
 
	NetworkClientInfo *ci = NetworkFindClientInfoFromClientID(client_id);
 
	if (ci != NULL)
 
		NetworkTextMessage(NETWORK_ACTION_JOIN, CC_DEFAULT, false, ci->client_name);
 

	
 
	InvalidateWindow(WC_CLIENT_LIST, 0);
 
	SetWindowDirty(WC_CLIENT_LIST, 0);
 

	
 
	return NETWORK_RECV_STATUS_OKAY;
 
}
 

	
 
DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_SHUTDOWN)
 
{
 
	_switch_mode_errorstr = STR_NETWORK_MESSAGE_SERVER_SHUTDOWN;
 

	
 
	return NETWORK_RECV_STATUS_SERVER_ERROR;
 
}
 

	
 
DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_NEWGAME)
 
@@ -872,25 +872,25 @@ DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER
 

	
 
DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_CONFIG_UPDATE)
 
{
 
	_network_server_max_companies = p->Recv_uint8();
 
	_network_server_max_spectators = p->Recv_uint8();
 

	
 
	return NETWORK_RECV_STATUS_OKAY;
 
}
 

	
 
DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_COMPANY_UPDATE)
 
{
 
	_network_company_passworded = p->Recv_uint16();
 
	InvalidateWindowClasses(WC_COMPANY);
 
	SetWindowClassesDirty(WC_COMPANY);
 

	
 
	return NETWORK_RECV_STATUS_OKAY;
 
}
 

	
 

	
 
/* The layout for the receive-functions by the client */
 
typedef NetworkRecvStatus NetworkClientPacket(Packet *p);
 

	
 
/* This array matches PacketType. At an incoming
 
 *  packet it is matches against this array
 
 *  and that way the right function to handle that
 
 *  packet is found. */
src/network/network_content_gui.cpp
Show inline comments
 
@@ -86,35 +86,35 @@ public:
 
		this->InitNested(&_network_content_download_status_window_desc, 0);
 
	}
 

	
 
	/** Free whatever we've allocated */
 
	~NetworkContentDownloadStatusWindow()
 
	{
 
		/* Tell all the backends about what we've downloaded */
 
		for (ContentType *iter = this->receivedTypes.Begin(); iter != this->receivedTypes.End(); iter++) {
 
			switch (*iter) {
 
				case CONTENT_TYPE_AI:
 
				case CONTENT_TYPE_AI_LIBRARY:
 
					AI::Rescan();
 
					InvalidateWindowClasses(WC_AI_DEBUG);
 
					SetWindowClassesDirty(WC_AI_DEBUG);
 
					break;
 

	
 
				case CONTENT_TYPE_BASE_GRAPHICS:
 
					BaseGraphics::FindSets();
 
					InvalidateWindow(WC_GAME_OPTIONS, 0);
 
					SetWindowDirty(WC_GAME_OPTIONS, 0);
 
					break;
 

	
 
				case CONTENT_TYPE_BASE_SOUNDS:
 
					BaseSounds::FindSets();
 
					InvalidateWindow(WC_GAME_OPTIONS, 0);
 
					SetWindowDirty(WC_GAME_OPTIONS, 0);
 
					break;
 

	
 
				case CONTENT_TYPE_NEWGRF:
 
					ScanNewGRFFiles();
 
					/* Yes... these are the NewGRF windows */
 
					InvalidateWindowClassesData(WC_SAVELOAD);
 
					InvalidateWindowData(WC_GAME_OPTIONS, 0, 1);
 
					InvalidateWindowData(WC_NETWORK_WINDOW, 1, 2);
 
					break;
 

	
 
				case CONTENT_TYPE_SCENARIO:
 
				case CONTENT_TYPE_HEIGHTMAP:
src/network/network_gui.cpp
Show inline comments
 
@@ -1194,25 +1194,25 @@ struct NetworkStartServerWindow : public
 

	
 
		return state;
 
	}
 

	
 
	virtual void OnQueryTextFinished(char *str)
 
	{
 
		if (str == NULL) return;
 

	
 
		if (this->widget_id == NSSW_SETPWD) {
 
			strecpy(_settings_client.network.server_password, str, lastof(_settings_client.network.server_password));
 
		} else {
 
			int32 value = atoi(str);
 
			this->InvalidateWidget(this->widget_id);
 
			this->SetWidgetDirty(this->widget_id);
 
			switch (this->widget_id) {
 
				default: NOT_REACHED();
 
				case NSSW_CLIENTS_TXT:    _settings_client.network.max_clients    = Clamp(value, 2, MAX_CLIENTS); break;
 
				case NSSW_COMPANIES_TXT:  _settings_client.network.max_companies  = Clamp(value, 1, MAX_COMPANIES); break;
 
				case NSSW_SPECTATORS_TXT: _settings_client.network.max_spectators = Clamp(value, 0, MAX_CLIENTS); break;
 
			}
 
		}
 

	
 
		this->SetDirty();
 
	}
 
};
 

	
src/network/network_server.cpp
Show inline comments
 
@@ -1724,25 +1724,25 @@ void NetworkServerSendConfigUpdate()
 
	NetworkClientSocket *cs;
 

	
 
	FOR_ALL_CLIENT_SOCKETS(cs) {
 
		SEND_COMMAND(PACKET_SERVER_CONFIG_UPDATE)(cs);
 
	}
 
}
 

	
 
void NetworkServerUpdateCompanyPassworded(CompanyID company_id, bool passworded)
 
{
 
	if (NetworkCompanyIsPassworded(company_id) == passworded) return;
 

	
 
	SB(_network_company_passworded, company_id, 1, !!passworded);
 
	InvalidateWindowClasses(WC_COMPANY);
 
	SetWindowClassesDirty(WC_COMPANY);
 

	
 
	NetworkClientSocket *cs;
 
	FOR_ALL_CLIENT_SOCKETS(cs) {
 
		SEND_COMMAND(PACKET_SERVER_COMPANY_UPDATE)(cs);
 
	}
 
}
 

	
 
/**
 
 * Handle the tid-bits of moving a client from one company to another.
 
 * @param client_id id of the client we want to move.
 
 * @param company_id id of the company we want to move the client to.
 
 * @return void
src/newgrf_industries.cpp
Show inline comments
 
@@ -548,14 +548,14 @@ void IndustryProductionCallback(Industry
 
			ind->incoming_cargo_waiting[i] = Clamp(ind->incoming_cargo_waiting[i] - DerefIndProd(group->substract_input[i], deref) * multiplier, 0, 0xFFFF);
 
		}
 
		for (uint i = 0; i < 2; i++) {
 
			ind->produced_cargo_waiting[i] = Clamp(ind->produced_cargo_waiting[i] + max(DerefIndProd(group->add_output[i], deref), 0) * multiplier, 0, 0xFFFF);
 
		}
 

	
 
		int32 again = DerefIndProd(group->again, deref);
 
		if (again == 0) break;
 

	
 
		SB(object.callback_param2, 24, 8, again);
 
	}
 

	
 
	InvalidateWindow(WC_INDUSTRY_VIEW, ind->index);
 
	SetWindowDirty(WC_INDUSTRY_VIEW, ind->index);
 
}
src/news_gui.cpp
Show inline comments
 
@@ -681,25 +681,25 @@ void AddNewsItem(StringID string, NewsSu
 
		assert(_oldest_news == NULL);
 
		_oldest_news = ni;
 
		ni->prev = NULL;
 
	} else {
 
		assert(_latest_news->next == NULL);
 
		_latest_news->next = ni;
 
		ni->prev = _latest_news;
 
	}
 

	
 
	ni->next = NULL;
 
	_latest_news = ni;
 

	
 
	InvalidateWindow(WC_MESSAGE_HISTORY, 0);
 
	SetWindowDirty(WC_MESSAGE_HISTORY, 0);
 
}
 

	
 
/** Delete a news item from the queue */
 
static void DeleteNewsItem(NewsItem *ni)
 
{
 
	if (_forced_news == ni || _current_news == ni) {
 
		/* about to remove the currently forced item (shown as newspapers) ||
 
		 * about to remove the currently displayed item (newspapers, ticker, or just a reminder) */
 
		MoveToNextItem();
 
	}
 

	
 
	/* delete item */
 
@@ -715,25 +715,25 @@ static void DeleteNewsItem(NewsItem *ni)
 
		ni->next->prev = ni->prev;
 
	} else {
 
		assert(_latest_news == ni);
 
		_latest_news = ni->prev;
 
	}
 

	
 
	free(ni->free_data);
 

	
 
	if (_current_news == ni) _current_news = ni->prev;
 
	_total_news--;
 
	delete ni;
 

	
 
	InvalidateWindow(WC_MESSAGE_HISTORY, 0);
 
	SetWindowDirty(WC_MESSAGE_HISTORY, 0);
 
}
 

	
 
void DeleteVehicleNews(VehicleID vid, StringID news)
 
{
 
	NewsItem *ni = _oldest_news;
 

	
 
	while (ni != NULL) {
 
		NewsItem *next = ni->next;
 
		if (((ni->reftype1 == NR_VEHICLE && ni->ref1 == vid) || (ni->reftype2 == NR_VEHICLE && ni->ref2 == vid)) &&
 
				(news == INVALID_STRING_ID || ni->string_id == news)) {
 
			DeleteNewsItem(ni);
 
		}
 
@@ -1151,25 +1151,25 @@ struct MessageOptionsWindow : Window {
 
	}
 

	
 
	virtual void OnClick(Point pt, int widget)
 
	{
 
		switch (widget) {
 
			case WIDGET_NEWSOPT_DROP_SUMMARY: // Dropdown menu for all settings
 
				ShowDropDownMenu(this, this->message_opt, this->state, WIDGET_NEWSOPT_DROP_SUMMARY, 0, 0);
 
				break;
 

	
 
			case WIDGET_NEWSOPT_SOUNDTICKER: // Change ticker sound on/off
 
				_news_ticker_sound ^= 1;
 
				this->OnInvalidateData(0);
 
				this->InvalidateWidget(widget);
 
				this->SetWidgetDirty(widget);
 
				break;
 

	
 
			default: { // Clicked on the [<] .. [>] widgets
 
				if (widget >= WIDGET_NEWSOPT_START_OPTION && widget < WIDGET_NEWSOPT_END_OPTION) {
 
					int wid = widget - WIDGET_NEWSOPT_START_OPTION;
 
					int element = wid / MOS_WIDG_PER_SETTING;
 
					byte val = (_news_type_data[element].display + ((wid % MOS_WIDG_PER_SETTING) ? 1 : -1)) % 3;
 

	
 
					this->SetMessageButtonStates(val, element);
 
					_news_type_data[element].display = (NewsDisplay)val;
 
					this->SetDirty();
 
				}
src/openttd.cpp
Show inline comments
 
@@ -593,25 +593,25 @@ int ttd_main(int argc, char *argv[])
 
	/* initialize screenshot formats */
 
	InitializeScreenshotFormats();
 

	
 
	/* initialize airport state machines */
 
	InitializeAirports();
 

	
 
	/* initialize all variables that are allocated dynamically */
 
	InitializeDynamicVariables();
 

	
 
	/* Initialize FreeType */
 
	InitFreeType();
 

	
 
	/* This must be done early, since functions use the InvalidateWindow* calls */
 
	/* This must be done early, since functions use the SetWindowDirty* calls */
 
	InitWindowSystem();
 

	
 
	/* Look for the sounds before the graphics. Otherwise none would be set and
 
	 * the first initialisation of the video happens on the wrong data. Now it
 
	 * can do the first initialisation right. */
 
	if (sounds_set == NULL && BaseSounds::ini_set != NULL) sounds_set = strdup(BaseSounds::ini_set);
 
	if (!BaseSounds::SetSet(sounds_set)) {
 
		StrEmpty(sounds_set) ?
 
			usererror("Failed to find a sounds set. Please acquire a sounds set for OpenTTD.") :
 
			usererror("Failed to select requested sounds set '%s'", sounds_set);
 
	}
 
	free(sounds_set);
src/order_cmd.cpp
Show inline comments
 
@@ -170,35 +170,35 @@ Order::Order(uint32 packed)
 
	this->refit_subtype = 0;
 
	this->wait_time     = 0;
 
	this->travel_time   = 0;
 
}
 

	
 
/**
 
 *
 
 * Updates the widgets of a vehicle which contains the order-data
 
 *
 
 */
 
void InvalidateVehicleOrder(const Vehicle *v, int data)
 
{
 
	InvalidateWindow(WC_VEHICLE_VIEW, v->index);
 
	SetWindowDirty(WC_VEHICLE_VIEW, v->index);
 

	
 
	if (data != 0) {
 
		/* Calls SetDirty() too */
 
		InvalidateWindowData(WC_VEHICLE_ORDERS,    v->index, data);
 
		InvalidateWindowData(WC_VEHICLE_TIMETABLE, v->index, data);
 
		return;
 
	}
 

	
 
	InvalidateWindow(WC_VEHICLE_ORDERS,    v->index);
 
	InvalidateWindow(WC_VEHICLE_TIMETABLE, v->index);
 
	SetWindowDirty(WC_VEHICLE_ORDERS,    v->index);
 
	SetWindowDirty(WC_VEHICLE_TIMETABLE, v->index);
 
}
 

	
 
/**
 
 *
 
 * Assign data to an order (from an other order)
 
 *   This function makes sure that the index is maintained correctly
 
 *
 
 */
 
void Order::AssignOrder(const Order &other)
 
{
 
	this->type  = other.type;
 
	this->flags = other.flags;
 
@@ -786,26 +786,26 @@ CommandCost CmdSkipToOrder(TileIndex til
 

	
 
	if (flags & DC_EXEC) {
 
		v->cur_order_index = sel_ord;
 

	
 
		if (v->type == VEH_ROAD) ClearSlot(RoadVehicle::From(v));
 

	
 
		if (v->current_order.IsType(OT_LOADING)) v->LeaveStation();
 

	
 
		InvalidateVehicleOrder(v, -2);
 
	}
 

	
 
	/* We have an aircraft/ship, they have a mini-schedule, so update them all */
 
	if (v->type == VEH_AIRCRAFT) InvalidateWindowClasses(WC_AIRCRAFT_LIST);
 
	if (v->type == VEH_SHIP) InvalidateWindowClasses(WC_SHIPS_LIST);
 
	if (v->type == VEH_AIRCRAFT) SetWindowClassesDirty(WC_AIRCRAFT_LIST);
 
	if (v->type == VEH_SHIP) SetWindowClassesDirty(WC_SHIPS_LIST);
 

	
 
	return CommandCost();
 
}
 

	
 
/**
 
 * Move an order inside the orderlist
 
 * @param tile unused
 
 * @param p1 the ID of the vehicle
 
 * @param p2 order to move and target
 
 *           bit 0-15  : the order to move
 
 *           bit 16-31 : the target order
 
 * @note The target order will move one place down in the orderlist
 
@@ -1506,25 +1506,25 @@ void RemoveOrderFromAllVehicles(OrderTyp
 
	/* Aircraft have StationIDs for depot orders and never use DepotIDs
 
	 * This fact is handled specially below
 
	 */
 

	
 
	/* Go through all vehicles */
 
	FOR_ALL_VEHICLES(v) {
 
		Order *order;
 

	
 
		order = &v->current_order;
 
		if ((v->type == VEH_AIRCRAFT && order->IsType(OT_GOTO_DEPOT) ? OT_GOTO_STATION : order->GetType()) == type &&
 
				v->current_order.GetDestination() == destination) {
 
			order->MakeDummy();
 
			InvalidateWindow(WC_VEHICLE_VIEW, v->index);
 
			SetWindowDirty(WC_VEHICLE_VIEW, v->index);
 
		}
 

	
 
		/* Clear the order from the order-list */
 
		int id = -1;
 
		FOR_VEHICLE_ORDERS(v, order) {
 
			id++;
 
			if (order->IsType(OT_GOTO_DEPOT) && (order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) != 0) continue;
 
			if ((v->type == VEH_AIRCRAFT && order->IsType(OT_GOTO_DEPOT) ? OT_GOTO_STATION : order->GetType()) == type &&
 
					order->GetDestination() == destination) {
 
				order->MakeDummy();
 
				for (const Vehicle *w = v->FirstShared(); w != NULL; w = w->NextShared()) {
 
					/* In GUI, simulate by removing the order and adding it back */
 
@@ -1797,25 +1797,25 @@ bool ProcessOrders(Vehicle *v)
 

	
 
	InvalidateVehicleOrder(v, -2);
 
	switch (v->type) {
 
		default:
 
			NOT_REACHED();
 

	
 
		case VEH_ROAD:
 
		case VEH_TRAIN:
 
			break;
 

	
 
		case VEH_AIRCRAFT:
 
		case VEH_SHIP:
 
			InvalidateWindowClasses(GetWindowClassForVehicleType(v->type));
 
			SetWindowClassesDirty(GetWindowClassForVehicleType(v->type));
 
			break;
 
	}
 

	
 
	return UpdateOrderDest(v, order) && may_reverse;
 
}
 

	
 
/**
 
 * Check whether the given vehicle should stop at the given station
 
 * based on this order and the non-stop settings.
 
 * @param v       the vehicle that might be stopping.
 
 * @param station the station to stop at.
 
 * @return true if the vehicle should stop.
src/order_gui.cpp
Show inline comments
 
@@ -447,25 +447,25 @@ private:
 
			ResetObjectToPlace();
 
		}
 

	
 
		return true;
 
	}
 

	
 
	/**
 
	 * Handle the click on the goto button.
 
	 * @param i Dummy parameter.
 
	 */
 
	void OrderClick_Goto(int i)
 
	{
 
		this->InvalidateWidget(ORDER_WIDGET_GOTO);
 
		this->SetWidgetDirty(ORDER_WIDGET_GOTO);
 
		this->ToggleWidgetLoweredState(ORDER_WIDGET_GOTO);
 
		if (this->IsWidgetLowered(ORDER_WIDGET_GOTO)) {
 
			_place_clicked_vehicle = NULL;
 
			SetObjectToPlaceWnd(ANIMCURSOR_PICKSTATION, PAL_NONE, HT_RECT, this);
 
			this->goto_type = OPOS_GOTO;
 
		} else {
 
			ResetObjectToPlace();
 
		}
 
	}
 

	
 
	/**
 
	 * Handle the click on the full load button.
 
@@ -512,25 +512,25 @@ private:
 
				_settings_client.gui.new_nonstop && (this->vehicle->type == VEH_TRAIN || this->vehicle->type == VEH_ROAD) ? ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS : ONSF_STOP_EVERYWHERE);
 
		order.SetDepotActionType(ODATFB_NEAREST_DEPOT);
 

	
 
		DoCommandP(this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 16), order.Pack(), CMD_INSERT_ORDER | CMD_MSG(STR_ERROR_CAN_T_INSERT_NEW_ORDER));
 
	}
 

	
 
	/**
 
	 * Handle the click on the conditional order button.
 
	 * @param i Dummy parameter.
 
	 */
 
	void OrderClick_Conditional(int i)
 
	{
 
		this->InvalidateWidget(ORDER_WIDGET_GOTO);
 
		this->SetWidgetDirty(ORDER_WIDGET_GOTO);
 
		this->LowerWidget(ORDER_WIDGET_GOTO);
 
		SetObjectToPlaceWnd(ANIMCURSOR_PICKSTATION, PAL_NONE, HT_RECT, this);
 
		this->goto_type = OPOS_CONDITIONAL;
 
	}
 

	
 
	/**
 
	 * Handle the click on the unload button.
 
	 */
 
	void OrderClick_Unload(int unload_type)
 
	{
 
		VehicleOrderID sel_ord = this->OrderGetSel();
 
		const Order *order = this->vehicle->GetOrder(sel_ord);
 
@@ -551,25 +551,25 @@ private:
 
	void OrderClick_Nonstop(int non_stop)
 
	{
 
		VehicleOrderID sel_ord = this->OrderGetSel();
 
		const Order *order = this->vehicle->GetOrder(sel_ord);
 

	
 
		if (order == NULL || order->GetNonStopType() == non_stop) return;
 

	
 
		/* Keypress if negative, so 'toggle' to the next */
 
		if (non_stop < 0) {
 
			non_stop = order->GetNonStopType() ^ ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS;
 
		}
 

	
 
		this->InvalidateWidget(ORDER_WIDGET_NON_STOP);
 
		this->SetWidgetDirty(ORDER_WIDGET_NON_STOP);
 
		DoCommandP(this->vehicle->tile, this->vehicle->index + (sel_ord << 16), MOF_NON_STOP | non_stop << 4,  CMD_MODIFY_ORDER | CMD_MSG(STR_ERROR_CAN_T_MODIFY_THIS_ORDER));
 
	}
 

	
 
	/**
 
	 * Handle the click on the skip button.
 
	 * If ctrl is pressed, skip to selected order, else skip to current order + 1
 
	 * @param i Dummy parameter.
 
	 */
 
	void OrderClick_Skip(int i)
 
	{
 
		/* Don't skip when there's nothing to skip */
 
		if (_ctrl_pressed && this->vehicle->cur_order_index == this->OrderGetSel()) return;
 
@@ -1129,25 +1129,25 @@ public:
 
				int order_id = this->GetOrderFromPt(_cursor.pos.y - this->top);
 
				if (order_id != INVALID_ORDER) {
 
					Order order;
 
					order.next = NULL;
 
					order.index = 0;
 
					order.MakeConditional(order_id);
 

	
 
					DoCommandP(this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 16), order.Pack(), CMD_INSERT_ORDER | CMD_MSG(STR_ERROR_CAN_T_INSERT_NEW_ORDER));
 
				}
 
			}
 
		}
 
		this->RaiseWidget(ORDER_WIDGET_GOTO);
 
		this->InvalidateWidget(ORDER_WIDGET_GOTO);
 
		this->SetWidgetDirty(ORDER_WIDGET_GOTO);
 
	}
 

	
 
	virtual void OnMouseLoop()
 
	{
 
		const Vehicle *v = _place_clicked_vehicle;
 
		/*
 
		 * Check if we clicked on a vehicle
 
		 * and if the GOTO button of this window is pressed
 
		 * This is because of all open order windows WE_MOUSELOOP is called
 
		 * and if you have 3 windows open, and this check is not done
 
		 * the order is copied to the last open window instead of the
 
		 * one where GOTO is enabled
 
@@ -1224,25 +1224,25 @@ public:
 
				SetWidgetLeftRight(ORDER_WIDGET_SERVICE_DROPDOWN, middle, rightmost - 1);
 
				SetWidgetLeftRight(ORDER_WIDGET_SERVICE, middle, rightmost - 1 - arrow_width);
 
			}
 
		}
 
	}
 

	
 
	virtual void OnTimeout()
 
	{
 
		/* unclick all buttons except for the 'goto' button (ORDER_WIDGET_GOTO), which is 'persistent' */
 
		for (uint i = 0; i < this->widget_count; i++) {
 
			if (this->IsWidgetLowered(i) && i != ORDER_WIDGET_GOTO) {
 
				this->RaiseWidget(i);
 
				this->InvalidateWidget(i);
 
				this->SetWidgetDirty(i);
 
			}
 
		}
 
	}
 
};
 

	
 
/**
 
 * Widget definition for "your" train orders
 
 */
 
static const Widget _orders_train_widgets[] = {
 
	{   WWT_CLOSEBOX,   RESIZE_NONE,   COLOUR_GREY,     0,    10,     0,    13, STR_BLACK_CROSS,            STR_TOOLTIP_CLOSE_WINDOW},                 // ORDER_WIDGET_CLOSEBOX
 
	{    WWT_CAPTION,   RESIZE_RIGHT,  COLOUR_GREY,    11,   371,     0,    13, STR_ORDERS_CAPTION,         STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS},       // ORDER_WIDGET_CAPTION
 
	{ WWT_PUSHTXTBTN,   RESIZE_LR,     COLOUR_GREY,   311,   371,     0,    13, STR_ORDERS_TIMETABLE_VIEW,  STR_ORDERS_TIMETABLE_VIEW_TOOLTIP},               // ORDER_WIDGET_TIMETABLE_VIEW
src/osk_gui.cpp
Show inline comments
 
@@ -236,38 +236,38 @@ struct OskWindow : public Window {
 
					this->InvalidateParent();
 
					delete this;
 
				}
 
				break;
 
		}
 
	}
 

	
 
	void InvalidateParent()
 
	{
 
		QueryStringBaseWindow *w = dynamic_cast<QueryStringBaseWindow*>(this->parent);
 
		if (w != NULL) w->OnOSKInput(this->text_btn);
 

	
 
		this->InvalidateWidget(OSK_WIDGET_TEXT);
 
		if (this->parent != NULL) this->parent->InvalidateWidget(this->text_btn);
 
		this->SetWidgetDirty(OSK_WIDGET_TEXT);
 
		if (this->parent != NULL) this->parent->SetWidgetDirty(this->text_btn);
 
	}
 

	
 
	virtual void OnMouseLoop()
 
	{
 
		this->qs->HandleEditBox(this, OSK_WIDGET_TEXT);
 
		/* make the caret of the parent window also blink */
 
		this->parent->InvalidateWidget(this->text_btn);
 
		this->parent->SetWidgetDirty(this->text_btn);
 
	}
 

	
 
	virtual void OnInvalidateData(int)
 
	{
 
		this->InvalidateWidget(OSK_WIDGET_TEXT);
 
		this->SetWidgetDirty(OSK_WIDGET_TEXT);
 
	}
 
};
 

	
 
static const Widget _osk_widgets[] = {
 
{    WWT_CAPTION, RESIZE_NONE,  COLOUR_GREY,     0,   255,     0,    13, STR_WHITE_STRING,  STR_NULL}, // OSK_WIDGET_CAPTION
 
{      WWT_PANEL, RESIZE_NONE,  COLOUR_GREY,     0,   255,    14,    29, 0x0,               STR_NULL}, // OSK_WIDGET_TEXT_BACKGROUND
 
{    WWT_EDITBOX, RESIZE_NONE,  COLOUR_GREY,     2,   253,    16,    27, 0x0,               STR_NULL}, // OSK_WIDGET_TEXT
 

	
 
{      WWT_PANEL, RESIZE_NONE,  COLOUR_GREY,     0,   255,    30,   139, 0x0,               STR_NULL}, // OSK_WIDGET_KEYS_BACKGROUND
 

	
 
{    WWT_TEXTBTN, RESIZE_NONE,  COLOUR_GREY,     3,   108,    35,    46, STR_BUTTON_CANCEL, STR_NULL}, // OSK_WIDGET_CANCEL
 
{    WWT_TEXTBTN, RESIZE_NONE,  COLOUR_GREY,   111,   216,    35,    46, STR_BUTTON_OK,     STR_NULL}, // OSK_WIDGET_OK
src/rail_gui.cpp
Show inline comments
 
@@ -305,25 +305,25 @@ enum RailToolbarWidgets {
 
	RTW_REMOVE,
 
	RTW_CONVERT_RAIL,
 
};
 

	
 

	
 
/** Toggles state of the Remove button of Build rail toolbar
 
 * @param w window the button belongs to
 
 */
 
static void ToggleRailButton_Remove(Window *w)
 
{
 
	DeleteWindowById(WC_SELECT_STATION, 0);
 
	w->ToggleWidgetLoweredState(RTW_REMOVE);
 
	w->InvalidateWidget(RTW_REMOVE);
 
	w->SetWidgetDirty(RTW_REMOVE);
 
	_remove_button_clicked = w->IsWidgetLowered(RTW_REMOVE);
 
	SetSelectionRed(_remove_button_clicked);
 
}
 

	
 
/** Updates the Remove button because of Ctrl state change
 
 * @param w window the button belongs to
 
 * @return true iff the remove buton was changed
 
 */
 
static bool RailToolbar_CtrlChanged(Window *w)
 
{
 
	if (w->IsWidgetDisabled(RTW_REMOVE)) return false;
 

	
 
@@ -786,25 +786,25 @@ struct BuildRailToolbarWindow : Window {
 
							ShowSelectWaypointIfNeeded(cmdcont, ta);
 
						}
 
					}
 
					break;
 
			}
 
		}
 
	}
 

	
 
	virtual void OnPlaceObjectAbort()
 
	{
 
		this->RaiseButtons();
 
		this->DisableWidget(RTW_REMOVE);
 
		this->InvalidateWidget(RTW_REMOVE);
 
		this->SetWidgetDirty(RTW_REMOVE);
 

	
 
		DeleteWindowById(WC_BUILD_SIGNAL, TRANSPORT_RAIL);
 
		DeleteWindowById(WC_BUILD_STATION, TRANSPORT_RAIL);
 
		DeleteWindowById(WC_BUILD_DEPOT, TRANSPORT_RAIL);
 
		DeleteWindowById(WC_SELECT_STATION, 0);
 
		DeleteWindowByClass(WC_BUILD_BRIDGE);
 
	}
 

	
 
	virtual void OnPlacePresize(Point pt, TileIndex tile)
 
	{
 
		DoCommand(tile, _cur_railtype, 0, DC_AUTO, CMD_BUILD_TUNNEL);
 
		VpSetPresizeRange(tile, _build_tunnel_endtile == 0 ? tile : _build_tunnel_endtile);
 
@@ -1592,32 +1592,32 @@ public:
 

	
 
				_cur_signal_type = (SignalType)((uint)((widget - BSW_SEMAPHORE_NORM) % (SIGTYPE_LAST + 1)));
 
				_cur_signal_variant = widget >= BSW_ELECTRIC_NORM ? SIG_ELECTRIC : SIG_SEMAPHORE;
 
				break;
 

	
 
			case BSW_CONVERT:
 
				_convert_signal_button = !_convert_signal_button;
 
				break;
 

	
 
			case BSW_DRAG_SIGNALS_DENSITY_DECREASE:
 
				if (_settings_client.gui.drag_signals_density > 1) {
 
					_settings_client.gui.drag_signals_density--;
 
					InvalidateWindow(WC_GAME_OPTIONS, 0);
 
					SetWindowDirty(WC_GAME_OPTIONS, 0);
 
				}
 
				break;
 

	
 
			case BSW_DRAG_SIGNALS_DENSITY_INCREASE:
 
				if (_settings_client.gui.drag_signals_density < 20) {
 
					_settings_client.gui.drag_signals_density++;
 
					InvalidateWindow(WC_GAME_OPTIONS, 0);
 
					SetWindowDirty(WC_GAME_OPTIONS, 0);
 
				}
 
				break;
 

	
 
			default: break;
 
		}
 

	
 
		this->SetDirty();
 
	}
 
};
 

	
 
/** Nested widget definition of the build signal window */
 
static const NWidgetPart _nested_signal_builder_widgets[] = {
src/road_gui.cpp
Show inline comments
 
@@ -258,25 +258,25 @@ enum RoadToolbarWidgets {
 
	RTW_REMOVE,
 
};
 

	
 
typedef void OnButtonClick(Window *w);
 

	
 

	
 
/** Toogles state of the Remove button of Build road toolbar
 
 * @param w window the button belongs to
 
 */
 
static void ToggleRoadButton_Remove(Window *w)
 
{
 
	w->ToggleWidgetLoweredState(RTW_REMOVE);
 
	w->InvalidateWidget(RTW_REMOVE);
 
	w->SetWidgetDirty(RTW_REMOVE);
 
	_remove_button_clicked = w->IsWidgetLowered(RTW_REMOVE);
 
	SetSelectionRed(_remove_button_clicked);
 
}
 

	
 
/** Updates the Remove button because of Ctrl state change
 
 * @param w window the button belongs to
 
 * @return true iff the remove buton was changed
 
 */
 
static bool RoadToolbar_CtrlChanged(Window *w)
 
{
 
	if (w->IsWidgetDisabled(RTW_REMOVE)) return false;
 

	
 
@@ -438,30 +438,30 @@ struct BuildRoadToolbarWindow : Window {
 
	 * Update the remove button lowered state of the road toolbar
 
	 *
 
	 * @param clicked_widget The widget which the client clicked just now
 
	 */
 
	void UpdateOptionWidgetStatus(RoadToolbarWidgets clicked_widget)
 
	{
 
		/* The remove and the one way button state is driven
 
		 * by the other buttons so they don't act on themselfs.
 
		 * Both are only valid if they are able to apply as options. */
 
		switch (clicked_widget) {
 
			case RTW_REMOVE:
 
				this->RaiseWidget(RTW_ONE_WAY);
 
				this->InvalidateWidget(RTW_ONE_WAY);
 
				this->SetWidgetDirty(RTW_ONE_WAY);
 
				break;
 

	
 
			case RTW_ONE_WAY:
 
				this->RaiseWidget(RTW_REMOVE);
 
				this->InvalidateWidget(RTW_REMOVE);
 
				this->SetWidgetDirty(RTW_REMOVE);
 
				break;
 

	
 
			case RTW_BUS_STATION:
 
			case RTW_TRUCK_STATION:
 
				this->DisableWidget(RTW_ONE_WAY);
 
				this->SetWidgetDisabledState(RTW_REMOVE, !this->IsWidgetLowered(clicked_widget));
 
				break;
 

	
 
			case RTW_ROAD_X:
 
			case RTW_ROAD_Y:
 
			case RTW_AUTOROAD:
 
				this->SetWidgetsDisabledState(!this->IsWidgetLowered(clicked_widget),
 
@@ -524,26 +524,26 @@ struct BuildRoadToolbarWindow : Window {
 
		_remove_button_clicked = this->IsWidgetLowered(RTW_REMOVE);
 
		_one_way_button_clicked = this->IsWidgetLowered(RTW_ONE_WAY);
 
		_place_proc(tile);
 
	}
 

	
 
	virtual void OnPlaceObjectAbort()
 
	{
 
		this->RaiseButtons();
 
		this->SetWidgetsDisabledState(true,
 
			RTW_REMOVE,
 
			RTW_ONE_WAY,
 
			WIDGET_LIST_END);
 
		this->InvalidateWidget(RTW_REMOVE);
 
		this->InvalidateWidget(RTW_ONE_WAY);
 
		this->SetWidgetDirty(RTW_REMOVE);
 
		this->SetWidgetDirty(RTW_ONE_WAY);
 

	
 
		DeleteWindowById(WC_BUS_STATION, TRANSPORT_ROAD);
 
		DeleteWindowById(WC_TRUCK_STATION, TRANSPORT_ROAD);
 
		DeleteWindowById(WC_BUILD_DEPOT, TRANSPORT_ROAD);
 
		DeleteWindowById(WC_SELECT_STATION, 0);
 
		DeleteWindowByClass(WC_BUILD_BRIDGE);
 
	}
 

	
 
	virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt)
 
	{
 
		/* Here we update the end tile flags
 
		 * of the road placement actions.
src/roadveh_cmd.cpp
Show inline comments
 
@@ -286,25 +286,25 @@ CommandCost CmdBuildRoadVeh(TileIndex ti
 
		for (RoadVehicle *u = v; u != NULL; u = u->Next()) {
 
			u->rcache.cached_veh_length = GetRoadVehLength(u);
 
			/* Cargo capacity is zero if and only if the vehicle cannot carry anything */
 
			if (u->cargo_cap != 0) u->cargo_cap = GetVehicleProperty(u, 0x0F, u->cargo_cap);
 
			v->InvalidateNewGRFCache();
 
			u->InvalidateNewGRFCache();
 
		}
 

	
 
		VehicleMove(v, false);
 

	
 
		InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
 
		InvalidateWindowClassesData(WC_ROADVEH_LIST, 0);
 
		InvalidateWindow(WC_COMPANY, v->owner);
 
		SetWindowDirty(WC_COMPANY, v->owner);
 
		if (IsLocalCompany()) {
 
			InvalidateAutoreplaceWindow(v->engine_type, v->group_id); // updates the replace Road window
 
		}
 

	
 
		Company::Get(_current_company)->num_engines[p1]++;
 

	
 
		CheckConsistencyOfArticulatedVehicle(v);
 
	}
 

	
 
	return cost;
 
}
 

	
 
@@ -611,25 +611,25 @@ static void RoadVehCrash(RoadVehicle *v)
 
	v->crashed_ctr++;
 

	
 
	for (Vehicle *u = v; u != NULL; u = u->Next()) {
 
		if (IsCargoInClass(u->cargo_type, CC_PASSENGERS)) pass += u->cargo.Count();
 

	
 
		u->vehstatus |= VS_CRASHED;
 

	
 
		MarkSingleVehicleDirty(u);
 
	}
 

	
 
	ClearSlot(v);
 

	
 
	InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
	SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 

	
 
	AI::NewEvent(v->owner, new AIEventVehicleCrashed(v->index, v->tile, AIEventVehicleCrashed::CRASH_RV_LEVEL_CROSSING));
 

	
 
	SetDParam(0, pass);
 
	AddVehicleNewsItem(
 
		(pass == 1) ?
 
			STR_NEWS_ROAD_VEHICLE_CRASH_DRIVER : STR_NEWS_ROAD_VEHICLE_CRASH,
 
		NS_ACCIDENT,
 
		v->index
 
	);
 

	
 
	ModifyStationRatingAround(v->tile, v->owner, -160, 22);
 
@@ -654,42 +654,42 @@ static bool RoadVehCheckTrainCrash(RoadV
 
	return false;
 
}
 

	
 
static void HandleBrokenRoadVeh(RoadVehicle *v)
 
{
 
	if (v->breakdown_ctr != 1) {
 
		v->breakdown_ctr = 1;
 
		v->cur_speed = 0;
 

	
 
		if (v->breakdowns_since_last_service != 255)
 
			v->breakdowns_since_last_service++;
 

	
 
		InvalidateWindow(WC_VEHICLE_VIEW, v->index);
 
		InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 
		SetWindowDirty(WC_VEHICLE_VIEW, v->index);
 
		SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
 

	
 
		if (!PlayVehicleSound(v, VSE_BREAKDOWN)) {
 
			SndPlayVehicleFx((_settings_game.game_creation.landscape != LT_TOYLAND) ?
 
				SND_0F_VEHICLE_BREAKDOWN : SND_35_COMEDY_BREAKDOWN, v);
 
		}
 

	
 
		if (!(v->vehstatus & VS_HIDDEN)) {
 
			EffectVehicle *u = CreateEffectVehicleRel(v, 4, 4, 5, EV_BREAKDOWN_SMOKE);
 
			if (u != NULL) u->animation_state = v->breakdown_delay * 2;
 
		}
 
	}
 

	
 
	if ((v->tick_counter & 1) == 0) {
 
		if (--v->breakdown_delay == 0) {
 
			v->breakdown_ctr = 0;
 
			InvalidateWindow(WC_VEHICLE_VIEW, v->index);
 
			SetWindowDirty(WC_VEHICLE_VIEW, v->index);
 
		}
 
	}
 
}
 

	
 
TileIndex RoadVehicle::GetOrderStationLocation(StationID station)
 
{
 
	if (station == this->last_station_visited) this->last_station_visited = INVALID_STATION;
 

	
 
	TileIndex dest;
 
	if (YapfFindNearestRoadVehicleCompatibleStop(this, station, &dest)) {
 
		return dest;
 
	} else {
 
@@ -827,25 +827,25 @@ static int RoadVehAccelerate(RoadVehicle
 
	}
 

	
 
	v->cur_speed = spd = Clamp(v->cur_speed + ((int)spd >> 8), 0, tempmax);
 

	
 
	/* Apply bridge speed limit */
 
	if (v->state == RVSB_WORMHOLE && !(v->vehstatus & VS_HIDDEN)) {
 
		v->cur_speed = min(v->cur_speed, GetBridgeSpec(GetBridgeType(v->tile))->speed * 2);
 
	}
 

	
 
	/* Update statusbar only if speed has changed to save CPU time */
 
	if (oldspeed != v->cur_speed) {
 
		if (_settings_client.gui.vehicle_speed) {
 
			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
			SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
		}
 
	}
 

	
 
	/* Speed is scaled in the same manner as for trains. @see train_cmd.cpp */
 
	int scaled_spd = spd * 3 >> 2;
 

	
 
	scaled_spd += v->progress;
 
	v->progress = 0;
 
	return scaled_spd;
 
}
 

	
 
static Direction RoadVehGetNewDirection(const RoadVehicle *v, int x, int y)
 
@@ -1721,25 +1721,25 @@ again:
 
				DEBUG(ms, 2, " current order type (%d) is not OT_GOTO_STATION", v->current_order.GetType());
 
			} else {
 
				if (v->current_order.GetDestination() != st->index)
 
					DEBUG(ms, 2, " current station %d is not target station in current_order.station (%d)",
 
							st->index, v->current_order.GetDestination());
 
			}
 

	
 
			DEBUG(ms, 2, " force a slot clearing");
 
			ClearSlot(v);
 
		}
 

	
 
		StartRoadVehSound(v);
 
		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
		SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
	}
 

	
 
	/* Check tile position conditions - i.e. stop position in depot,
 
	 * entry onto bridge or into tunnel */
 
	uint32 r = VehicleEnterTile(v, v->tile, x, y);
 
	if (HasBit(r, VETS_CANNOT_ENTER)) {
 
		v->cur_speed = 0;
 
		return false;
 
	}
 

	
 
	if (v->current_order.IsType(OT_LEAVESTATION) && IsDriveThroughStopTile(v->tile)) {
 
		v->current_order.Free();
 
@@ -1836,43 +1836,43 @@ static void CheckIfRoadVehNeedsService(R
 
		VehicleServiceInDepot(v);
 
		return;
 
	}
 

	
 
	RoadFindDepotData rfdd = FindClosestRoadDepot(v, MAX_ACCEPTABLE_DEPOT_DIST);
 
	/* Only go to the depot if it is not too far out of our way. */
 
	if (rfdd.best_length == UINT_MAX || rfdd.best_length > MAX_ACCEPTABLE_DEPOT_DIST) {
 
		if (v->current_order.IsType(OT_GOTO_DEPOT)) {
 
			/* If we were already heading for a depot but it has
 
			 * suddenly moved farther away, we continue our normal
 
			 * schedule? */
 
			v->current_order.MakeDummy();
 
			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
			SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
		}
 
		return;
 
	}
 

	
 
	DepotID depot = GetDepotIndex(rfdd.tile);
 

	
 
	if (v->current_order.IsType(OT_GOTO_DEPOT) &&
 
			v->current_order.GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS &&
 
			!Chance16(1, 20)) {
 
		return;
 
	}
 

	
 
	if (v->current_order.IsType(OT_LOADING)) v->LeaveStation();
 
	ClearSlot(v);
 

	
 
	v->current_order.MakeGoToDepot(depot, ODTFB_SERVICE);
 
	v->dest_tile = rfdd.tile;
 
	InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
	SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
}
 

	
 
void RoadVehicle::OnNewDay()
 
{
 
	if (!this->IsRoadVehFront()) return;
 

	
 
	if ((++this->day_counter & 7) == 0) DecreaseVehicleValue(this);
 
	if (this->blocked_ctr == 0) CheckVehicleBreakdown(this);
 

	
 
	AgeVehicle(this);
 
	CheckIfRoadVehNeedsService(this);
 

	
 
@@ -1948,26 +1948,26 @@ void RoadVehicle::OnNewDay()
 
		}
 
	}
 

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

	
 
	CommandCost cost(EXPENSES_ROADVEH_RUN, this->GetRunningCost() * this->running_ticks / (DAYS_IN_YEAR * DAY_TICKS));
 

	
 
	this->profit_this_year -= cost.GetCost();
 
	this->running_ticks = 0;
 

	
 
	SubtractMoneyFromCompanyFract(this->owner, cost);
 

	
 
	InvalidateWindow(WC_VEHICLE_DETAILS, this->index);
 
	InvalidateWindowClasses(WC_ROADVEH_LIST);
 
	SetWindowDirty(WC_VEHICLE_DETAILS, this->index);
 
	SetWindowClassesDirty(WC_ROADVEH_LIST);
 
}
 

	
 
Trackdir RoadVehicle::GetVehicleTrackdir() const
 
{
 
	if (this->vehstatus & VS_CRASHED) return INVALID_TRACKDIR;
 

	
 
	if (this->IsInDepot()) {
 
		/* We'll assume the road vehicle is facing outwards */
 
		return DiagDirToDiagTrackdir(GetRoadDepotDirection(this->tile));
 
	}
 

	
 
	if (IsStandardRoadStopTile(this->tile)) {
 
@@ -2060,24 +2060,24 @@ CommandCost CmdRefitRoadVeh(TileIndex ti
 

	
 
		total_capacity += capacity;
 

	
 
		if (new_cid != v->cargo_type) {
 
			cost.AddCost(GetRefitCost(v->engine_type));
 
		}
 

	
 
		if (flags & DC_EXEC) {
 
			v->cargo_cap = capacity;
 
			v->cargo.Truncate((v->cargo_type == new_cid) ? capacity : 0);
 
			v->cargo_type = new_cid;
 
			v->cargo_subtype = new_subtype;
 
			InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 
			InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
 
			SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
 
			SetWindowDirty(WC_VEHICLE_DEPOT, v->tile);
 
			InvalidateWindowClassesData(WC_ROADVEH_LIST, 0);
 
		}
 
	}
 

	
 
	if (flags & DC_EXEC) RoadVehUpdateCache(RoadVehicle::Get(p1)->First());
 

	
 
	_returned_refit_capacity = total_capacity;
 

	
 
	return cost;
 
}
src/settings.cpp
Show inline comments
 
@@ -655,31 +655,31 @@ static bool PopulationInLabelActive(int3
 
	UpdateAllTownVirtCoords();
 
	return true;
 
}
 

	
 
static bool RedrawScreen(int32 p1)
 
{
 
	MarkWholeScreenDirty();
 
	return true;
 
}
 

	
 
static bool InvalidateDetailsWindow(int32 p1)
 
{
 
	InvalidateWindowClasses(WC_VEHICLE_DETAILS);
 
	SetWindowClassesDirty(WC_VEHICLE_DETAILS);
 
	return true;
 
}
 

	
 
static bool InvalidateStationBuildWindow(int32 p1)
 
{
 
	InvalidateWindow(WC_BUILD_STATION, 0);
 
	SetWindowDirty(WC_BUILD_STATION, 0);
 
	return true;
 
}
 

	
 
static bool InvalidateBuildIndustryWindow(int32 p1)
 
{
 
	InvalidateWindowData(WC_BUILD_INDUSTRY, 0);
 
	return true;
 
}
 

	
 
static bool CloseSignalGUI(int32 p1)
 
{
 
	if (p1 == 0) {
 
@@ -743,25 +743,25 @@ static bool TrainAccelerationModelChange
 
	FOR_ALL_TRAINS(t) {
 
		if (t->IsFrontEngine()) {
 
			t->tcache.cached_max_curve_speed = GetTrainCurveSpeedLimit(t);
 
			UpdateTrainAcceleration(t);
 
		}
 
	}
 

	
 
	return true;
 
}
 

	
 
static bool DragSignalsDensityChanged(int32)
 
{
 
	InvalidateWindow(WC_BUILD_SIGNAL, 0);
 
	SetWindowDirty(WC_BUILD_SIGNAL, 0);
 

	
 
	return true;
 
}
 

	
 
/*
 
 * A: competitors
 
 * B: competitor start time. Deprecated since savegame version 110.
 
 * C: town count (3 = high, 0 = very low)
 
 * D: industry count (4 = high, 0 = none)
 
 * E: inital loan (in GBP)
 
 * F: interest rate
 
 * G: running costs (0 = low, 2 = high)
 
@@ -811,25 +811,25 @@ static bool DifficultyReset(int32 level)
 
{
 
	SetDifficultyLevel(level, (_game_mode == GM_MENU) ? &_settings_newgame.difficulty : &_settings_game.difficulty);
 
	return true;
 
}
 

	
 
static bool DifficultyChange(int32)
 
{
 
	if (_game_mode == GM_MENU) {
 
		if (_settings_newgame.difficulty.diff_level != 3) {
 
			ShowErrorMessage(INVALID_STRING_ID, STR_WARNING_DIFFICULTY_TO_CUSTOM, 0, 0);
 
			_settings_newgame.difficulty.diff_level = 3;
 
		}
 
		InvalidateWindowClasses(WC_SELECT_GAME);
 
		SetWindowClassesDirty(WC_SELECT_GAME);
 
	} else {
 
		_settings_game.difficulty.diff_level = 3;
 
	}
 

	
 
	/* If we are a network-client, update the difficult setting (if it is open).
 
	 * Use this instead of just dirtying the window because we need to load in
 
	 * the new difficulty settings */
 
	if (_networking && FindWindowById(WC_GAME_OPTIONS, 0) != NULL) {
 
		ShowGameDifficulty();
 
	}
 

	
 
	return true;
 
@@ -1437,25 +1437,25 @@ CommandCost CmdChangeSetting(TileIndex t
 

	
 
		if (sd->desc.proc != NULL && !sd->desc.proc(newval)) {
 
			WriteValue(var, sd->save.conv, (int64)oldval);
 
			return CommandCost();
 
		}
 

	
 
		if (sd->desc.flags & SGF_NO_NETWORK) {
 
			GamelogStartAction(GLAT_SETTING);
 
			GamelogSetting(sd->desc.name, oldval, newval);
 
			GamelogStopAction();
 
		}
 

	
 
		InvalidateWindow(WC_GAME_OPTIONS, 0);
 
		SetWindowDirty(WC_GAME_OPTIONS, 0);
 
	}
 

	
 
	return CommandCost();
 
}
 

	
 
/** Change one of the per-company settings.
 
 * @param tile unused
 
 * @param flags operation to perform
 
 * @param p1 the index of the setting in the _company_settings array which identifies it
 
 * @param p2 the new value for the setting
 
 * The new value is properly clamped to its minimum/maximum when setting
 
 */
 
@@ -1471,25 +1471,25 @@ CommandCost CmdChangeCompanySetting(Tile
 
		int32 newval = (int32)p2;
 

	
 
		Write_ValidateSetting(var, sd, newval);
 
		newval = (int32)ReadValue(var, sd->save.conv);
 

	
 
		if (oldval == newval) return CommandCost();
 

	
 
		if (sd->desc.proc != NULL && !sd->desc.proc(newval)) {
 
			WriteValue(var, sd->save.conv, (int64)oldval);
 
			return CommandCost();
 
		}
 

	
 
		InvalidateWindow(WC_GAME_OPTIONS, 0);
 
		SetWindowDirty(WC_GAME_OPTIONS, 0);
 
	}
 

	
 
	return CommandCost();
 
}
 

	
 
/** Top function to save the new value of an element of the Settings struct
 
 * @param index offset in the SettingDesc array of the Settings struct which
 
 * identifies the setting member we want to change
 
 * @param object pointer to a valid settings struct that has its settings change.
 
 * This only affects setting-members that are not needed to be the same on all
 
 * clients in a network game.
 
 * @param value new value of the setting */
 
@@ -1500,25 +1500,25 @@ bool SetSettingValue(uint index, int32 v
 
	 * (if any) to change. Also *hack*hack* we update the _newgame version
 
	 * of settings because changing a company-based setting in a game also
 
	 * changes its defaults. At least that is the convention we have chosen */
 
	if (sd->save.conv & SLF_NETWORK_NO) {
 
		void *var = GetVariableAddress((_game_mode == GM_MENU) ? &_settings_newgame : &_settings_game, &sd->save);
 
		Write_ValidateSetting(var, sd, value);
 

	
 
		if (_game_mode != GM_MENU) {
 
			void *var2 = GetVariableAddress(&_settings_newgame, &sd->save);
 
			Write_ValidateSetting(var2, sd, value);
 
		}
 
		if (sd->desc.proc != NULL) sd->desc.proc((int32)ReadValue(var, sd->save.conv));
 
		InvalidateWindow(WC_GAME_OPTIONS, 0);
 
		SetWindowDirty(WC_GAME_OPTIONS, 0);
 
		return true;
 
	}
 

	
 
	/* send non-company-based settings over the network */
 
	if (!_networking || (_networking && _network_server)) {
 
		return DoCommandP(0, index, value, CMD_CHANGE_SETTING);
 
	}
 
	return false;
 
}
 

	
 
/** Top function to save the new value of an element of the Settings struct
 
 * @param index offset in the SettingDesc array of the CompanySettings struct
src/settings_gui.cpp
Show inline comments
 
@@ -375,25 +375,25 @@ struct GameOptionsWindow : Window {
 
			case GOW_ROADSIDE_DROPDOWN: // Road side
 
				if (this->opt->vehicle.road_side != index) { // only change if setting changed
 
					uint i;
 
					if (GetSettingFromName("vehicle.road_side", &i) == NULL) NOT_REACHED();
 
					SetSettingValue(i, index);
 
					MarkWholeScreenDirty();
 
				}
 
				break;
 

	
 
			case GOW_TOWNNAME_DROPDOWN: // Town names
 
				if (_game_mode == GM_MENU || Town::GetNumItems() == 0) {
 
					this->opt->game_creation.town_name = index;
 
					InvalidateWindow(WC_GAME_OPTIONS, 0);
 
					SetWindowDirty(WC_GAME_OPTIONS, 0);
 
				}
 
				break;
 

	
 
			case GOW_AUTOSAVE_DROPDOWN: // Autosave options
 
				_settings_client.gui.autosave = index;
 
				this->SetDirty();
 
				break;
 

	
 
			case GOW_LANG_DROPDOWN: // Change interface language
 
				ReadLanguagePack(index);
 
				CheckForMissingGlyphsInLoadedLanguagePack();
 
				UpdateAllStationVirtCoords();
src/ship_cmd.cpp
Show inline comments
 
@@ -137,32 +137,32 @@ static void CheckIfShipNeedsService(Vehi
 
{
 
	if (Company::Get(v->owner)->settings.vehicle.servint_ships == 0 || !v->NeedsAutomaticServicing()) return;
 
	if (v->IsInDepot()) {
 
		VehicleServiceInDepot(v);
 
		return;
 
	}
 

	
 
	const Depot *depot = FindClosestShipDepot(v);
 

	
 
	if (depot == NULL || DistanceManhattan(v->tile, depot->xy) > 12) {
 
		if (v->current_order.IsType(OT_GOTO_DEPOT)) {
 
			v->current_order.MakeDummy();
 
			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
			SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
		}
 
		return;
 
	}
 

	
 
	v->current_order.MakeGoToDepot(depot->index, ODTFB_SERVICE);
 
	v->dest_tile = depot->xy;
 
	InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
	SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
}
 

	
 
Money Ship::GetRunningCost() const
 
{
 
	return GetVehicleProperty(this, 0x0F, ShipVehInfo(this->engine_type)->running_cost) * _price.ship_running;
 
}
 

	
 
void Ship::OnNewDay()
 
{
 
	if ((++this->day_counter & 7) == 0)
 
		DecreaseVehicleValue(this);
 

	
 
@@ -172,27 +172,27 @@ void Ship::OnNewDay()
 

	
 
	CheckOrders(this);
 

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

	
 
	CommandCost cost(EXPENSES_SHIP_RUN, this->GetRunningCost() * this->running_ticks / (DAYS_IN_YEAR * DAY_TICKS));
 

	
 
	this->profit_this_year -= cost.GetCost();
 
	this->running_ticks = 0;
 

	
 
	SubtractMoneyFromCompanyFract(this->owner, cost);
 

	
 
	InvalidateWindow(WC_VEHICLE_DETAILS, this->index);
 
	SetWindowDirty(WC_VEHICLE_DETAILS, this->index);
 
	/* we need this for the profit */
 
	InvalidateWindowClasses(WC_SHIPS_LIST);
 
	SetWindowClassesDirty(WC_SHIPS_LIST);
 
}
 

	
 
Trackdir Ship::GetVehicleTrackdir() const
 
{
 
	if (this->vehstatus & VS_CRASHED) return INVALID_TRACKDIR;
 

	
 
	if (this->IsInDepot()) {
 
		/* We'll assume the ship is facing outwards */
 
		return DiagDirToDiagTrackdir(GetShipDepotDirection(this->tile));
 
	}
 

	
 
	if (this->state == TRACK_BIT_WORMHOLE) {
 
@@ -203,42 +203,42 @@ Trackdir Ship::GetVehicleTrackdir() cons
 
	return TrackDirectionToTrackdir(FindFirstTrack(this->state), this->direction);
 
}
 

	
 
static void HandleBrokenShip(Vehicle *v)
 
{
 
	if (v->breakdown_ctr != 1) {
 
		v->breakdown_ctr = 1;
 
		v->cur_speed = 0;
 

	
 
		if (v->breakdowns_since_last_service != 255)
 
			v->breakdowns_since_last_service++;
 

	
 
		InvalidateWindow(WC_VEHICLE_VIEW, v->index);
 
		InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 
		SetWindowDirty(WC_VEHICLE_VIEW, v->index);
 
		SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
 

	
 
		if (!PlayVehicleSound(v, VSE_BREAKDOWN)) {
 
			SndPlayVehicleFx((_settings_game.game_creation.landscape != LT_TOYLAND) ?
 
				SND_10_TRAIN_BREAKDOWN : SND_3A_COMEDY_BREAKDOWN_2, v);
 
		}
 

	
 
		if (!(v->vehstatus & VS_HIDDEN)) {
 
			EffectVehicle *u = CreateEffectVehicleRel(v, 4, 4, 5, EV_BREAKDOWN_SMOKE);
 
			if (u != NULL) u->animation_state = v->breakdown_delay * 2;
 
		}
 
	}
 

	
 
	if (!(v->tick_counter & 1)) {
 
		if (!--v->breakdown_delay) {
 
			v->breakdown_ctr = 0;
 
			InvalidateWindow(WC_VEHICLE_VIEW, v->index);
 
			SetWindowDirty(WC_VEHICLE_VIEW, v->index);
 
		}
 
	}
 
}
 

	
 
void Ship::MarkDirty()
 
{
 
	this->UpdateViewport(false, false);
 
}
 

	
 
static void PlayShipSound(const Vehicle *v)
 
{
 
	if (!PlayVehicleSound(v, VSE_START)) {
 
@@ -281,25 +281,25 @@ void Ship::UpdateDeltaXY(Direction direc
 

	
 
	uint32 x = _delta_xy_table[direction];
 
	this->x_offs        = GB(x,  0, 8);
 
	this->y_offs        = GB(x,  8, 8);
 
	this->x_extent      = GB(x, 16, 8);
 
	this->y_extent      = GB(x, 24, 8);
 
	this->z_extent      = 6;
 
}
 

	
 
void RecalcShipStuff(Vehicle *v)
 
{
 
	v->UpdateViewport(false, true);
 
	InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
 
	SetWindowDirty(WC_VEHICLE_DEPOT, v->tile);
 
}
 

	
 
static const TileIndexDiffC _ship_leave_depot_offs[] = {
 
	{-1,  0},
 
	{ 0, -1}
 
};
 

	
 
static void CheckShipLeaveDepot(Ship *v)
 
{
 
	if (!v->IsInDepot()) return;
 

	
 
	TileIndex tile = v->tile;
 
@@ -315,39 +315,39 @@ static void CheckShipLeaveDepot(Ship *v)
 
		return;
 
	}
 

	
 
	v->state = AxisToTrackBits(axis);
 
	v->vehstatus &= ~VS_HIDDEN;
 

	
 
	v->cur_speed = 0;
 
	RecalcShipStuff(v);
 

	
 
	PlayShipSound(v);
 
	VehicleServiceInDepot(v);
 
	InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
 
	InvalidateWindowClasses(WC_SHIPS_LIST);
 
	SetWindowClassesDirty(WC_SHIPS_LIST);
 
}
 

	
 
static bool ShipAccelerate(Vehicle *v)
 
{
 
	uint spd;
 
	byte t;
 

	
 
	spd = min(v->cur_speed + 1, GetVehicleProperty(v, 0x0B, v->max_speed));
 

	
 
	/* updates statusbar only if speed have changed to save CPU time */
 
	if (spd != v->cur_speed) {
 
		v->cur_speed = spd;
 
		if (_settings_client.gui.vehicle_speed)
 
			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
			SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
	}
 

	
 
	/* Decrease somewhat when turning */
 
	if (!(v->direction & 1)) spd = spd * 3 / 4;
 

	
 
	if (spd == 0) return false;
 
	if ((byte)++spd == 0) return true;
 

	
 
	v->progress = (t = v->progress) - (byte)spd;
 

	
 
	return (t < v->progress);
 
}
 
@@ -618,25 +618,25 @@ static void ShipController(Ship *v)
 
			if (v->IsInDepot()) {
 
				gp.x = v->x_pos;
 
				gp.y = v->y_pos;
 
			} else {
 
				/* Not inside depot */
 
				r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
 
				if (HasBit(r, VETS_CANNOT_ENTER)) goto reverse_direction;
 

	
 
				/* A leave station order only needs one tick to get processed, so we can
 
				 * always skip ahead. */
 
				if (v->current_order.IsType(OT_LEAVESTATION)) {
 
					v->current_order.Free();
 
					InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
					SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
				} else if (v->dest_tile != 0) {
 
					/* We have a target, let's see if we reached it... */
 
					if (v->current_order.IsType(OT_GOTO_WAYPOINT) &&
 
							DistanceManhattan(v->dest_tile, gp.new_tile) <= 3) {
 
						/* We got within 3 tiles of our target buoy, so let's skip to our
 
						 * next order */
 
						UpdateVehicleTimetable(v, true);
 
						v->IncrementOrderIndex();
 
						v->current_order.MakeDummy();
 
					} else {
 
						/* Non-buoy orders really need to reach the tile */
 
						if (v->dest_tile == gp.new_tile) {
 
@@ -810,25 +810,25 @@ CommandCost CmdBuildShip(TileIndex tile,
 
		if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SetBit(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE);
 

	
 
		v->InvalidateNewGRFCacheOfChain();
 

	
 
		v->cargo_cap = GetVehicleProperty(v, 0x0D, svi->capacity);
 

	
 
		v->InvalidateNewGRFCacheOfChain();
 

	
 
		VehicleMove(v, false);
 

	
 
		InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
 
		InvalidateWindowClassesData(WC_SHIPS_LIST, 0);
 
		InvalidateWindow(WC_COMPANY, v->owner);
 
		SetWindowDirty(WC_COMPANY, v->owner);
 
		if (IsLocalCompany())
 
			InvalidateAutoreplaceWindow(v->engine_type, v->group_id); // updates the replace Ship window
 

	
 
		Company::Get(_current_company)->num_engines[p1]++;
 
	}
 

	
 
	return value;
 
}
 

	
 
/** Sell a ship.
 
 * @param tile unused
 
 * @param flags type of operation
 
@@ -939,20 +939,20 @@ CommandCost CmdRefitShip(TileIndex tile,
 

	
 
	if (new_cid != v->cargo_type) {
 
		cost = GetRefitCost(v->engine_type);
 
	}
 

	
 
	if (flags & DC_EXEC) {
 
		v->cargo_cap = capacity;
 
		v->cargo.Truncate((v->cargo_type == new_cid) ? capacity : 0);
 
		v->cargo_type = new_cid;
 
		v->cargo_subtype = new_subtype;
 
		v->colourmap = PAL_NONE; // invalidate vehicle colour map
 
		v->InvalidateNewGRFCacheOfChain();
 
		InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 
		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
 
		SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
 
		SetWindowDirty(WC_VEHICLE_DEPOT, v->tile);
 
		InvalidateWindowClassesData(WC_SHIPS_LIST, 0);
 
	}
 

	
 
	return cost;
 

	
 
}
src/signs_gui.cpp
Show inline comments
 
@@ -167,25 +167,25 @@ struct SignListWindow : Window, SignList
 
			this->text_offset = WD_FRAMETEXT_LEFT + spr_dim.width + 2; // 2 pixels space between icon and the sign text.
 
			resize->height = max<uint>(FONT_HEIGHT_NORMAL, GetSpriteSize(SPR_PLAYER_ICON).height);
 
			Dimension d = {this->text_offset + MAX_LENGTH_SIGN_NAME_PIXELS + WD_FRAMETEXT_RIGHT, WD_FRAMERECT_TOP + 5 * resize->height + WD_FRAMERECT_BOTTOM};
 
			*size = maxdim(*size, d);
 
		}
 
	}
 

	
 
	virtual void OnInvalidateData(int data)
 
	{
 
		if (data == 0) { // New or deleted sign.
 
			this->signs.ForceRebuild();
 
			this->BuildSignsList();
 
			this->InvalidateWidget(SLW_CAPTION);
 
			this->SetWidgetDirty(SLW_CAPTION);
 
			this->vscroll.SetCount(this->signs.Length());
 
		} else { // Change of sign contents.
 
			this->signs.ForceResort();
 
		}
 

	
 
		this->SortSignsList();
 
	}
 
};
 

	
 
static const NWidgetPart _nested_sign_list_widgets[] = {
 
	NWidget(NWID_HORIZONTAL),
 
		NWidget(WWT_CLOSEBOX, COLOUR_GREY, SLW_CLOSEBOX),
 
@@ -263,25 +263,25 @@ struct SignWindow : QueryStringBaseWindo
 
		/* Display an empty string when the sign hasnt been edited yet */
 
		if (si->name != NULL) {
 
			SetDParam(0, si->index);
 
			GetString(this->edit_str_buf, STR_SIGN_NAME, last_of);
 
		} else {
 
			GetString(this->edit_str_buf, STR_EMPTY, last_of);
 
		}
 
		*last_of = '\0';
 

	
 
		this->cur_sign = si->index;
 
		InitializeTextBuffer(&this->text, this->edit_str_buf, this->edit_str_size, MAX_LENGTH_SIGN_NAME_PIXELS);
 

	
 
		this->InvalidateWidget(QUERY_EDIT_SIGN_WIDGET_TEXT);
 
		this->SetWidgetDirty(QUERY_EDIT_SIGN_WIDGET_TEXT);
 
		this->SetFocusedWidget(QUERY_EDIT_SIGN_WIDGET_TEXT);
 
	}
 

	
 
	/**
 
	 * Returns a pointer to the (alphabetically) previous or next sign of the current sign.
 
	 * @param next false if the previous sign is wanted, true if the next sign is wanted
 
	 * @return pointer to the previous/next sign
 
	 */
 
	const Sign *PrevNextSign(bool next)
 
	{
 
		/* Rebuild the sign list */
 
		this->signs.ForceRebuild();
src/station_cmd.cpp
Show inline comments
 
@@ -418,25 +418,25 @@ void Station::GetTileArea(TileArea *ta, 
 
 */
 
void Station::UpdateVirtCoord()
 
{
 
	Point pt = RemapCoords2(TileX(this->xy) * TILE_SIZE, TileY(this->xy) * TILE_SIZE);
 

	
 
	pt.y -= 32;
 
	if ((this->facilities & FACIL_AIRPORT) && this->airport_type == AT_OILRIG) pt.y -= 16;
 

	
 
	SetDParam(0, this->index);
 
	SetDParam(1, this->facilities);
 
	this->sign.UpdatePosition(pt.x, pt.y, STR_VIEWPORT_STATION);
 

	
 
	InvalidateWindow(WC_STATION_VIEW, this->index);
 
	SetWindowDirty(WC_STATION_VIEW, this->index);
 
}
 

	
 
/** Update the virtual coords needed to draw the station sign for all stations. */
 
void UpdateAllStationVirtCoords()
 
{
 
	BaseStation *st;
 

	
 
	FOR_ALL_BASE_STATIONS(st) {
 
		st->UpdateVirtCoord();
 
	}
 
}
 

	
 
@@ -612,25 +612,25 @@ void UpdateStationAcceptance(Station *st
 
					/* Old cargo is no longer accepted */
 
					rejects[num_rej++] = i;
 
				}
 
			}
 
		}
 

	
 
		/* Show news message if there are any changes */
 
		if (num_acc > 0) ShowRejectOrAcceptNews(st, num_acc, accepts, accept_msg[num_acc - 1]);
 
		if (num_rej > 0) ShowRejectOrAcceptNews(st, num_rej, rejects, reject_msg[num_rej - 1]);
 
	}
 

	
 
	/* redraw the station view since acceptance changed */
 
	InvalidateWindowWidget(WC_STATION_VIEW, st->index, SVW_ACCEPTLIST);
 
	SetWindowWidgetDirty(WC_STATION_VIEW, st->index, SVW_ACCEPTLIST);
 
}
 

	
 
static void UpdateStationSignCoord(BaseStation *st)
 
{
 
	const StationRect *r = &st->rect;
 

	
 
	if (r->IsEmpty()) return; // no tiles belong to this station
 

	
 
	/* clamp sign coord to be inside the station rect */
 
	st->xy = TileXY(ClampU(TileX(st->xy), r->left, r->right), ClampU(TileY(st->xy), r->top, r->bottom));
 
	st->UpdateVirtCoord();
 
}
 
@@ -1144,25 +1144,25 @@ CommandCost CmdBuildRailStation(TileInde
 
			if (IsRailStationTile(v->tile)) SetRailStationPlatformReservation(v->tile, TrackdirToExitdir(v->GetVehicleTrackdir()), true);
 
			TryPathReserve(v, true, true);
 
			for (; v->Next() != NULL; v = v->Next()) ;
 
			if (IsRailStationTile(v->tile)) SetRailStationPlatformReservation(v->tile, TrackdirToExitdir(ReverseTrackdir(v->GetVehicleTrackdir())), true);
 
		}
 

	
 
		st->MarkTilesDirty(false);
 
		st->UpdateVirtCoord();
 
		UpdateStationAcceptance(st, false);
 
		st->RecomputeIndustriesNear();
 
		InvalidateWindowData(WC_SELECT_STATION, 0, 0);
 
		InvalidateWindowData(WC_STATION_LIST, st->owner, 0);
 
		InvalidateWindowWidget(WC_STATION_VIEW, st->index, SVW_TRAINS);
 
		SetWindowWidgetDirty(WC_STATION_VIEW, st->index, SVW_TRAINS);
 
	}
 

	
 
	return cost;
 
}
 

	
 
static void MakeRailStationAreaSmaller(BaseStation *st)
 
{
 
	TileArea ta = st->train_station;
 

	
 
restart:
 

	
 
	/* too small? */
 
@@ -1301,25 +1301,25 @@ CommandCost RemoveFromRailBaseStation(Ti
 
	for (T **stp = affected_stations.Begin(); stp != affected_stations.End(); stp++) {
 
		T *st = *stp;
 

	
 
		/* now we need to make the "spanned" area of the railway station smaller
 
		 * if we deleted something at the edges.
 
		 * we also need to adjust train_tile. */
 
		MakeRailStationAreaSmaller(st);
 
		UpdateStationSignCoord(st);
 

	
 
		/* if we deleted the whole station, delete the train facility. */
 
		if (st->train_station.tile == INVALID_TILE) {
 
			st->facilities &= ~FACIL_TRAIN;
 
			InvalidateWindowWidget(WC_STATION_VIEW, st->index, SVW_TRAINS);
 
			SetWindowWidgetDirty(WC_STATION_VIEW, st->index, SVW_TRAINS);
 
			st->UpdateVirtCoord();
 
			DeleteStationIfEmpty(st);
 
		}
 
	}
 

	
 
	total_cost.AddCost(quantity * removal_cost);
 
	return total_cost;
 
}
 

	
 
/** Remove a single tile from a rail station.
 
 * This allows for custom-built station with holes and weird layouts
 
 * @param start tile of station piece to remove
 
@@ -1336,25 +1336,25 @@ CommandCost CmdRemoveFromRailStation(Til
 
	if (start >= MapSize() || end >= MapSize()) return CMD_ERROR;
 

	
 
	TileArea ta(start, end);
 
	SmallVector<Station *, 4> affected_stations;
 

	
 
	CommandCost ret = RemoveFromRailBaseStation(ta, affected_stations, flags, _price.remove_rail_station, HasBit(p2, 0));
 
	if (ret.Failed()) return ret;
 

	
 
	/* Do all station specific functions here. */
 
	for (Station **stp = affected_stations.Begin(); stp != affected_stations.End(); stp++) {
 
		Station *st = *stp;
 

	
 
		if (st->train_station.tile == INVALID_TILE) InvalidateWindowWidget(WC_STATION_VIEW, st->index, SVW_TRAINS);
 
		if (st->train_station.tile == INVALID_TILE) SetWindowWidgetDirty(WC_STATION_VIEW, st->index, SVW_TRAINS);
 
		st->MarkTilesDirty(false);
 
		st->RecomputeIndustriesNear();
 
	}
 

	
 
	/* Now apply the rail cost to the number that we deleted */
 
	return ret;
 
}
 

	
 
/** Remove a single tile from a waypoint.
 
 * This allows for custom-built waypoint with holes and weird layouts
 
 * @param start tile of waypoint piece to remove
 
 * @param flags operation to perform
 
@@ -1424,25 +1424,25 @@ CommandCost RemoveRailStation(T *st, DoC
 

	
 
		st->train_station.tile = INVALID_TILE;
 
		st->train_station.w = 0;
 
		st->train_station.h = 0;
 

	
 
		st->facilities &= ~FACIL_TRAIN;
 

	
 
		free(st->speclist);
 
		st->num_specs = 0;
 
		st->speclist  = NULL;
 
		st->cached_anim_triggers = 0;
 

	
 
		InvalidateWindowWidget(WC_STATION_VIEW, st->index, SVW_TRAINS);
 
		SetWindowWidgetDirty(WC_STATION_VIEW, st->index, SVW_TRAINS);
 
		st->UpdateVirtCoord();
 
		DeleteStationIfEmpty(st);
 
	}
 

	
 
	return cost;
 
}
 

	
 
/**
 
 * Remove a rail road station
 
 * @param tile TileIndex been queried
 
 * @param flags operation to perform
 
 * @return cost or failure of operation
 
@@ -1627,25 +1627,25 @@ CommandCost CmdBuildRoadStop(TileIndex t
 
		RoadStopType rs_type = type ? ROADSTOP_TRUCK : ROADSTOP_BUS;
 
		if (is_drive_through) {
 
			MakeDriveThroughRoadStop(tile, st->owner, road_owner, tram_owner, st->index, rs_type, rts, (Axis)p1);
 
		} else {
 
			MakeRoadStop(tile, st->owner, st->index, rs_type, rts, (DiagDirection)p1);
 
		}
 

	
 
		st->UpdateVirtCoord();
 
		UpdateStationAcceptance(st, false);
 
		st->RecomputeIndustriesNear();
 
		InvalidateWindowData(WC_SELECT_STATION, 0, 0);
 
		InvalidateWindowData(WC_STATION_LIST, st->owner, 0);
 
		InvalidateWindowWidget(WC_STATION_VIEW, st->index, SVW_ROADVEHS);
 
		SetWindowWidgetDirty(WC_STATION_VIEW, st->index, SVW_ROADVEHS);
 
	}
 
	return cost;
 
}
 

	
 

	
 
static Vehicle *ClearRoadStopStatusEnum(Vehicle *v, void *)
 
{
 
	if (v->type == VEH_ROAD) RoadVehicle::From(v)->state &= RVSB_ROAD_STOP_TRACKDIR_MASK;
 

	
 
	return NULL;
 
}
 

	
 
@@ -1692,25 +1692,25 @@ static CommandCost RemoveRoadStop(TileIn
 
			*primary_stop = cur_stop->next;
 
			/* removed the only stop? */
 
			if (*primary_stop == NULL) {
 
				st->facilities &= (is_truck ? ~FACIL_TRUCK_STOP : ~FACIL_BUS_STOP);
 
			}
 
		} else {
 
			/* tell the predecessor in the list to skip this stop */
 
			RoadStop *pred = *primary_stop;
 
			while (pred->next != cur_stop) pred = pred->next;
 
			pred->next = cur_stop->next;
 
		}
 

	
 
		InvalidateWindowWidget(WC_STATION_VIEW, st->index, SVW_ROADVEHS);
 
		SetWindowWidgetDirty(WC_STATION_VIEW, st->index, SVW_ROADVEHS);
 
		delete cur_stop;
 

	
 
		/* Make sure no vehicle is going to the old roadstop */
 
		RoadVehicle *v;
 
		FOR_ALL_ROADVEHICLES(v) {
 
			if (v->First() == v && v->current_order.IsType(OT_GOTO_STATION) &&
 
					v->dest_tile == tile) {
 
				v->dest_tile = v->GetOrderStationLocation(st->index);
 
			}
 
		}
 

	
 
		DoClearSquare(tile);
 
@@ -1992,28 +1992,28 @@ CommandCost CmdBuildAirport(TileIndex ti
 

	
 
			TILE_LOOP(tile_cur, w, h, tile) {
 
				MakeAirport(tile_cur, st->owner, st->index, *b);
 
				b++;
 
			}
 
		}
 

	
 
		st->UpdateVirtCoord();
 
		UpdateStationAcceptance(st, false);
 
		st->RecomputeIndustriesNear();
 
		InvalidateWindowData(WC_SELECT_STATION, 0, 0);
 
		InvalidateWindowData(WC_STATION_LIST, st->owner, 0);
 
		InvalidateWindowWidget(WC_STATION_VIEW, st->index, SVW_PLANES);
 
		SetWindowWidgetDirty(WC_STATION_VIEW, st->index, SVW_PLANES);
 

	
 
		if (_settings_game.economy.station_noise_level) {
 
			InvalidateWindow(WC_TOWN_VIEW, st->town->index);
 
			SetWindowDirty(WC_TOWN_VIEW, st->town->index);
 
		}
 
	}
 

	
 
	return cost;
 
}
 

	
 
/**
 
 * Remove an airport
 
 * @param tile TileIndex been queried
 
 * @param flags operation to perform
 
 * @return cost or failure of operation
 
 */
 
@@ -2057,28 +2057,28 @@ static CommandCost RemoveAirport(TileInd
 

	
 
		/* Go get the final noise level, that is base noise minus factor from distance to town center.
 
		 * And as for construction, always remove it, even if the setting is not set, in order to avoid the
 
		 * need of recalculation */
 
		Town *nearest = AirportGetNearestTown(afc, tile);
 
		nearest->noise_reached -= GetAirportNoiseLevelForTown(afc, nearest->xy, tile);
 

	
 
		st->rect.AfterRemoveRect(st, tile, w, h);
 

	
 
		st->airport_tile = INVALID_TILE;
 
		st->facilities &= ~FACIL_AIRPORT;
 

	
 
		InvalidateWindowWidget(WC_STATION_VIEW, st->index, SVW_PLANES);
 
		SetWindowWidgetDirty(WC_STATION_VIEW, st->index, SVW_PLANES);
 

	
 
		if (_settings_game.economy.station_noise_level) {
 
			InvalidateWindow(WC_TOWN_VIEW, st->town->index);
 
			SetWindowDirty(WC_TOWN_VIEW, st->town->index);
 
		}
 

	
 
		st->UpdateVirtCoord();
 
		st->RecomputeIndustriesNear();
 
		DeleteStationIfEmpty(st);
 
	}
 

	
 
	return cost;
 
}
 

	
 
/**
 
 * Tests whether the company's vehicles have this station in orders
 
@@ -2202,25 +2202,25 @@ CommandCost CmdBuildDock(TileIndex tile,
 

	
 
		st->rect.BeforeAddRect(
 
				tile + ToTileIndexDiff(_dock_tileoffs_chkaround[direction]),
 
				_dock_w_chk[direction], _dock_h_chk[direction], StationRect::ADD_TRY);
 

	
 
		MakeDock(tile, st->owner, st->index, direction, wc);
 

	
 
		st->UpdateVirtCoord();
 
		UpdateStationAcceptance(st, false);
 
		st->RecomputeIndustriesNear();
 
		InvalidateWindowData(WC_SELECT_STATION, 0, 0);
 
		InvalidateWindowData(WC_STATION_LIST, st->owner, 0);
 
		InvalidateWindowWidget(WC_STATION_VIEW, st->index, SVW_SHIPS);
 
		SetWindowWidgetDirty(WC_STATION_VIEW, st->index, SVW_SHIPS);
 
	}
 

	
 
	return CommandCost(EXPENSES_CONSTRUCTION, _price.build_dock);
 
}
 

	
 
/**
 
 * Remove a dock
 
 * @param tile TileIndex been queried
 
 * @param flags operation to perform
 
 * @return cost or failure of operation
 
 */
 
static CommandCost RemoveDock(TileIndex tile, DoCommandFlag flags)
 
@@ -2237,25 +2237,25 @@ static CommandCost RemoveDock(TileIndex 
 
	if (flags & DC_EXEC) {
 
		DoClearSquare(tile1);
 
		MakeWaterKeepingClass(tile2, st->owner);
 

	
 
		st->rect.AfterRemoveTile(st, tile1);
 
		st->rect.AfterRemoveTile(st, tile2);
 

	
 
		MarkTileDirtyByTile(tile2);
 

	
 
		st->dock_tile = INVALID_TILE;
 
		st->facilities &= ~FACIL_DOCK;
 

	
 
		InvalidateWindowWidget(WC_STATION_VIEW, st->index, SVW_SHIPS);
 
		SetWindowWidgetDirty(WC_STATION_VIEW, st->index, SVW_SHIPS);
 
		st->UpdateVirtCoord();
 
		st->RecomputeIndustriesNear();
 
		DeleteStationIfEmpty(st);
 
	}
 

	
 
	return CommandCost(EXPENSES_CONSTRUCTION, _price.remove_dock);
 
}
 

	
 
#include "table/station_land.h"
 

	
 
const DrawTileSprites *GetStationTileLayout(StationType st, byte gfx)
 
{
 
@@ -2814,27 +2814,27 @@ static void UpdateStationRating(Station 
 

	
 
					waiting = min(waiting, MAX_WAITING_CARGO);
 
					waiting_changed = true;
 
				}
 

	
 
				if (waiting_changed) ge->cargo.Truncate(waiting);
 
			}
 
		}
 
	} while (++ge != endof(st->goods));
 

	
 
	StationID index = st->index;
 
	if (waiting_changed) {
 
		InvalidateWindow(WC_STATION_VIEW, index); // update whole window
 
		SetWindowDirty(WC_STATION_VIEW, index); // update whole window
 
	} else {
 
		InvalidateWindowWidget(WC_STATION_VIEW, index, SVW_RATINGLIST); // update only ratings list
 
		SetWindowWidgetDirty(WC_STATION_VIEW, index, SVW_RATINGLIST); // update only ratings list
 
	}
 
}
 

	
 
/* called for every station each tick */
 
static void StationHandleSmallTick(BaseStation *st)
 
{
 
	if ((st->facilities & FACIL_WAYPOINT) != 0 || !st->IsInUse()) return;
 

	
 
	byte b = st->delete_ctr + 1;
 
	if (b >= 185) b = 0;
 
	st->delete_ctr = b;
 

	
 
@@ -2882,25 +2882,25 @@ void ModifyStationRatingAround(TileIndex
 
			}
 
		}
 
	}
 
}
 

	
 
static void UpdateStationWaiting(Station *st, CargoID type, uint amount, SourceType source_type, SourceID source_id)
 
{
 
	st->goods[type].cargo.Append(new CargoPacket(st->index, amount, source_type, source_id));
 
	SetBit(st->goods[type].acceptance_pickup, GoodsEntry::PICKUP);
 

	
 
	StationAnimationTrigger(st, st->xy, STAT_ANIM_NEW_CARGO, type);
 

	
 
	InvalidateWindow(WC_STATION_VIEW, st->index);
 
	SetWindowDirty(WC_STATION_VIEW, st->index);
 
	st->MarkTilesDirty(true);
 
}
 

	
 
static bool IsUniqueStationName(const char *name)
 
{
 
	const Station *st;
 

	
 
	FOR_ALL_STATIONS(st) {
 
		if (st->name != NULL && strcmp(st->name, name) == 0) return false;
 
	}
 

	
 
	return true;
src/station_gui.cpp
Show inline comments
 
@@ -245,25 +245,25 @@ protected:
 
		return -(minr1 - minr2);
 
	}
 

	
 
	/** Sort the stations list */
 
	void SortStationsList()
 
	{
 
		if (!this->stations.Sort()) return;
 

	
 
		/* Reset name sorter sort cache */
 
		this->last_station = NULL;
 

	
 
		/* Set the modified widget dirty */
 
		this->InvalidateWidget(SLW_LIST);
 
		this->SetWidgetDirty(SLW_LIST);
 
	}
 

	
 
public:
 
	CompanyStationsWindow(const WindowDesc *desc, WindowNumber window_number) : Window(desc, window_number)
 
	{
 
		this->owner = (Owner)this->window_number;
 
		this->vscroll.SetCapacity(12);
 
		this->resize.step_height = 10;
 
		this->resize.height = this->height - 10 * 7; // minimum if 5 in the list
 

	
 
		/* Add cargo filter buttons */
 
		uint num_active = 0;
 
@@ -960,25 +960,25 @@ struct StationViewWindow : public Window
 
				y += 10;
 
			}
 
		}
 
	}
 

	
 
	void HandleCargoWaitingClick(int row)
 
	{
 
		if (row == 0) return;
 

	
 
		for (CargoID c = 0; c < NUM_CARGO; c++) {
 
			if (this->cargo_rows[c] == row) {
 
				ToggleBit(this->cargo, c);
 
				this->InvalidateWidget(SVW_WAITING);
 
				this->SetWidgetDirty(SVW_WAITING);
 
				break;
 
			}
 
		}
 
	}
 

	
 
	virtual void OnClick(Point pt, int widget)
 
	{
 
		switch (widget) {
 
			case SVW_WAITING:
 
				this->HandleCargoWaitingClick((pt.y - this->widget[SVW_WAITING].top) / 10 + this->vscroll.GetPosition());
 
				break;
 

	
src/statusbar_gui.cpp
Show inline comments
 
@@ -162,32 +162,32 @@ struct StatusBarWindow : Window {
 
			case SBW_MIDDLE: ShowLastNewsMessage(); break;
 
			case SBW_RIGHT:  if (_local_company != COMPANY_SPECTATOR) ShowCompanyFinances(_local_company); break;
 
			default: ResetObjectToPlace();
 
		}
 
	}
 

	
 
	virtual void OnTick()
 
	{
 
		if (_pause_mode != PM_UNPAUSED) return;
 

	
 
		if (this->ticker_scroll < TICKER_STOP) { // Scrolling text
 
			this->ticker_scroll += COUNTER_STEP;
 
			this->InvalidateWidget(SBW_MIDDLE);
 
			this->SetWidgetDirty(SBW_MIDDLE);
 
		}
 

	
 
		if (this->reminder_timeout > REMINDER_STOP) { // Red blot to show there are new unread newsmessages
 
			this->reminder_timeout -= COUNTER_STEP;
 
		} else if (this->reminder_timeout < REMINDER_STOP) {
 
			this->reminder_timeout = REMINDER_STOP;
 
			this->InvalidateWidget(SBW_MIDDLE);
 
			this->SetWidgetDirty(SBW_MIDDLE);
 
		}
 
	}
 
};
 

	
 
static const Widget _main_status_widgets[] = {
 
{      WWT_PANEL,   RESIZE_NONE,   COLOUR_GREY,     0,   139,     0,    11, 0x0, STR_NULL},
 
{    WWT_PUSHBTN,   RESIZE_RIGHT,  COLOUR_GREY,   140,   179,     0,    11, 0x0, STR_STATUSBAR_TOOLTIP_SHOW_LAST_NEWS},
 
{    WWT_PUSHBTN,   RESIZE_LR,     COLOUR_GREY,   180,   319,     0,    11, 0x0, STR_NULL},
 
{   WIDGETS_END},
 
};
 

	
 
static const NWidgetPart _nested_main_status_widgets[] = {
src/terraform_gui.cpp
Show inline comments
 
@@ -725,25 +725,25 @@ struct ScenarioEditorLandscapeGeneration
 
						ResetLandscapeConfirmationCallback);
 
					break;
 
			}
 
		}
 
	}
 

	
 
	virtual void OnTimeout()
 
	{
 
		for (uint i = ETTW_START; i < this->nested_array_size; i++) {
 
			if (i == ETTW_BUTTONS_START) i = ETTW_BUTTONS_END; // skip the buttons
 
			if (this->IsWidgetLowered(i)) {
 
				this->RaiseWidget(i);
 
				this->InvalidateWidget(i);
 
				this->SetWidgetDirty(i);
 
			}
 
		}
 
	}
 

	
 
	virtual void OnPlaceObject(Point pt, TileIndex tile)
 
	{
 
		_place_proc(tile);
 
	}
 

	
 
	virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt)
 
	{
 
		VpSelectTilesWithMethod(pt.x, pt.y, select_method);
src/timetable_cmd.cpp
Show inline comments
 
@@ -31,25 +31,25 @@ static void ChangeTimetable(Vehicle *v, 
 
		order->wait_time = time;
 
	}
 
	v->orders.list->UpdateOrderTimetable(delta);
 

	
 
	for (v = v->FirstShared(); v != NULL; v = v->NextShared()) {
 
		if (v->cur_order_index == order_number && v->current_order.Equals(*order)) {
 
			if (is_journey) {
 
				v->current_order.travel_time = time;
 
			} else {
 
				v->current_order.wait_time = time;
 
			}
 
		}
 
		InvalidateWindow(WC_VEHICLE_TIMETABLE, v->index);
 
		SetWindowDirty(WC_VEHICLE_TIMETABLE, v->index);
 
	}
 
}
 

	
 
/**
 
 * Add or remove waiting times from an order.
 
 * @param tile Not used.
 
 * @param flags Operation to perform.
 
 * @param p1 Various bitstuffed elements
 
 * - p1 = (bit  0-15) - Vehicle with the orders to change.
 
 * - p1 = (bit 16-23) - Order index to modify.
 
 * - p1 = (bit    24) - Whether to change the waiting time or the travelling
 
 *                      time.
 
@@ -167,25 +167,25 @@ CommandCost CmdAutofillTimetable(TileInd
 
		} else {
 
			ClrBit(v->vehicle_flags, VF_AUTOFILL_TIMETABLE);
 
			ClrBit(v->vehicle_flags, VF_AUTOFILL_PRES_WAIT_TIME);
 
		}
 
	}
 

	
 
	for (Vehicle *v2 = v->FirstShared(); v2 != NULL; v2 = v2->NextShared()) {
 
		if (v2 != v) {
 
			/* Stop autofilling; only one vehicle at a time can perform autofill */
 
			ClrBit(v2->vehicle_flags, VF_AUTOFILL_TIMETABLE);
 
			ClrBit(v2->vehicle_flags, VF_AUTOFILL_PRES_WAIT_TIME);
 
		}
 
		InvalidateWindow(WC_VEHICLE_TIMETABLE, v2->index);
 
		SetWindowDirty(WC_VEHICLE_TIMETABLE, v2->index);
 
	}
 

	
 
	return CommandCost();
 
}
 

	
 
void UpdateVehicleTimetable(Vehicle *v, bool travelling)
 
{
 
	uint timetabled = travelling ? v->current_order.travel_time : v->current_order.wait_time;
 
	uint time_taken = v->current_order_time;
 

	
 
	v->current_order_time = 0;
 

	
 
@@ -232,15 +232,15 @@ void UpdateVehicleTimetable(Vehicle *v, 
 
	}
 

	
 
	if (just_started) return;
 

	
 
	/* Vehicles will wait at stations if they arrive early even if they are not
 
	 * timetabled to wait there, so make sure the lateness counter is updated
 
	 * when this happens. */
 
	if (timetabled == 0 && (travelling || v->lateness_counter >= 0)) return;
 

	
 
	v->lateness_counter -= (timetabled - time_taken);
 

	
 
	for (v = v->FirstShared(); v != NULL; v = v->NextShared()) {
 
		InvalidateWindow(WC_VEHICLE_TIMETABLE, v->index);
 
		SetWindowDirty(WC_VEHICLE_TIMETABLE, v->index);
 
	}
 
}
src/toolbar_gui.cpp
Show inline comments
 
@@ -1111,48 +1111,48 @@ struct MainToolbarWindow : Window {
 
		return ES_HANDLED;
 
	}
 

	
 
	virtual void OnPlaceObject(Point pt, TileIndex tile)
 
	{
 
		_place_proc(tile);
 
	}
 

	
 
	virtual void OnTick()
 
	{
 
		if (this->IsWidgetLowered(TBN_PAUSE) != !!_pause_mode) {
 
			this->ToggleWidgetLoweredState(TBN_PAUSE);
 
			this->InvalidateWidget(TBN_PAUSE);
 
			this->SetWidgetDirty(TBN_PAUSE);
 
		}
 

	
 
		if (this->IsWidgetLowered(TBN_FASTFORWARD) != !!_fast_forward) {
 
			this->ToggleWidgetLoweredState(TBN_FASTFORWARD);
 
			this->InvalidateWidget(TBN_FASTFORWARD);
 
			this->SetWidgetDirty(TBN_FASTFORWARD);
 
		}
 
	}
 

	
 
	virtual void OnResize(Point delta)
 
	{
 
		if (this->width <= TBP_NORMAL_MAXBUTTON * TBP_BUTTONWIDTH) {
 
			SplitToolbar(this);
 
		} else {
 
			ResizeToolbar(this);
 
		}
 
	}
 

	
 
	virtual void OnTimeout()
 
	{
 
		for (uint i = TBN_SETTINGS; i < this->widget_count - 1; i++) {
 
			if (this->IsWidgetLowered(i)) {
 
				this->RaiseWidget(i);
 
				this->InvalidateWidget(i);
 
				this->SetWidgetDirty(i);
 
			}
 
		}
 
	}
 

	
 
	virtual void OnInvalidateData(int data)
 
	{
 
		if (FindWindowById(WC_MAIN_WINDOW, 0) != NULL) HandleZoomMessage(this, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, TBN_ZOOMIN, TBN_ZOOMOUT);
 
	}
 
};
 

	
 
static const Widget _toolb_normal_widgets[] = {
 
{     WWT_IMGBTN,   RESIZE_LEFT,  COLOUR_GREY,     0,     0,     0,    21, SPR_IMG_PAUSE,           STR_TOOLBAR_TOOLTIP_PAUSE_GAME},               // TBN_PAUSE
 
@@ -1384,26 +1384,26 @@ public:
 
			if (extra_spacing_at[j] == i) {
 
				j++;
 
				uint add = spacing / (lengthof(extra_spacing_at) - j);
 
				spacing -= add;
 
				x += add;
 
			}
 
		}
 
	}
 

	
 
	virtual void OnTimeout()
 
	{
 
		this->SetWidgetsLoweredState(false, TBSE_DATEBACKWARD, TBSE_DATEFORWARD, WIDGET_LIST_END);
 
		this->InvalidateWidget(TBSE_DATEBACKWARD);
 
		this->InvalidateWidget(TBSE_DATEFORWARD);
 
		this->SetWidgetDirty(TBSE_DATEBACKWARD);
 
		this->SetWidgetDirty(TBSE_DATEFORWARD);
 
	}
 

	
 
	virtual void OnTick()
 
	{
 
		if (this->IsWidgetLowered(TBSE_PAUSE) != !!_pause_mode) {
 
			this->ToggleWidgetLoweredState(TBSE_PAUSE);
 
			this->SetDirty();
 
		}
 

	
 
		if (this->IsWidgetLowered(TBSE_FASTFORWARD) != !!_fast_forward) {
 
			this->ToggleWidgetLoweredState(TBSE_FASTFORWARD);
 
			this->SetDirty();
src/town_cmd.cpp
Show inline comments
 
@@ -330,46 +330,46 @@ static bool IsCloseToTown(TileIndex tile
 
/**
 
 * Resize the sign(label) of the town after changes in
 
 * population (creation or growth or else)
 
 */
 
void Town::UpdateVirtCoord()
 
{
 
	Point pt = RemapCoords2(TileX(this->xy) * TILE_SIZE, TileY(this->xy) * TILE_SIZE);
 
	SetDParam(0, this->index);
 
	SetDParam(1, this->population);
 
	this->sign.UpdatePosition(pt.x, pt.y - 24,
 
		_settings_client.gui.population_in_label ? STR_VIEWPORT_TOWN_POP : STR_VIEWPORT_TOWN);
 

	
 
	InvalidateWindow(WC_TOWN_VIEW, this->index);
 
	SetWindowDirty(WC_TOWN_VIEW, this->index);
 
}
 

	
 
/** Update the virtual coords needed to draw the town sign for all towns. */
 
void UpdateAllTownVirtCoords()
 
{
 
	Town *t;
 

	
 
	FOR_ALL_TOWNS(t) {
 
		t->UpdateVirtCoord();
 
	}
 
}
 

	
 
/**
 
 * Change the towns population
 
 * @param t Town which polulation has changed
 
 * @param mod polulation change (can be positive or negative)
 
 */
 
static void ChangePopulation(Town *t, int mod)
 
{
 
	t->population += mod;
 
	InvalidateWindow(WC_TOWN_VIEW, t->index);
 
	SetWindowDirty(WC_TOWN_VIEW, t->index);
 
	t->UpdateVirtCoord();
 

	
 
	InvalidateWindowData(WC_TOWN_DIRECTORY, 0, 1);
 
}
 

	
 
/**
 
 * Determines the world population
 
 * Basically, count population of all towns, one by one
 
 * @return uint32 the calculated population of the world
 
 */
 
uint32 GetWorldPopulation()
 
{
 
@@ -2462,25 +2462,25 @@ static void TownActionBribe(Town *t)
 
		}
 

	
 
		/* only show errormessage to the executing player. All errors are handled command.c
 
		 * but this is special, because it can only 'fail' on a DC_EXEC */
 
		if (IsLocalCompany()) ShowErrorMessage(STR_ERROR_BRIBE_FAILED_2, STR_ERROR_BRIBE_FAILED, 0, 0);
 

	
 
		/* decrease by a lot!
 
		 * ChangeTownRating is only for stuff in demolishing. Bribe failure should
 
		 * be independent of any cheat settings
 
		 */
 
		if (t->ratings[_current_company] > RATING_BRIBE_DOWN_TO) {
 
			t->ratings[_current_company] = RATING_BRIBE_DOWN_TO;
 
			InvalidateWindow(WC_TOWN_AUTHORITY, t->index);
 
			SetWindowDirty(WC_TOWN_AUTHORITY, t->index);
 
		}
 
	} else {
 
		ChangeTownRating(t, RATING_BRIBE_UP_STEP, RATING_BRIBE_MAXIMUM, DC_EXEC);
 
	}
 
}
 

	
 
typedef void TownActionProc(Town *t);
 
static TownActionProc * const _town_action_proc[] = {
 
	TownActionAdvertiseSmall,
 
	TownActionAdvertiseMedium,
 
	TownActionAdvertiseLarge,
 
	TownActionRoadRebuild,
 
@@ -2566,25 +2566,25 @@ uint GetMaskOfTownActions(int *nump, Com
 
 */
 
CommandCost CmdDoTownAction(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
 
{
 
	Town *t = Town::GetIfValid(p1);
 
	if (t == NULL || p2 >= lengthof(_town_action_proc)) return CMD_ERROR;
 

	
 
	if (!HasBit(GetMaskOfTownActions(NULL, _current_company, t), p2)) return CMD_ERROR;
 

	
 
	CommandCost cost(EXPENSES_OTHER, (_price.build_industry >> 8) * _town_action_costs[p2]);
 

	
 
	if (flags & DC_EXEC) {
 
		_town_action_proc[p2](t);
 
		InvalidateWindow(WC_TOWN_AUTHORITY, p1);
 
		SetWindowDirty(WC_TOWN_AUTHORITY, p1);
 
	}
 

	
 
	return cost;
 
}
 

	
 
static void UpdateTownGrowRate(Town *t)
 
{
 
	/* Increase company ratings if they're low */
 
	const Company *c;
 
	FOR_ALL_COMPANIES(c) {
 
		if (t->ratings[c->index] < RATING_GROWTH_MAXIMUM) {
 
			t->ratings[c->index] = min((int)RATING_GROWTH_MAXIMUM, t->ratings[c->index] + RATING_GROWTH_UP_STEP);
 
@@ -2607,25 +2607,25 @@ static void UpdateTownGrowRate(Town *t)
 
					int new_rating = t->ratings[st->owner] + RATING_STATION_DOWN_STEP;
 
					t->ratings[st->owner] = max(new_rating, INT16_MIN);
 
				}
 
			}
 
		}
 
	}
 

	
 
	/* clamp all ratings to valid values */
 
	for (uint i = 0; i < MAX_COMPANIES; i++) {
 
		t->ratings[i] = Clamp(t->ratings[i], RATING_MINIMUM, RATING_MAXIMUM);
 
	}
 

	
 
	InvalidateWindow(WC_TOWN_AUTHORITY, t->index);
 
	SetWindowDirty(WC_TOWN_AUTHORITY, t->index);
 

	
 
	ClrBit(t->flags, TOWN_IS_FUNDED);
 
	if (_settings_game.economy.town_growth_rate == 0 && t->fund_buildings_months == 0) return;
 

	
 
	/** Towns are processed every TOWN_GROWTH_FREQUENCY ticks, and this is the
 
	 * number of times towns are processed before a new building is built. */
 
	static const uint16 _grow_count_values[2][6] = {
 
		{ 120, 120, 120, 100,  80,  60 }, // Fund new buildings has been activated
 
		{ 320, 420, 300, 220, 160, 100 }  // Normal values
 
	};
 

	
 
	uint16 m;
 
@@ -2666,25 +2666,25 @@ static void UpdateTownAmounts(Town *t)
 
	t->pct_pass_transported = t->new_act_pass * 256 / (t->new_max_pass + 1);
 

	
 
	t->max_pass = t->new_max_pass; t->new_max_pass = 0;
 
	t->act_pass = t->new_act_pass; t->new_act_pass = 0;
 
	t->act_food = t->new_act_food; t->new_act_food = 0;
 
	t->act_water = t->new_act_water; t->new_act_water = 0;
 

	
 
	/* Using +1 here to prevent overflow and division by zero */
 
	t->pct_mail_transported = t->new_act_mail * 256 / (t->new_max_mail + 1);
 
	t->max_mail = t->new_max_mail; t->new_max_mail = 0;
 
	t->act_mail = t->new_act_mail; t->new_act_mail = 0;
 

	
 
	InvalidateWindow(WC_TOWN_VIEW, t->index);
 
	SetWindowDirty(WC_TOWN_VIEW, t->index);
 
}
 

	
 
static void UpdateTownUnwanted(Town *t)
 
{
 
	const Company *c;
 

	
 
	FOR_ALL_COMPANIES(c) {
 
		if (t->unwanted[c->index] > 0) t->unwanted[c->index]--;
 
	}
 
}
 

	
 
/**
 
@@ -2812,25 +2812,25 @@ void ChangeTownRating(Town *t, int add, 
 
		}
 
	} else {
 
		if (rating < max) {
 
			rating += add;
 
			if (rating > max) rating = max;
 
		}
 
	}
 
	if (_town_rating_test) {
 
		_town_test_ratings[t] = rating;
 
	} else {
 
		SetBit(t->have_ratings, _current_company);
 
		t->ratings[_current_company] = rating;
 
		InvalidateWindow(WC_TOWN_AUTHORITY, t->index);
 
		SetWindowDirty(WC_TOWN_AUTHORITY, t->index);
 
	}
 
}
 

	
 
bool CheckforTownRating(DoCommandFlag flags, Town *t, TownRatingCheckType type)
 
{
 
	/* if magic_bulldozer cheat is active, town doesn't restrict your destructive actions */
 
	if (t == NULL || !Company::IsValidID(_current_company) ||
 
			_cheats.magic_bulldozer.value || (flags & DC_NO_TEST_TOWN_RATING)) {
 
		return true;
 
	}
 

	
 
	/* minimum rating needed to be allowed to remove stuff */
src/train_cmd.cpp
Show inline comments
 
@@ -121,26 +121,26 @@ void TrainPowerChanged(Train *v)
 

	
 
		if (HasBit(u->flags, VRF_POWEREDWAGON) && HasPowerOnRail(v->railtype, railtype)) {
 
			total_power += RailVehInfo(u->tcache.first_engine)->pow_wag_power;
 
		}
 
	}
 

	
 
	if (v->tcache.cached_power != total_power || v->tcache.cached_max_te != max_te) {
 
		/* If it has no power (no catenary), stop the train */
 
		if (total_power == 0) v->vehstatus |= VS_STOPPED;
 

	
 
		v->tcache.cached_power = total_power;
 
		v->tcache.cached_max_te = max_te;
 
		InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 
		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
		SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
 
		SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
	}
 
}
 

	
 

	
 
/**
 
 * Recalculates the cached weight of a train and its vehicles. Should be called each time the cargo on
 
 * the consist changes.
 
 * @param v First vehicle of the consist.
 
 */
 
static void TrainCargoChanged(Train *v)
 
{
 
	uint32 weight = 0;
 
@@ -346,25 +346,25 @@ void TrainConsistChanged(Train *v, bool 
 
	}
 

	
 
	/* store consist weight/max speed in cache */
 
	v->tcache.cached_max_speed = max_speed;
 
	v->tcache.cached_tilt = train_can_tilt;
 
	v->tcache.cached_max_curve_speed = GetTrainCurveSpeedLimit(v);
 

	
 
	/* recalculate cached weights and power too (we do this *after* the rest, so it is known which wagons are powered and need extra weight added) */
 
	TrainCargoChanged(v);
 

	
 
	if (v->IsFrontEngine()) {
 
		UpdateTrainAcceleration(v);
 
		InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 
		SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
 
	}
 
}
 

	
 
enum AccelType {
 
	AM_ACCEL,
 
	AM_BRAKE
 
};
 

	
 
/**
 
 * Get the stop location of (the center) of the front vehicle of a train at
 
 * a platform of a station.
 
 * @param station_id     the ID of the station where we're stopping
 
@@ -759,25 +759,25 @@ static CommandCost CmdBuildRailWagon(Eng
 
		v->random_bits = VehicleRandomBits();
 

	
 
		v->group_id = DEFAULT_GROUP;
 

	
 
		AddArticulatedParts(v, VEH_TRAIN);
 

	
 
		_new_vehicle_id = v->index;
 

	
 
		VehicleMove(v, false);
 
		TrainConsistChanged(v->First(), false);
 
		UpdateTrainGroupID(v->First());
 

	
 
		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
 
		SetWindowDirty(WC_VEHICLE_DEPOT, v->tile);
 
		if (IsLocalCompany()) {
 
			InvalidateAutoreplaceWindow(v->engine_type, v->group_id); // updates the replace Train window
 
		}
 
		Company::Get(_current_company)->num_engines[engine]++;
 

	
 
		CheckConsistencyOfArticulatedVehicle(v);
 
	}
 

	
 
	return value;
 
}
 

	
 
/** Move all free vehicles in the depot to the train */
 
@@ -930,25 +930,25 @@ CommandCost CmdBuildRailVehicle(TileInde
 
			AddArticulatedParts(v, VEH_TRAIN);
 
		}
 

	
 
		TrainConsistChanged(v, false);
 
		UpdateTrainGroupID(v);
 

	
 
		if (!HasBit(p2, 1) && !(flags & DC_AUTOREPLACE)) { // check if the cars should be added to the new vehicle
 
			NormalizeTrainVehInDepot(v);
 
		}
 

	
 
		InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
 
		InvalidateWindowClassesData(WC_TRAINS_LIST, 0);
 
		InvalidateWindow(WC_COMPANY, v->owner);
 
		SetWindowDirty(WC_COMPANY, v->owner);
 
		if (IsLocalCompany()) {
 
			InvalidateAutoreplaceWindow(v->engine_type, v->group_id); // updates the replace Train window
 
		}
 

	
 
		Company::Get(_current_company)->num_engines[p1]++;
 

	
 
		CheckConsistencyOfArticulatedVehicle(v);
 
	}
 

	
 
	return value;
 
}
 

	
 
@@ -1397,42 +1397,42 @@ CommandCost CmdMoveRailVehicle(TileIndex
 
			const GroupID tmp_g = src_head->group_id;
 
			CmdMoveRailVehicle(0, flags, src_head->index | (INVALID_VEHICLE << 16), 1, text);
 
			SetTrainGroupID(src_head, tmp_g);
 
			src_head = NULL; // don't do anything more to this train since the new call will do it
 
		}
 

	
 
		if (src_head != NULL) {
 
			NormaliseTrainConsist(src_head);
 
			TrainConsistChanged(src_head, false);
 
			UpdateTrainGroupID(src_head);
 
			if (src_head->IsFrontEngine()) {
 
				/* Update the refit button and window */
 
				InvalidateWindow(WC_VEHICLE_REFIT, src_head->index);
 
				InvalidateWindowWidget(WC_VEHICLE_VIEW, src_head->index, VVW_WIDGET_REFIT_VEH);
 
				SetWindowDirty(WC_VEHICLE_REFIT, src_head->index);
 
				SetWindowWidgetDirty(WC_VEHICLE_VIEW, src_head->index, VVW_WIDGET_REFIT_VEH);
 
			}
 
			/* Update the depot window */
 
			InvalidateWindow(WC_VEHICLE_DEPOT, src_head->tile);
 
			SetWindowDirty(WC_VEHICLE_DEPOT, src_head->tile);
 
		}
 

	
 
		if (dst_head != NULL) {
 
			NormaliseTrainConsist(dst_head);
 
			TrainConsistChanged(dst_head, false);
 
			UpdateTrainGroupID(dst_head);
 
			if (dst_head->IsFrontEngine()) {
 
				/* Update the refit button and window */
 
				InvalidateWindowWidget(WC_VEHICLE_VIEW, dst_head->index, VVW_WIDGET_REFIT_VEH);
 
				InvalidateWindow(WC_VEHICLE_REFIT, dst_head->index);
 
				SetWindowWidgetDirty(WC_VEHICLE_VIEW, dst_head->index, VVW_WIDGET_REFIT_VEH);
 
				SetWindowDirty(WC_VEHICLE_REFIT, dst_head->index);
 
			}
 
			/* Update the depot window */
 
			InvalidateWindow(WC_VEHICLE_DEPOT, dst_head->tile);
 
			SetWindowDirty(WC_VEHICLE_DEPOT, dst_head->tile);
 
		}
 

	
 
		InvalidateWindowClassesData(WC_TRAINS_LIST, 0);
 
	}
 

	
 
	return CommandCost();
 
}
 

	
 
/** Sell a (single) train wagon/engine.
 
 * @param tile unused
 
 * @param flags type of operation
 
 * @param p1 the wagon/engine index
 
@@ -1461,25 +1461,25 @@ CommandCost CmdSellRailWagon(TileIndex t
 
	}
 

	
 
	if (v->IsRearDualheaded()) return_cmd_error(STR_ERROR_REAR_ENGINE_FOLLOW_FRONT);
 

	
 
	if (flags & DC_EXEC) {
 
		if (v == first && first->IsFrontEngine()) {
 
			DeleteWindowById(WC_VEHICLE_VIEW, first->index);
 
			DeleteWindowById(WC_VEHICLE_ORDERS, first->index);
 
			DeleteWindowById(WC_VEHICLE_REFIT, first->index);
 
			DeleteWindowById(WC_VEHICLE_DETAILS, first->index);
 
			DeleteWindowById(WC_VEHICLE_TIMETABLE, first->index);
 
		}
 
		InvalidateWindow(WC_VEHICLE_DEPOT, first->tile);
 
		SetWindowDirty(WC_VEHICLE_DEPOT, first->tile);
 
		InvalidateWindowClassesData(WC_TRAINS_LIST, 0);
 
	}
 

	
 
	CommandCost cost(EXPENSES_NEW_VEHICLES);
 
	switch (p2) {
 
		case 0: { // Delete given wagon
 
			bool switch_engine = false;    // update second wagon to engine?
 

	
 
			/* 1. Delete the engine, if it is dualheaded also delete the matching
 
			 * rear engine of the loco (from the point of deletion onwards) */
 
			Train *rear = (v->IsMultiheaded() &&
 
				v->IsEngine()) ? v->other_multiheaded_part : NULL;
 
@@ -1537,25 +1537,25 @@ CommandCost CmdSellRailWagon(TileIndex t
 
				first = UnlinkWagon(v, first);
 
				delete v;
 

	
 
				/* 4 If the second wagon was an engine, update it to front_engine
 
				 * which UnlinkWagon() has changed to TS_Free_Car */
 
				if (switch_engine) first->SetFrontEngine();
 

	
 
				/* 5. If the train still exists, update its acceleration, window, etc. */
 
				if (first != NULL) {
 
					NormaliseTrainConsist(first);
 
					TrainConsistChanged(first, false);
 
					UpdateTrainGroupID(first);
 
					if (first->IsFrontEngine()) InvalidateWindow(WC_VEHICLE_REFIT, first->index);
 
					if (first->IsFrontEngine()) SetWindowDirty(WC_VEHICLE_REFIT, first->index);
 
				}
 

	
 
			}
 
		} break;
 
		case 1: { // Delete wagon and all wagons after it given certain criteria
 
			/* Start deleting every vehicle after the selected one
 
			 * If we encounter a matching rear-engine to a front-engine
 
			 * earlier in the chain (before deletion), leave it alone */
 
			for (Train *tmp; v != NULL; v = tmp) {
 
				tmp = v->GetNextVehicle();
 

	
 
				if (v->IsMultiheaded()) {
 
@@ -1588,25 +1588,25 @@ CommandCost CmdSellRailWagon(TileIndex t
 
				cost.AddCost(-v->value);
 
				if (flags & DC_EXEC) {
 
					first = UnlinkWagon(v, first);
 
					delete v;
 
				}
 
			}
 

	
 
			/* 3. If it is still a valid train after selling, update its acceleration and cached values */
 
			if ((flags & DC_EXEC) && first != NULL) {
 
				NormaliseTrainConsist(first);
 
				TrainConsistChanged(first, false);
 
				UpdateTrainGroupID(first);
 
				InvalidateWindow(WC_VEHICLE_REFIT, first->index);
 
				SetWindowDirty(WC_VEHICLE_REFIT, first->index);
 
			}
 
		} break;
 
	}
 
	return cost;
 
}
 

	
 
void Train::UpdateDeltaXY(Direction direction)
 
{
 
#define MKIT(a, b, c, d) ((a & 0xFF) << 24) | ((b & 0xFF) << 16) | ((c & 0xFF) << 8) | ((d & 0xFF) << 0)
 
	static const uint32 _delta_xy_table[8] = {
 
		MKIT(3, 3, -1, -1),
 
		MKIT(3, 7, -1, -3),
 
@@ -1624,47 +1624,47 @@ void Train::UpdateDeltaXY(Direction dire
 
	this->y_offs        = GB(x,  8, 8);
 
	this->x_extent      = GB(x, 16, 8);
 
	this->y_extent      = GB(x, 24, 8);
 
	this->z_extent      = 6;
 
}
 

	
 
static inline void SetLastSpeed(Train *v, int spd)
 
{
 
	int old = v->tcache.last_speed;
 
	if (spd != old) {
 
		v->tcache.last_speed = spd;
 
		if (_settings_client.gui.vehicle_speed || (old == 0) != (spd == 0)) {
 
			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
			SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
		}
 
	}
 
}
 

	
 
/** Mark a train as stuck and stop it if it isn't stopped right now. */
 
static void MarkTrainAsStuck(Train *v)
 
{
 
	if (!HasBit(v->flags, VRF_TRAIN_STUCK)) {
 
		/* It is the first time the problem occured, set the "train stuck" flag. */
 
		SetBit(v->flags, VRF_TRAIN_STUCK);
 

	
 
		/* When loading the vehicle is already stopped. No need to change that. */
 
		if (v->current_order.IsType(OT_LOADING)) return;
 

	
 
		v->load_unload_time_rem = 0;
 

	
 
		/* Stop train */
 
		v->cur_speed = 0;
 
		v->subspeed = 0;
 
		SetLastSpeed(v, 0);
 

	
 
		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
		SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
	}
 
}
 

	
 
static void SwapTrainFlags(uint16 *swap_flag1, uint16 *swap_flag2)
 
{
 
	uint16 flag1 = *swap_flag1;
 
	uint16 flag2 = *swap_flag2;
 

	
 
	/* Clear the flags */
 
	ClrBit(*swap_flag1, VRF_GOINGUP);
 
	ClrBit(*swap_flag1, VRF_GOINGDOWN);
 
	ClrBit(*swap_flag2, VRF_GOINGUP);
 
@@ -1951,25 +1951,25 @@ static void ReverseTrainDirection(Train 
 
	for (Vehicle *u = v; u != NULL; u = u->Next()) u->UpdateViewport(false, false);
 

	
 
	/* update crossing we were approaching */
 
	if (crossing != INVALID_TILE) UpdateLevelCrossing(crossing);
 

	
 
	/* maybe we are approaching crossing now, after reversal */
 
	crossing = TrainApproachingCrossingTile(v);
 
	if (crossing != INVALID_TILE) MaybeBarCrossingWithSound(crossing);
 

	
 
	/* If we are inside a depot after reversing, don't bother with path reserving. */
 
	if (v->track == TRACK_BIT_DEPOT) {
 
		/* Can't be stuck here as inside a depot is always a safe tile. */
 
		if (HasBit(v->flags, VRF_TRAIN_STUCK)) InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
		if (HasBit(v->flags, VRF_TRAIN_STUCK)) SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
		ClrBit(v->flags, VRF_TRAIN_STUCK);
 
		return;
 
	}
 

	
 
	/* TrainExitDir does not always produce the desired dir for depots and
 
	 * tunnels/bridges that is needed for UpdateSignalsOnSegment. */
 
	DiagDirection dir = TrainExitDir(v->direction, v->track);
 
	if (IsRailDepotTile(v->tile) || IsTileType(v->tile, MP_TUNNELBRIDGE)) dir = INVALID_DIAGDIR;
 

	
 
	if (UpdateSignalsOnSegment(v->tile, dir, v->owner) == SIGSEG_PBS || _settings_game.pf.reserve_paths) {
 
		/* If we are currently on a tile with conventional signals, we can't treat the
 
		 * current tile as a safe tile or we would enter a PBS block without a reservation. */
 
@@ -2009,26 +2009,26 @@ CommandCost CmdReverseTrainDirection(Til
 
		if (v->IsMultiheaded() || HasBit(EngInfo(v->engine_type)->callbackmask, CBM_VEHICLE_ARTIC_ENGINE)) {
 
			return_cmd_error(STR_ERROR_CAN_T_REVERSE_DIRECTION_RAIL_VEHICLE_MULTIPLE_UNITS);
 
		}
 

	
 
		Train *front = v->First();
 
		/* make sure the vehicle is stopped in the depot */
 
		if (CheckTrainStoppedInDepot(front) < 0) {
 
			return_cmd_error(STR_ERROR_TRAINS_CAN_ONLY_BE_ALTERED_INSIDE_A_DEPOT);
 
		}
 

	
 
		if (flags & DC_EXEC) {
 
			ToggleBit(v->flags, VRF_REVERSE_DIRECTION);
 
			InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
 
			InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 
			SetWindowDirty(WC_VEHICLE_DEPOT, v->tile);
 
			SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
 
		}
 
	} else {
 
		/* turn the whole train around */
 
		if ((v->vehstatus & VS_CRASHED) || v->breakdown_ctr != 0) return CMD_ERROR;
 

	
 
		if (flags & DC_EXEC) {
 
			/* Properly leave the station if we are loading and won't be loading anymore */
 
			if (v->current_order.IsType(OT_LOADING)) {
 
				const Vehicle *last = v;
 
				while (last->Next() != NULL) last = last->Next();
 

	
 
				/* not a station || different station --> leave the station */
 
@@ -2139,26 +2139,26 @@ CommandCost CmdRefitRailVehicle(TileInde
 
			}
 

	
 
			if (new_cid != v->cargo_type) {
 
				cost.AddCost(GetRefitCost(v->engine_type));
 
			}
 

	
 
			num += amount;
 
			if (flags & DC_EXEC) {
 
				v->cargo.Truncate((v->cargo_type == new_cid) ? amount : 0);
 
				v->cargo_type = new_cid;
 
				v->cargo_cap = amount;
 
				v->cargo_subtype = new_subtype;
 
				InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 
				InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
 
				SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
 
				SetWindowDirty(WC_VEHICLE_DEPOT, v->tile);
 
				InvalidateWindowClassesData(WC_TRAINS_LIST, 0);
 
			}
 
		}
 
	} while ((v = v->Next()) != NULL && !only_this);
 

	
 
	_returned_refit_capacity = num;
 

	
 
	/* Update the train's cached variables */
 
	if (flags & DC_EXEC) TrainConsistChanged(Train::Get(p1)->First(), false);
 

	
 
	return cost;
 
}
 
@@ -2428,71 +2428,71 @@ static void CheckNextTrainTile(Train *v)
 
}
 

	
 
static bool CheckTrainStayInDepot(Train *v)
 
{
 
	/* bail out if not all wagons are in the same depot or not in a depot at all */
 
	for (const Train *u = v; u != NULL; u = u->Next()) {
 
		if (u->track != TRACK_BIT_DEPOT || u->tile != v->tile) return false;
 
	}
 

	
 
	/* if the train got no power, then keep it in the depot */
 
	if (v->tcache.cached_power == 0) {
 
		v->vehstatus |= VS_STOPPED;
 
		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
 
		SetWindowDirty(WC_VEHICLE_DEPOT, v->tile);
 
		return true;
 
	}
 

	
 
	SigSegState seg_state;
 

	
 
	if (v->force_proceed == 0) {
 
		/* force proceed was not pressed */
 
		if (++v->load_unload_time_rem < 37) {
 
			InvalidateWindowClasses(WC_TRAINS_LIST);
 
			SetWindowClassesDirty(WC_TRAINS_LIST);
 
			return true;
 
		}
 

	
 
		v->load_unload_time_rem = 0;
 

	
 
		seg_state = _settings_game.pf.reserve_paths ? SIGSEG_PBS : UpdateSignalsOnSegment(v->tile, INVALID_DIAGDIR, v->owner);
 
		if (seg_state == SIGSEG_FULL || HasDepotReservation(v->tile)) {
 
			/* Full and no PBS signal in block or depot reserved, can't exit. */
 
			InvalidateWindowClasses(WC_TRAINS_LIST);
 
			SetWindowClassesDirty(WC_TRAINS_LIST);
 
			return true;
 
		}
 
	} else {
 
		seg_state = _settings_game.pf.reserve_paths ? SIGSEG_PBS : UpdateSignalsOnSegment(v->tile, INVALID_DIAGDIR, v->owner);
 
	}
 

	
 
	/* We are leaving a depot, but have to go to the exact same one; re-enter */
 
	if (v->current_order.IsType(OT_GOTO_DEPOT) && v->tile == v->dest_tile) {
 
		/* We need to have a reservation for this to work. */
 
		if (HasDepotReservation(v->tile)) return true;
 
		SetDepotReservation(v->tile, true);
 
		VehicleEnterDepot(v);
 
		return true;
 
	}
 

	
 
	/* Only leave when we can reserve a path to our destination. */
 
	if (seg_state == SIGSEG_PBS && !TryPathReserve(v) && v->force_proceed == 0) {
 
		/* No path and no force proceed. */
 
		InvalidateWindowClasses(WC_TRAINS_LIST);
 
		SetWindowClassesDirty(WC_TRAINS_LIST);
 
		MarkTrainAsStuck(v);
 
		return true;
 
	}
 

	
 
	SetDepotReservation(v->tile, true);
 
	if (_settings_client.gui.show_track_reservation) MarkTileDirtyByTile(v->tile);
 

	
 
	VehicleServiceInDepot(v);
 
	InvalidateWindowClasses(WC_TRAINS_LIST);
 
	SetWindowClassesDirty(WC_TRAINS_LIST);
 
	v->PlayLeaveStationSound();
 

	
 
	v->track = TRACK_BIT_X;
 
	if (v->direction & 2) v->track = TRACK_BIT_Y;
 

	
 
	v->vehstatus &= ~VS_HIDDEN;
 
	v->cur_speed = 0;
 

	
 
	v->UpdateDeltaXY(v->direction);
 
	v->cur_image = v->GetImage(v->direction);
 
	VehicleMove(v, false);
 
	UpdateSignalsOnSegment(v->tile, INVALID_DIAGDIR, v->owner);
 
@@ -3160,25 +3160,25 @@ bool TryPathReserve(Train *v, bool mark_
 
	/* The path we are driving on is alread blocked by some other train.
 
	 * This can only happen in certain situations when mixing path and
 
	 * block signals or when changing tracks and/or signals.
 
	 * Exit here as doing any further reservations will probably just
 
	 * make matters worse. */
 
	if (other_train && v->tile != origin.tile) {
 
		if (mark_as_stuck) MarkTrainAsStuck(v);
 
		return false;
 
	}
 
	/* If we have a reserved path and the path ends at a safe tile, we are finished already. */
 
	if (origin.okay && (v->tile != origin.tile || first_tile_okay)) {
 
		/* Can't be stuck then. */
 
		if (HasBit(v->flags, VRF_TRAIN_STUCK)) InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
		if (HasBit(v->flags, VRF_TRAIN_STUCK)) SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
		ClrBit(v->flags, VRF_TRAIN_STUCK);
 
		return true;
 
	}
 

	
 
	/* If we are in a depot, tentativly reserve the depot. */
 
	if (v->track == TRACK_BIT_DEPOT) {
 
		SetDepotReservation(v->tile, true);
 
		if (_settings_client.gui.show_track_reservation) MarkTileDirtyByTile(v->tile);
 
	}
 

	
 
	DiagDirection exitdir = TrackdirToExitdir(origin.trackdir);
 
	TileIndex     new_tile = TileAddByDiagDir(origin.tile, exitdir);
 
@@ -3188,25 +3188,25 @@ bool TryPathReserve(Train *v, bool mark_
 

	
 
	bool res_made = false;
 
	ChooseTrainTrack(v, new_tile, exitdir, reachable, true, &res_made, mark_as_stuck);
 

	
 
	if (!res_made) {
 
		/* Free the depot reservation as well. */
 
		if (v->track == TRACK_BIT_DEPOT) SetDepotReservation(v->tile, false);
 
		return false;
 
	}
 

	
 
	if (HasBit(v->flags, VRF_TRAIN_STUCK)) {
 
		v->load_unload_time_rem = 0;
 
		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
		SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
	}
 
	ClrBit(v->flags, VRF_TRAIN_STUCK);
 
	return true;
 
}
 

	
 

	
 
static bool CheckReverseTrain(Train *v)
 
{
 
	if (_settings_game.difficulty.line_reverse_mode != 0 ||
 
			v->track == TRACK_BIT_DEPOT || v->track == TRACK_BIT_WORMHOLE ||
 
			!(v->direction & 1)) {
 
		return false;
 
@@ -3527,29 +3527,29 @@ static void SetVehicleCrashed(Train *v)
 
				/* ClearPathReservation will not free the wormhole exit
 
				 * if the train has just entered the wormhole. */
 
				SetTunnelBridgeReservation(GetOtherTunnelBridgeEnd(u->tile), false);
 
			}
 
		}
 
	}
 

	
 
	/* we may need to update crossing we were approaching */
 
	TileIndex crossing = TrainApproachingCrossingTile(v);
 

	
 
	v->crash_anim_pos++;
 

	
 
	InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
	InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 
	SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
	SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
 

	
 
	if (v->track == TRACK_BIT_DEPOT) {
 
		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
 
		SetWindowDirty(WC_VEHICLE_DEPOT, v->tile);
 
	}
 

	
 
	InvalidateWindowClassesData(WC_TRAINS_LIST, 0);
 

	
 
	for (; v != NULL; v = v->Next()) {
 
		v->vehstatus |= VS_CRASHED;
 
		MarkSingleVehicleDirty(v);
 
	}
 

	
 
	/* must be updated after the train has been marked crashed */
 
	if (crossing != INVALID_TILE) UpdateLevelCrossing(crossing);
 
}
 
@@ -4015,25 +4015,25 @@ static void DeleteLastWagon(Train *v)
 
	 * *u is then the one-before-last wagon, and *v the last
 
	 * one which will physicially be removed */
 
	Train *u = v;
 
	for (; v->Next() != NULL; v = v->Next()) u = v;
 
	u->SetNext(NULL);
 

	
 
	if (first != v) {
 
		/* Recalculate cached train properties */
 
		TrainConsistChanged(first, false);
 
		/* Update the depot window if the first vehicle is in depot -
 
		 * if v == first, then it is updated in PreDestructor() */
 
		if (first->track == TRACK_BIT_DEPOT) {
 
			InvalidateWindow(WC_VEHICLE_DEPOT, first->tile);
 
			SetWindowDirty(WC_VEHICLE_DEPOT, first->tile);
 
		}
 
	}
 

	
 
	/* 'v' shouldn't be accessed after it has been deleted */
 
	TrackBits trackbits = v->track;
 
	TileIndex tile = v->tile;
 
	Owner owner = v->owner;
 

	
 
	delete v;
 
	v = NULL; // make sure nobody will try to read 'v' anymore
 

	
 
	if (trackbits == TRACK_BIT_WORMHOLE) {
 
@@ -4112,58 +4112,58 @@ static bool HandleCrashedTrain(Train *v)
 
					GB(r,  0, 3) + 5,
 
					EV_EXPLOSION_SMALL);
 
				break;
 
			}
 
		} while ((u = u->Next()) != NULL);
 
	}
 

	
 
	if (state <= 240 && !(v->tick_counter & 3)) ChangeTrainDirRandomly(v);
 

	
 
	if (state >= 4440 && !(v->tick_counter & 0x1F)) {
 
		bool ret = v->Next() != NULL;
 
		DeleteLastWagon(v);
 
		InvalidateWindow(WC_REPLACE_VEHICLE, (v->group_id << 16) | VEH_TRAIN);
 
		SetWindowDirty(WC_REPLACE_VEHICLE, (v->group_id << 16) | VEH_TRAIN);
 
		return ret;
 
	}
 

	
 
	return true;
 
}
 

	
 
static void HandleBrokenTrain(Train *v)
 
{
 
	if (v->breakdown_ctr != 1) {
 
		v->breakdown_ctr = 1;
 
		v->cur_speed = 0;
 

	
 
		if (v->breakdowns_since_last_service != 255)
 
			v->breakdowns_since_last_service++;
 

	
 
		InvalidateWindow(WC_VEHICLE_VIEW, v->index);
 
		InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 
		SetWindowDirty(WC_VEHICLE_VIEW, v->index);
 
		SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
 

	
 
		if (!PlayVehicleSound(v, VSE_BREAKDOWN)) {
 
			SndPlayVehicleFx((_settings_game.game_creation.landscape != LT_TOYLAND) ?
 
				SND_10_TRAIN_BREAKDOWN : SND_3A_COMEDY_BREAKDOWN_2, v);
 
		}
 

	
 
		if (!(v->vehstatus & VS_HIDDEN)) {
 
			EffectVehicle *u = CreateEffectVehicleRel(v, 4, 4, 5, EV_BREAKDOWN_SMOKE);
 
			if (u != NULL) u->animation_state = v->breakdown_delay * 2;
 
		}
 
	}
 

	
 
	if (!(v->tick_counter & 3)) {
 
		if (!--v->breakdown_delay) {
 
			v->breakdown_ctr = 0;
 
			InvalidateWindow(WC_VEHICLE_VIEW, v->index);
 
			SetWindowDirty(WC_VEHICLE_VIEW, v->index);
 
		}
 
	}
 
}
 

	
 
/** Maximum speeds for train that is broken down or approaching line end */
 
static const uint16 _breakdown_speeds[16] = {
 
	225, 210, 195, 180, 165, 150, 135, 120, 105, 90, 75, 60, 45, 30, 15, 15
 
};
 

	
 

	
 
/**
 
 * Train is approaching line end, slow down and possibly reverse
 
@@ -4321,25 +4321,25 @@ static bool TrainCheckIfLineEnds(Train *
 

	
 

	
 
static bool TrainLocoHandler(Train *v, bool mode)
 
{
 
	/* train has crashed? */
 
	if (v->vehstatus & VS_CRASHED) {
 
		return mode ? true : HandleCrashedTrain(v); // 'this' can be deleted here
 
	}
 

	
 
	if (v->force_proceed != 0) {
 
		v->force_proceed--;
 
		ClrBit(v->flags, VRF_TRAIN_STUCK);
 
		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
		SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
	}
 

	
 
	/* train is broken down? */
 
	if (v->breakdown_ctr != 0) {
 
		if (v->breakdown_ctr <= 2) {
 
			HandleBrokenTrain(v);
 
			return true;
 
		}
 
		if (!v->current_order.IsType(OT_LOADING)) v->breakdown_ctr--;
 
	}
 

	
 
	if (HasBit(v->flags, VRF_REVERSING) && v->cur_speed == 0) {
 
@@ -4390,39 +4390,39 @@ static bool TrainLocoHandler(Train *v, b
 
					AddVehicleNewsItem(
 
						STR_NEWS_TRAIN_IS_STUCK,
 
						NS_ADVICE,
 
						v->index
 
					);
 
				}
 
				v->load_unload_time_rem = 0;
 
			}
 
			/* Exit if force proceed not pressed, else reset stuck flag anyway. */
 
			if (v->force_proceed == 0) return true;
 
			ClrBit(v->flags, VRF_TRAIN_STUCK);
 
			v->load_unload_time_rem = 0;
 
			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
			SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
		}
 
	}
 

	
 
	if (v->current_order.IsType(OT_LEAVESTATION)) {
 
		v->current_order.Free();
 
		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
		SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
		return true;
 
	}
 

	
 
	int j = UpdateTrainSpeed(v);
 

	
 
	/* we need to invalidate the widget if we are stopping from 'Stopping 0 km/h' to 'Stopped' */
 
	if (v->cur_speed == 0 && v->tcache.last_speed == 0 && (v->vehstatus & VS_STOPPED)) {
 
		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
		SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
	}
 

	
 
	int adv_spd = (v->direction & 1) ? 192 : 256;
 
	if (j < adv_spd) {
 
		/* if the vehicle has speed 0, update the last_speed field. */
 
		if (v->cur_speed == 0) SetLastSpeed(v, v->cur_speed);
 
	} else {
 
		TrainCheckIfLineEnds(v);
 
		/* Loop until the train has finished moving. */
 
		for (;;) {
 
			j -= adv_spd;
 
			TrainController(v, NULL);
 
@@ -4512,40 +4512,40 @@ static void CheckIfTrainNeedsService(Tra
 
		VehicleServiceInDepot(v);
 
		return;
 
	}
 

	
 
	TrainFindDepotData tfdd = FindClosestTrainDepot(v, MAX_ACCEPTABLE_DEPOT_DIST);
 
	/* Only go to the depot if it is not too far out of our way. */
 
	if (tfdd.best_length == UINT_MAX || tfdd.best_length > MAX_ACCEPTABLE_DEPOT_DIST) {
 
		if (v->current_order.IsType(OT_GOTO_DEPOT)) {
 
			/* If we were already heading for a depot but it has
 
			 * suddenly moved farther away, we continue our normal
 
			 * schedule? */
 
			v->current_order.MakeDummy();
 
			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
			SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
		}
 
		return;
 
	}
 

	
 
	DepotID depot = GetDepotIndex(tfdd.tile);
 

	
 
	if (v->current_order.IsType(OT_GOTO_DEPOT) &&
 
			v->current_order.GetDestination() != depot &&
 
			!Chance16(3, 16)) {
 
		return;
 
	}
 

	
 
	v->current_order.MakeGoToDepot(depot, ODTFB_SERVICE);
 
	v->dest_tile = tfdd.tile;
 
	InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
	SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
}
 

	
 
void Train::OnNewDay()
 
{
 
	if ((++this->day_counter & 7) == 0) DecreaseVehicleValue(this);
 

	
 
	if (this->IsFrontEngine()) {
 
		CheckVehicleBreakdown(this);
 
		AgeVehicle(this);
 

	
 
		CheckIfTrainNeedsService(this);
 

	
 
@@ -4557,26 +4557,26 @@ void Train::OnNewDay()
 
			if (tile != INVALID_TILE) this->dest_tile = tile;
 
		}
 

	
 
		if (this->running_ticks != 0) {
 
			/* running costs */
 
			CommandCost cost(EXPENSES_TRAIN_RUN, this->GetRunningCost() * this->running_ticks / (DAYS_IN_YEAR  * DAY_TICKS));
 

	
 
			this->profit_this_year -= cost.GetCost();
 
			this->running_ticks = 0;
 

	
 
			SubtractMoneyFromCompanyFract(this->owner, cost);
 

	
 
			InvalidateWindow(WC_VEHICLE_DETAILS, this->index);
 
			InvalidateWindowClasses(WC_TRAINS_LIST);
 
			SetWindowDirty(WC_VEHICLE_DETAILS, this->index);
 
			SetWindowClassesDirty(WC_TRAINS_LIST);
 
		}
 
	} else if (this->IsEngine()) {
 
		/* Also age engines that aren't front engines */
 
		AgeVehicle(this);
 
	}
 
}
 

	
 
Trackdir Train::GetVehicleTrackdir() const
 
{
 
	if (this->vehstatus & VS_CRASHED) return INVALID_TRACKDIR;
 

	
 
	if (this->track == TRACK_BIT_DEPOT) {
src/transparency_gui.cpp
Show inline comments
 
@@ -108,25 +108,25 @@ public:
 
				if (IsInsideBS(pt.x, nwid->pos_x, nwid->current_x))
 
					break;
 
			}
 
			if (i == TTW_WIDGET_LOADING || i == TTW_WIDGET_END) return;
 

	
 
			ToggleInvisibility((TransparencyOption)(i - TTW_WIDGET_BEGIN));
 
			SndPlayFx(SND_15_BEEP);
 

	
 
			/* Redraw whole screen only if transparency is set */
 
			if (IsTransparencySet((TransparencyOption)(i - TTW_WIDGET_BEGIN))) {
 
				MarkWholeScreenDirty();
 
			} else {
 
				this->InvalidateWidget(TTW_WIDGET_BUTTONS);
 
				this->SetWidgetDirty(TTW_WIDGET_BUTTONS);
 
			}
 
		}
 
	}
 

	
 
	virtual void OnInvalidateData(int data)
 
	{
 
		for (uint i = TTW_WIDGET_BEGIN; i < TTW_WIDGET_END; i++) {
 
			this->SetWidgetLoweredState(i, IsTransparencySet((TransparencyOption)(i - TTW_WIDGET_BEGIN)));
 
		}
 
	}
 
};
 

	
src/tree_gui.cpp
Show inline comments
 
@@ -143,25 +143,25 @@ public:
 

	
 
	virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile)
 
	{
 
		if (pt.x != -1 && select_proc == DDSP_PLANT_TREES) {
 
			DoCommandP(end_tile, this->tree_to_plant, start_tile,
 
				CMD_PLANT_TREE | CMD_MSG(STR_ERROR_CAN_T_PLANT_TREE_HERE));
 
		}
 
	}
 

	
 
	virtual void OnTimeout()
 
	{
 
		this->RaiseWidget(BTW_MANY_RANDOM);
 
		this->InvalidateWidget(BTW_MANY_RANDOM);
 
		this->SetWidgetDirty(BTW_MANY_RANDOM);
 
	}
 

	
 
	virtual void OnPlaceObjectAbort()
 
	{
 
		this->RaiseButtons();
 
	}
 
};
 

	
 
static const Widget _build_trees_widgets[] = {
 
{   WWT_CLOSEBOX,   RESIZE_NONE,  COLOUR_DARK_GREEN,   0,    10,     0,    13, STR_BLACK_CROSS,               STR_TOOLTIP_CLOSE_WINDOW},           // BTW_CLOSE
 
{    WWT_CAPTION,   RESIZE_NONE,  COLOUR_DARK_GREEN,  11,   142,     0,    13, STR_PLANT_TREE_CAPTION,        STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS}, // BTW_CAPTION
 
{      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,   0,   142,    14,   183, 0x0,                           STR_NULL},                           // BTW_BACKGROUND
src/unmovable_cmd.cpp
Show inline comments
 
@@ -60,25 +60,25 @@ static inline const UnmovableSpec *GetUn
 
static CommandCost DestroyCompanyHQ(CompanyID cid, DoCommandFlag flags)
 
{
 
	Company *c = Company::Get(cid);
 

	
 
	if (flags & DC_EXEC) {
 
		TileIndex t = c->location_of_HQ;
 

	
 
		DoClearSquare(t);
 
		DoClearSquare(t + TileDiffXY(0, 1));
 
		DoClearSquare(t + TileDiffXY(1, 0));
 
		DoClearSquare(t + TileDiffXY(1, 1));
 
		c->location_of_HQ = INVALID_TILE; // reset HQ position
 
		InvalidateWindow(WC_COMPANY, cid);
 
		SetWindowDirty(WC_COMPANY, cid);
 

	
 
		CargoPacket::InvalidateAllFrom(ST_HEADQUARTERS, cid);
 
	}
 

	
 
	/* cost of relocating company is 1% of company value */
 
	return CommandCost(EXPENSES_PROPERTY, CalculateCompanyValue(c) / 100);
 
}
 

	
 
void UpdateCompanyHQ(Company *c, uint score)
 
{
 
	byte val;
 
	TileIndex tile = c->location_of_HQ;
 
@@ -118,25 +118,25 @@ CommandCost CmdBuildCompanyHQ(TileIndex 
 
	if (c->location_of_HQ != INVALID_TILE) { // Moving HQ
 
		cost.AddCost(DestroyCompanyHQ(_current_company, flags));
 
	}
 

	
 
	if (flags & DC_EXEC) {
 
		int score = UpdateCompanyRatingAndValue(c, false);
 

	
 
		c->location_of_HQ = tile;
 

	
 
		MakeCompanyHQ(tile, _current_company);
 

	
 
		UpdateCompanyHQ(c, score);
 
		InvalidateWindow(WC_COMPANY, c->index);
 
		SetWindowDirty(WC_COMPANY, c->index);
 
	}
 

	
 
	return cost;
 
}
 

	
 
/** Purchase a land area. Actually you only purchase one tile, so
 
 * the name is a bit confusing ;p
 
 * @param tile the tile the company is purchasing
 
 * @param flags for this command type
 
 * @param p1 unused
 
 * @param p2 unused
 
 * @return error of cost of operation
 
@@ -282,25 +282,25 @@ static CommandCost ClearTile_Unmovable(T
 
		return DoCommand(tile, 0, 0, flags, CMD_SELL_LAND_AREA);
 
	}
 

	
 
	/* checks if you're allowed to remove unmovable things */
 
	if (_game_mode != GM_EDITOR && _current_company != OWNER_WATER && ((flags & DC_AUTO) || !_cheats.magic_bulldozer.value) )
 
		return_cmd_error(flags & DC_AUTO ? STR_ERROR_OBJECT_IN_THE_WAY : INVALID_STRING_ID);
 

	
 
	if (IsStatue(tile)) {
 
		if (flags & DC_AUTO) return_cmd_error(STR_ERROR_OBJECT_IN_THE_WAY);
 

	
 
		TownID town = GetStatueTownID(tile);
 
		ClrBit(Town::Get(town)->statues, GetTileOwner(tile));
 
		InvalidateWindow(WC_TOWN_AUTHORITY, town);
 
		SetWindowDirty(WC_TOWN_AUTHORITY, town);
 
	}
 

	
 
	if (flags & DC_EXEC) {
 
		DoClearSquare(tile);
 
	}
 

	
 
	return CommandCost();
 
}
 

	
 
static void AddAcceptedCargo_Unmovable(TileIndex tile, CargoArray &acceptance, uint32 *town_acc)
 
{
 
	if (!IsCompanyHQ(tile)) return;
 
@@ -477,25 +477,25 @@ static void ChangeTileOwner_Unmovable(Ti
 
	} else if (IsStatueTile(tile)) {
 
		TownID town = GetStatueTownID(tile);
 
		Town *t = Town::Get(town);
 
		ClrBit(t->statues, old_owner);
 
		if (new_owner != INVALID_OWNER && !HasBit(t->statues, new_owner)) {
 
			/* Transfer ownership to the new company */
 
			SetBit(t->statues, new_owner);
 
			SetTileOwner(tile, new_owner);
 
		} else {
 
			DoClearSquare(tile);
 
		}
 

	
 
		InvalidateWindow(WC_TOWN_AUTHORITY, town);
 
		SetWindowDirty(WC_TOWN_AUTHORITY, town);
 
	} else {
 
		DoClearSquare(tile);
 
	}
 
}
 

	
 
static CommandCost TerraformTile_Unmovable(TileIndex tile, DoCommandFlag flags, uint z_new, Slope tileh_new)
 
{
 
	/* Owned land remains unsold */
 
	if (IsOwnedLand(tile) && CheckTileOwnership(tile)) return CommandCost();
 

	
 
	if (AutoslopeEnabled() && (IsStatue(tile) || IsCompanyHQ(tile))) {
 
		if (!IsSteepSlope(tileh_new) && (z_new + GetSlopeMaxZ(tileh_new) == GetTileMaxZ(tile))) return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
src/vehicle.cpp
Show inline comments
 
@@ -78,25 +78,25 @@ bool Vehicle::NeedsAutorenewing(const Co
 
	if (!c->settings.engine_renew) return false;
 
	if (this->age - this->max_age < (c->settings.engine_renew_months * 30)) return false;
 
	if (this->age == 0) return false; // rail cars don't age and lacks a max age
 

	
 
	return true;
 
}
 

	
 
void VehicleServiceInDepot(Vehicle *v)
 
{
 
	v->date_of_last_service = _date;
 
	v->breakdowns_since_last_service = 0;
 
	v->reliability = Engine::Get(v->engine_type)->reliability;
 
	InvalidateWindow(WC_VEHICLE_DETAILS, v->index); // ensure that last service date and reliability are updated
 
	SetWindowDirty(WC_VEHICLE_DETAILS, v->index); // ensure that last service date and reliability are updated
 
}
 

	
 
bool Vehicle::NeedsServicing() const
 
{
 
	if (this->vehstatus & (VS_STOPPED | VS_CRASHED)) return false;
 

	
 
	if (_settings_game.order.no_servicing_if_no_breakdowns && _settings_game.difficulty.vehicle_breakdowns == 0) {
 
		/* Vehicles set for autoreplacing needs to go to a depot even if breakdowns are turned off.
 
		 * Note: If servicing is enabled, we postpone replacement till next service. */
 
		return EngineHasReplacementForCompany(Company::Get(this->owner), this->engine_type, this->group_id);
 
	}
 

	
 
@@ -508,25 +508,25 @@ void Vehicle::PreDestructor()
 
	}
 

	
 
	if (this->Previous() == NULL) {
 
		InvalidateWindowData(WC_VEHICLE_DEPOT, this->tile);
 
	}
 

	
 
	if (this->IsPrimaryVehicle()) {
 
		DeleteWindowById(WC_VEHICLE_VIEW, this->index);
 
		DeleteWindowById(WC_VEHICLE_ORDERS, this->index);
 
		DeleteWindowById(WC_VEHICLE_REFIT, this->index);
 
		DeleteWindowById(WC_VEHICLE_DETAILS, this->index);
 
		DeleteWindowById(WC_VEHICLE_TIMETABLE, this->index);
 
		InvalidateWindow(WC_COMPANY, this->owner);
 
		SetWindowDirty(WC_COMPANY, this->owner);
 
	}
 
	InvalidateWindowClassesData(GetWindowClassForVehicleType(this->type), 0);
 

	
 
	this->cargo.Truncate(0);
 
	DeleteVehicleOrders(this);
 
	DeleteDepotHighlightOfVehicle(this);
 

	
 
	extern void StopGlobalFollowVehicle(const Vehicle *v);
 
	StopGlobalFollowVehicle(this);
 

	
 
	ReleaseDisastersTargetingVehicle(this->index);
 
}
 
@@ -815,45 +815,45 @@ Vehicle *CheckClickOnVehicle(const ViewP
 
				found = v;
 
				best_dist = dist;
 
			}
 
		}
 
	}
 

	
 
	return found;
 
}
 

	
 
void DecreaseVehicleValue(Vehicle *v)
 
{
 
	v->value -= v->value >> 8;
 
	InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 
	SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
 
}
 

	
 
static const byte _breakdown_chance[64] = {
 
	  3,   3,   3,   3,   3,   3,   3,   3,
 
	  4,   4,   5,   5,   6,   6,   7,   7,
 
	  8,   8,   9,   9,  10,  10,  11,  11,
 
	 12,  13,  13,  13,  13,  14,  15,  16,
 
	 17,  19,  21,  25,  28,  31,  34,  37,
 
	 40,  44,  48,  52,  56,  60,  64,  68,
 
	 72,  80,  90, 100, 110, 120, 130, 140,
 
	150, 170, 190, 210, 230, 250, 250, 250,
 
};
 

	
 
void CheckVehicleBreakdown(Vehicle *v)
 
{
 
	int rel, rel_old;
 

	
 
	/* decrease reliability */
 
	v->reliability = rel = max((rel_old = v->reliability) - v->reliability_spd_dec, 0);
 
	if ((rel_old >> 8) != (rel >> 8)) InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 
	if ((rel_old >> 8) != (rel >> 8)) SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
 

	
 
	if (v->breakdown_ctr != 0 || (v->vehstatus & VS_STOPPED) ||
 
			_settings_game.difficulty.vehicle_breakdowns < 1 ||
 
			v->cur_speed < 5 || _game_mode == GM_MENU) {
 
		return;
 
	}
 

	
 
	uint32 r = Random();
 

	
 
	/* increase chance of failure */
 
	int chance = v->breakdown_chance + 1;
 
	if (Chance16I(1, 25, r)) chance += 25;
 
@@ -875,25 +875,25 @@ void CheckVehicleBreakdown(Vehicle *v)
 
}
 

	
 
void AgeVehicle(Vehicle *v)
 
{
 
	if (v->age < 65535) v->age++;
 

	
 
	int age = v->age - v->max_age;
 
	if (age == DAYS_IN_LEAP_YEAR * 0 || age == DAYS_IN_LEAP_YEAR * 1 ||
 
			age == DAYS_IN_LEAP_YEAR * 2 || age == DAYS_IN_LEAP_YEAR * 3 || age == DAYS_IN_LEAP_YEAR * 4) {
 
		v->reliability_spd_dec <<= 1;
 
	}
 

	
 
	InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 
	SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
 

	
 
	/* Don't warn about non-primary or not ours vehicles or vehicles that are crashed */
 
	if (v->Previous() != NULL || v->owner != _local_company || (v->vehstatus & VS_CRASHED) != 0) return;
 

	
 
	/* Don't warn if a renew is active */
 
	if (Company::Get(v->owner)->settings.engine_renew && Engine::Get(v->engine_type)->company_avail != 0) return;
 

	
 
	StringID str;
 
	if (age == -DAYS_IN_LEAP_YEAR) {
 
		str = STR_NEWS_VEHICLE_IS_GETTING_OLD;
 
	} else if (age == 0) {
 
		str = STR_NEWS_VEHICLE_IS_GETTING_VERY_OLD;
 
@@ -951,69 +951,69 @@ uint8 CalcPercentVehicleFilled(const Veh
 
	/* Return the percentage */
 
	return (count * 100) / max;
 
}
 

	
 
void VehicleEnterDepot(Vehicle *v)
 
{
 
	/* Always work with the front of the vehicle */
 
	assert(v == v->First());
 

	
 
	switch (v->type) {
 
		case VEH_TRAIN: {
 
			Train *t = Train::From(v);
 
			InvalidateWindowClasses(WC_TRAINS_LIST);
 
			SetWindowClassesDirty(WC_TRAINS_LIST);
 
			/* Clear path reservation */
 
			SetDepotReservation(t->tile, false);
 
			if (_settings_client.gui.show_track_reservation) MarkTileDirtyByTile(t->tile);
 

	
 
			UpdateSignalsOnSegment(t->tile, INVALID_DIAGDIR, t->owner);
 
			t->load_unload_time_rem = 0;
 
			ClrBit(t->flags, VRF_TOGGLE_REVERSE);
 
			TrainConsistChanged(t, true);
 
			break;
 
		}
 

	
 
		case VEH_ROAD:
 
			InvalidateWindowClasses(WC_ROADVEH_LIST);
 
			SetWindowClassesDirty(WC_ROADVEH_LIST);
 
			break;
 

	
 
		case VEH_SHIP:
 
			InvalidateWindowClasses(WC_SHIPS_LIST);
 
			SetWindowClassesDirty(WC_SHIPS_LIST);
 
			Ship::From(v)->state = TRACK_BIT_DEPOT;
 
			RecalcShipStuff(v);
 
			break;
 

	
 
		case VEH_AIRCRAFT:
 
			InvalidateWindowClasses(WC_AIRCRAFT_LIST);
 
			SetWindowClassesDirty(WC_AIRCRAFT_LIST);
 
			HandleAircraftEnterHangar(Aircraft::From(v));
 
			break;
 
		default: NOT_REACHED();
 
	}
 

	
 
	if (v->type != VEH_TRAIN) {
 
		/* Trains update the vehicle list when the first unit enters the depot and calls VehicleEnterDepot() when the last unit enters.
 
		 * We only increase the number of vehicles when the first one enters, so we will not need to search for more vehicles in the depot */
 
		InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
 
	}
 
	InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
 
	SetWindowDirty(WC_VEHICLE_DEPOT, v->tile);
 

	
 
	v->vehstatus |= VS_HIDDEN;
 
	v->cur_speed = 0;
 

	
 
	VehicleServiceInDepot(v);
 

	
 
	TriggerVehicle(v, VEHICLE_TRIGGER_DEPOT);
 

	
 
	if (v->current_order.IsType(OT_GOTO_DEPOT)) {
 
		InvalidateWindow(WC_VEHICLE_VIEW, v->index);
 
		SetWindowDirty(WC_VEHICLE_VIEW, v->index);
 

	
 
		const Order *real_order = v->GetOrder(v->cur_order_index);
 
		Order t = v->current_order;
 
		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;
 
@@ -1426,28 +1426,28 @@ void Vehicle::BeginLoading()
 
		 * whether the train is lost or not; not marking a train lost
 
		 * that arrives at random stations is bad. */
 
		this->current_order.SetNonStopType(ONSF_NO_STOP_AT_ANY_STATION);
 

	
 
	} else {
 
		current_order.MakeLoading(false);
 
	}
 

	
 
	Station::Get(this->last_station_visited)->loading_vehicles.push_back(this);
 

	
 
	PrepareUnload(this);
 

	
 
	InvalidateWindow(GetWindowClassForVehicleType(this->type), this->owner);
 
	InvalidateWindowWidget(WC_VEHICLE_VIEW, this->index, VVW_WIDGET_START_STOP_VEH);
 
	InvalidateWindow(WC_VEHICLE_DETAILS, this->index);
 
	InvalidateWindow(WC_STATION_VIEW, this->last_station_visited);
 
	SetWindowDirty(GetWindowClassForVehicleType(this->type), this->owner);
 
	SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, VVW_WIDGET_START_STOP_VEH);
 
	SetWindowDirty(WC_VEHICLE_DETAILS, this->index);
 
	SetWindowDirty(WC_STATION_VIEW, this->last_station_visited);
 

	
 
	Station::Get(this->last_station_visited)->MarkTilesDirty(true);
 
	this->cur_speed = 0;
 
	this->MarkDirty();
 
}
 

	
 
void Vehicle::LeaveStation()
 
{
 
	assert(current_order.IsType(OT_LOADING));
 

	
 
	delete this->cargo_payment;
 

	
 
@@ -1508,54 +1508,54 @@ CommandCost Vehicle::SendToDepot(DoComma
 
	if (this->vehstatus & VS_CRASHED) return CMD_ERROR;
 
	if (this->IsStoppedInDepot()) return CMD_ERROR;
 

	
 
	if (this->current_order.IsType(OT_GOTO_DEPOT)) {
 
		bool halt_in_depot = this->current_order.GetDepotActionType() & ODATFB_HALT;
 
		if (!!(command & DEPOT_SERVICE) == halt_in_depot) {
 
			/* We called with a different DEPOT_SERVICE setting.
 
			 * Now we change the setting to apply the new one and let the vehicle head for the same depot.
 
			 * Note: the if is (true for requesting service == true for ordered to stop in depot)          */
 
			if (flags & DC_EXEC) {
 
				this->current_order.SetDepotOrderType(ODTF_MANUAL);
 
				this->current_order.SetDepotActionType(halt_in_depot ? ODATF_SERVICE_ONLY : ODATFB_HALT);
 
				InvalidateWindowWidget(WC_VEHICLE_VIEW, this->index, VVW_WIDGET_START_STOP_VEH);
 
				SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, VVW_WIDGET_START_STOP_VEH);
 
			}
 
			return CommandCost();
 
		}
 

	
 
		if (command & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders
 
		if (flags & DC_EXEC) {
 
			/* If the orders to 'goto depot' are in the orders list (forced servicing),
 
			 * then skip to the next order; effectively cancelling this forced service */
 
			if (this->current_order.GetDepotOrderType() & ODTFB_PART_OF_ORDERS) this->IncrementOrderIndex();
 

	
 
			this->current_order.MakeDummy();
 
			InvalidateWindowWidget(WC_VEHICLE_VIEW, this->index, VVW_WIDGET_START_STOP_VEH);
 
			SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, VVW_WIDGET_START_STOP_VEH);
 
		}
 
		return CommandCost();
 
	}
 

	
 
	TileIndex location;
 
	DestinationID destination;
 
	bool reverse;
 
	static const StringID no_depot[] = {STR_ERROR_UNABLE_TO_FIND_ROUTE_TO, STR_ERROR_UNABLE_TO_FIND_LOCAL_DEPOT, STR_ERROR_UNABLE_TO_FIND_LOCAL_DEPOT, STR_ERROR_CAN_T_SEND_AIRCRAFT_TO_HANGAR};
 
	if (!this->FindClosestDepot(&location, &destination, &reverse)) return_cmd_error(no_depot[this->type]);
 

	
 
	if (flags & DC_EXEC) {
 
		if (this->current_order.IsType(OT_LOADING)) this->LeaveStation();
 

	
 
		this->dest_tile = location;
 
		this->current_order.MakeGoToDepot(destination, ODTF_MANUAL);
 
		if (!(command & DEPOT_SERVICE)) this->current_order.SetDepotActionType(ODATFB_HALT);
 
		InvalidateWindowWidget(WC_VEHICLE_VIEW, this->index, VVW_WIDGET_START_STOP_VEH);
 
		SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, VVW_WIDGET_START_STOP_VEH);
 

	
 
		/* If there is no depot in front, reverse automatically (trains only) */
 
		if (this->type == VEH_TRAIN && reverse) DoCommand(this->tile, this->index, 0, DC_EXEC, CMD_REVERSE_TRAIN_DIRECTION);
 

	
 
		if (this->type == VEH_AIRCRAFT) {
 
			Aircraft *a = Aircraft::From(this);
 
			if (a->state == FLYING && a->targetairport != destination) {
 
				/* The aircraft is now heading for a different hangar than the next in the orders */
 
				extern void AircraftNextAirportPos_and_Order(Aircraft *a);
 
				AircraftNextAirportPos_and_Order(a);
 
			}
 
		}
 
@@ -1636,26 +1636,26 @@ void Vehicle::RemoveFromShared()
 

	
 
	this->next_shared     = NULL;
 
	this->previous_shared = NULL;
 
}
 

	
 
void StopAllVehicles()
 
{
 
	Vehicle *v;
 
	FOR_ALL_VEHICLES(v) {
 
		/* Code ripped from CmdStartStopTrain. Can't call it, because of
 
		 * ownership problems, so we'll duplicate some code, for now */
 
		v->vehstatus |= VS_STOPPED;
 
		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
 
		SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
		SetWindowDirty(WC_VEHICLE_DEPOT, v->tile);
 
	}
 
}
 

	
 
void VehiclesYearlyLoop()
 
{
 
	Vehicle *v;
 
	FOR_ALL_VEHICLES(v) {
 
		if (v->IsPrimaryVehicle()) {
 
			/* show warning if vehicle is not generating enough income last 2 years (corresponds to a red icon in the vehicle list) */
 
			Money profit = v->GetDisplayProfitThisYear();
 
			if (v->age >= 730 && profit < 0) {
 
				if (_settings_client.gui.vehicle_income_warn && v->owner == _local_company) {
 
@@ -1663,25 +1663,25 @@ void VehiclesYearlyLoop()
 
					SetDParam(1, profit);
 
					AddVehicleNewsItem(
 
						STR_NEWS_VEHICLE_IS_UNPROFITABLE,
 
						NS_ADVICE,
 
						v->index
 
					);
 
				}
 
				AI::NewEvent(v->owner, new AIEventVehicleUnprofitable(v->index));
 
			}
 

	
 
			v->profit_last_year = v->profit_this_year;
 
			v->profit_this_year = 0;
 
			InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 
			SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
 
		}
 
	}
 
}
 

	
 

	
 
/**
 
 * Can this station be used by the given engine type?
 
 * @param engine_type the type of vehicles to test
 
 * @param st the station to test for
 
 * @return true if and only if the vehicle of the type can use this station.
 
 * @note For road vehicles the Vehicle is needed to determine whether it can
 
 *       use the station. This function will return true for road vehicles
src/vehicle_cmd.cpp
Show inline comments
 
@@ -97,27 +97,27 @@ CommandCost CmdStartStopVehicle(TileInde
 
	 * return 0xFF if it can. */
 
	uint16 callback = GetVehicleCallback(CBID_VEHICLE_START_STOP_CHECK, 0, 0, v->engine_type, v);
 
	if (callback != CALLBACK_FAILED && GB(callback, 0, 8) != 0xFF && HasBit(p2, 0)) {
 
		StringID error = GetGRFStringID(GetEngineGRFID(v->engine_type), 0xD000 + callback);
 
		return_cmd_error(error);
 
	}
 

	
 
	if (flags & DC_EXEC) {
 
		if (v->IsStoppedInDepot() && (flags & DC_AUTOREPLACE) == 0) DeleteVehicleNews(p1, STR_NEWS_TRAIN_IS_WAITING + v->type);
 

	
 
		v->vehstatus ^= VS_STOPPED;
 
		if (v->type != VEH_TRAIN) v->cur_speed = 0; // trains can stop 'slowly'
 
		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
 
		InvalidateWindowClasses(GetWindowClassForVehicleType(v->type));
 
		SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
		SetWindowDirty(WC_VEHICLE_DEPOT, v->tile);
 
		SetWindowClassesDirty(GetWindowClassForVehicleType(v->type));
 
	}
 
	return CommandCost();
 
}
 

	
 
/** Starts or stops a lot of vehicles
 
 * @param tile Tile of the depot where the vehicles are started/stopped (only used for depots)
 
 * @param flags type of operation
 
 * @param p1 Station/Order/Depot ID (only used for vehicle list windows)
 
 * @param p2 bitmask
 
 *   - bit 0-4 Vehicle type
 
 *   - bit 5 false = start vehicles, true = stop vehicles
 
 *   - bit 6 if set, then it's a vehicle list window, not a depot and Tile is ignored in this case
 
@@ -558,17 +558,17 @@ CommandCost CmdRenameVehicle(TileIndex t
 
 * @param p2 new service interval
 
 */
 
CommandCost CmdChangeServiceInt(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
 
{
 
	Vehicle *v = Vehicle::GetIfValid(p1);
 
	if (v == NULL || !CheckOwnership(v->owner)) return CMD_ERROR;
 

	
 
	uint16 serv_int = GetServiceIntervalClamped(p2, v->owner); // Double check the service interval from the user-input
 
	if (serv_int != p2) return CMD_ERROR;
 

	
 
	if (flags & DC_EXEC) {
 
		v->service_interval = serv_int;
 
		InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 
		SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
 
	}
 

	
 
	return CommandCost();
 
}
src/viewport.cpp
Show inline comments
 
@@ -453,28 +453,28 @@ Point GetTileZoomCenterWindow(bool in, W
 
	return GetTileFromScreenXY(_cursor.pos.x, _cursor.pos.y, x + vp->left, y + vp->top);
 
}
 

	
 
/** Update the status of the zoom-buttons according to the zoom-level
 
 * of the viewport. This will update their status and invalidate accordingly
 
 * @param w Window pointer to the window that has the zoom buttons
 
 * @param vp pointer to the viewport whose zoom-level the buttons represent
 
 * @param widget_zoom_in widget index for window with zoom-in button
 
 * @param widget_zoom_out widget index for window with zoom-out button */
 
void HandleZoomMessage(Window *w, const ViewPort *vp, byte widget_zoom_in, byte widget_zoom_out)
 
{
 
	w->SetWidgetDisabledState(widget_zoom_in, vp->zoom == ZOOM_LVL_MIN);
 
	w->InvalidateWidget(widget_zoom_in);
 
	w->SetWidgetDirty(widget_zoom_in);
 

	
 
	w->SetWidgetDisabledState(widget_zoom_out, vp->zoom == ZOOM_LVL_MAX);
 
	w->InvalidateWidget(widget_zoom_out);
 
	w->SetWidgetDirty(widget_zoom_out);
 
}
 

	
 
/**
 
 * Draws a ground sprite at a specific world-coordinate.
 
 *
 
 * @param image the image to draw.
 
 * @param pal the provided palette.
 
 * @param x position x (world coordinates) of the sprite.
 
 * @param y position y (world coordinates) of the sprite.
 
 * @param z position z (world coordinates) of the sprite.
 
 * @param sub Only draw a part of the sprite.
 
 * @param extra_offs_x Pixel X offset for the sprite position.
src/water_cmd.cpp
Show inline comments
 
@@ -828,26 +828,26 @@ static void FloodVehicle(Vehicle *v)
 
				} break;
 

	
 
				case VEH_AIRCRAFT:
 
					pass += 2; // driver
 
					Aircraft::From(v)->crashed_counter = 9000; // max 10000, disappear pretty fast
 
					InvalidateWindowClassesData(WC_AIRCRAFT_LIST, 0);
 
					break;
 
			}
 
		} else {
 
			return;
 
		}
 

	
 
		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
 
		SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
		SetWindowDirty(WC_VEHICLE_DEPOT, v->tile);
 

	
 
		AI::NewEvent(v->owner, new AIEventVehicleCrashed(v->index, v->tile, AIEventVehicleCrashed::CRASH_FLOODED));
 
		SetDParam(0, pass);
 
		AddVehicleNewsItem(STR_NEWS_DISASTER_FLOOD_VEHICLE,
 
			NS_ACCIDENT,
 
			v->index);
 
		CreateEffectVehicleRel(v, 4, 4, 8, EV_EXPLOSION_LARGE);
 
		SndPlayVehicleFx(SND_12_EXPLOSION, v);
 
	}
 
}
 

	
 
/**
src/widget.cpp
Show inline comments
 
@@ -982,25 +982,25 @@ inline void NWidgetBase::StoreSizePositi
 

	
 
/**
 
 * @fn void Draw(const Window *w)
 
 * Draw the widgets of the tree.
 
 * The function calls #Window::DrawWidget for each widget with a non-negative index, after the widget itself is painted.
 
 * @param w Window that owns the tree.
 
 */
 

	
 
/**
 
 * Mark the widget as 'dirty' (in need of repaint).
 
 * @param w Window owning the widget.
 
 */
 
void NWidgetBase::Invalidate(const Window *w) const
 
void NWidgetBase::SetDirty(const Window *w) const
 
{
 
	int abs_left = w->left + this->pos_x;
 
	int abs_top = w->top + this->pos_y;
 
	SetDirtyBlocks(abs_left, abs_top, abs_left + this->current_x, abs_top + this->current_y);
 
}
 

	
 
/**
 
 * @fn NWidgetCore *NWidgetBase::GetWidgetFromPos(int x, int y)
 
 * Retrieve a widget by its position.
 
 * @param x Horizontal position relative to the left edge of the window.
 
 * @param y Vertical position relative to the top edge of the window.
 
 * @return Returns the deepest nested widget that covers the given position, or \c NULL if no widget can be found.
 
@@ -1645,25 +1645,25 @@ void NWidgetSpacer::FillNestedArray(NWid
 
}
 

	
 
void NWidgetSpacer::StoreWidgets(Widget *widgets, int length, bool left_moving, bool top_moving, bool rtl)
 
{
 
	/* Spacer widgets are never stored in the widget array. */
 
}
 

	
 
void NWidgetSpacer::Draw(const Window *w)
 
{
 
	/* Spacer widget is never visible. */
 
}
 

	
 
void NWidgetSpacer::Invalidate(const Window *w) const
 
void NWidgetSpacer::SetDirty(const Window *w) const
 
{
 
	/* Spacer widget never need repainting. */
 
}
 

	
 
NWidgetCore *NWidgetSpacer::GetWidgetFromPos(int x, int y)
 
{
 
	return NULL;
 
}
 

	
 
/**
 
 * Constructor parent nested widgets.
 
 * @param tp     Type of parent widget.
src/widget_type.h
Show inline comments
 
@@ -200,25 +200,25 @@ public:
 
	inline void SetPadding(uint8 top, uint8 right, uint8 bottom, uint8 left)
 
	{
 
		this->padding_top = top;
 
		this->padding_right = right;
 
		this->padding_bottom = bottom;
 
		this->padding_left = left;
 
	};
 

	
 
	inline uint GetHorizontalStepSize(SizingType sizing) const;
 
	inline uint GetVerticalStepSize(SizingType sizing) const;
 

	
 
	virtual void Draw(const Window *w) = 0;
 
	virtual void Invalidate(const Window *w) const;
 
	virtual void SetDirty(const Window *w) const;
 

	
 
	WidgetType type;      ///< Type of the widget / nested widget.
 
	bool fill_x;          ///< Allow horizontal filling from initial size.
 
	bool fill_y;          ///< Allow vertical filling from initial size.
 
	uint resize_x;        ///< Horizontal resize step (\c 0 means not resizable).
 
	uint resize_y;        ///< Vertical resize step (\c 0 means not resizable).
 
	/* Size of the widget in the smallest window possible.
 
	 * Computed by #SetupSmallestSize() followed by #AssignSizePosition().
 
	 */
 
	uint smallest_x;      ///< Smallest horizontal size of the widget in a filled window.
 
	uint smallest_y;      ///< Smallest vertical size of the widget in a filled window.
 
	/* Current widget size (that is, after resizing). */
 
@@ -449,25 +449,25 @@ public:
 

	
 
/** Spacer widget.
 
 * @ingroup NestedWidgets */
 
class NWidgetSpacer : public NWidgetResizeBase {
 
public:
 
	NWidgetSpacer(int length, int height);
 

	
 
	void SetupSmallestSize(Window *w, bool init_array);
 
	void StoreWidgets(Widget *widgets, int length, bool left_moving, bool top_moving, bool rtl);
 
	/* virtual */ void FillNestedArray(NWidgetCore **array, uint length);
 

	
 
	/* virtual */ void Draw(const Window *w);
 
	/* virtual */ void Invalidate(const Window *w) const;
 
	/* virtual */ void SetDirty(const Window *w) const;
 
	/* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y);
 
};
 

	
 
/** Nested widget with a child.
 
 * @ingroup NestedWidgets */
 
class NWidgetBackground : public NWidgetCore {
 
public:
 
	NWidgetBackground(WidgetType tp, Colours colour, int index, NWidgetPIPContainer *child = NULL);
 
	~NWidgetBackground();
 

	
 
	void Add(NWidgetBase *nwid);
 
	void SetPIP(uint8 pip_pre, uint8 pip_inter, uint8 pip_post);
src/widgets/dropdown.cpp
Show inline comments
 
@@ -95,25 +95,25 @@ struct DropdownWindow : Window {
 
	int scrolling;
 

	
 
	DropdownWindow(int x, int y, int width, int height, const Widget *widget) : Window(x, y, width, height, WC_DROPDOWN_MENU, widget)
 
	{
 
		this->FindWindowPlacementAndResize(width, height);
 
	}
 

	
 
	~DropdownWindow()
 
	{
 
		Window *w2 = FindWindowById(this->parent_wnd_class, this->parent_wnd_num);
 
		if (w2 != NULL) {
 
			w2->RaiseWidget(this->parent_button);
 
			w2->InvalidateWidget(this->parent_button);
 
			w2->SetWidgetDirty(this->parent_button);
 
		}
 

	
 
		DeleteDropDownList(this->list);
 
	}
 

	
 
	bool GetDropDownItem(int &value)
 
	{
 
		if (GetWidgetFromPos(this, _cursor.pos.x - this->left, _cursor.pos.y - this->top) < 0) return false;
 

	
 
		int y     = _cursor.pos.y - this->top - 2;
 
		int width = this->widget[0].right - 3;
 
		int pos   = this->vscroll.GetPosition();
 
@@ -243,25 +243,25 @@ struct DropdownWindow : Window {
 
			this->SetDirty();
 
		}
 
	}
 
};
 

	
 
void ShowDropDownList(Window *w, DropDownList *list, int selected, int button, uint width, bool auto_width, bool instant_close)
 
{
 
	static Widget *generated_dropdown_menu_widgets = NULL;
 

	
 
	DeleteWindowById(WC_DROPDOWN_MENU, 0);
 

	
 
	w->LowerWidget(button);
 
	w->InvalidateWidget(button);
 
	w->SetWidgetDirty(button);
 

	
 
	/* Our parent's button widget is used to determine where to place the drop
 
	 * down list window. */
 
	Rect wi_rect;
 
	Colours wi_colour;
 
	if (w->nested_array != NULL) {
 
		const NWidgetCore *nwi = w->nested_array[button];
 
		wi_rect.left   = nwi->pos_x;
 
		wi_rect.right  = nwi->pos_x + nwi->current_x - 1;
 
		wi_rect.top    = nwi->pos_y;
 
		wi_rect.bottom = nwi->pos_y + nwi->current_y - 1;
 
		wi_colour = nwi->colour;
src/window.cpp
Show inline comments
 
@@ -98,27 +98,27 @@ WindowDesc::~WindowDesc()
 
/**
 
 * Set the window that has the focus
 
 * @param w The window to set the focus on
 
 */
 
void SetFocusedWindow(Window *w)
 
{
 
	if (_focused_window == w) return;
 

	
 
	/* Invalidate focused widget */
 
	if (_focused_window != NULL) {
 
		if (_focused_window->focused_widget != NULL) {
 
			uint focused_widget_id = _focused_window->focused_widget - _focused_window->widget;
 
			_focused_window->InvalidateWidget(focused_widget_id);
 
			_focused_window->SetWidgetDirty(focused_widget_id);
 
		}
 
		if (_focused_window->nested_focus != NULL) _focused_window->nested_focus->Invalidate(_focused_window);
 
		if (_focused_window->nested_focus != NULL) _focused_window->nested_focus->SetDirty(_focused_window);
 
	}
 

	
 
	/* Remember which window was previously focused */
 
	Window *old_focused = _focused_window;
 
	_focused_window = w;
 

	
 
	/* So we can inform it that it lost focus */
 
	if (old_focused != NULL) old_focused->OnFocusLost();
 
	if (_focused_window != NULL) _focused_window->OnFocus();
 
}
 

	
 
/**
 
@@ -143,40 +143,40 @@ bool EditBoxInGlobalFocus()
 
 * Set focus within this window to the given widget. The function however doesn't change which window has focus.
 
 * @param widget_index Index of the widget in the window to set the focus to.
 
 * @return Focus has changed.
 
 */
 
bool Window::SetFocusedWidget(byte widget_index)
 
{
 
	if (this->widget != NULL) {
 
		/* Do nothing if widget_index is already focused, or if it wasn't a valid widget. */
 
		if (widget_index >= this->widget_count || this->widget + widget_index == this->focused_widget) return false;
 

	
 
		if (this->focused_widget != NULL) {
 
			/* Repaint the widget that lost focus. A focused edit box may else leave the caret on the screen. */
 
			this->InvalidateWidget(this->focused_widget - this->widget);
 
			this->SetWidgetDirty(this->focused_widget - this->widget);
 
		}
 
		this->focused_widget = &this->widget[widget_index];
 
		return true;
 
	}
 

	
 
	if (this->nested_array != NULL) {
 
		/* Do nothing if widget_index is already focused, or if it wasn't a valid widget. */
 
		if (widget_index >= this->nested_array_size) return false;
 

	
 
		assert(this->nested_array[widget_index] != NULL); // Setting focus to a non-existing widget is a bad idea.
 
		if (this->nested_focus != NULL) {
 
			if (this->nested_array[widget_index] == this->nested_focus) return false;
 

	
 
			/* Repaint the widget that lost focus. A focused edit box may else leave the caret on the screen. */
 
			this->nested_focus->Invalidate(this);
 
			this->nested_focus->SetDirty(this);
 
		}
 
		this->nested_focus = this->nested_array[widget_index];
 
		return true;
 
	}
 
	NOT_REACHED();
 
}
 

	
 
/**
 
 * Sets the enabled/disabled status of a list of widgets.
 
 * By default, widgets are enabled.
 
 * On certain conditions, they have to be disabled.
 
 * @param disab_stat status to use ie: disabled = true, enabled = false
 
@@ -237,65 +237,65 @@ void CDECL Window::SetWidgetsLoweredStat
 
}
 

	
 
/**
 
 * Raise the buttons of the window.
 
 * @param autoraise Raise only the push buttons of the window.
 
 */
 
void Window::RaiseButtons(bool autoraise)
 
{
 
	if (this->widget != NULL) {
 
		for (uint i = 0; i < this->widget_count; i++) {
 
			if ((!autoraise || (this->widget[i].type & WWB_PUSHBUTTON)) && this->IsWidgetLowered(i)) {
 
				this->RaiseWidget(i);
 
				this->InvalidateWidget(i);
 
				this->SetWidgetDirty(i);
 
			}
 
		}
 
	}
 
	if (this->nested_array != NULL) {
 
		for (uint i = 0; i < this->nested_array_size; i++) {
 
			if (this->nested_array[i] != NULL && (!autoraise || (this->nested_array[i]->type & WWB_PUSHBUTTON)) && this->IsWidgetLowered(i)) {
 
				this->RaiseWidget(i);
 
				this->InvalidateWidget(i);
 
				this->SetWidgetDirty(i);
 
			}
 
		}
 
	}
 
}
 

	
 
/**
 
 * Invalidate a widget, i.e. mark it as being changed and in need of redraw.
 
 * @param widget_index the widget to redraw.
 
 */
 
void Window::InvalidateWidget(byte widget_index) const
 
void Window::SetWidgetDirty(byte widget_index) const
 
{
 
	if (this->widget != NULL) {
 
		const Widget *wi = &this->widget[widget_index];
 

	
 
		/* Don't redraw the window if the widget is invisible or of no-type */
 
		if (wi->type == WWT_EMPTY || IsWidgetHidden(widget_index)) return;
 

	
 
		SetDirtyBlocks(this->left + wi->left, this->top + wi->top, this->left + wi->right + 1, this->top + wi->bottom + 1);
 
	}
 
	if (this->nested_array != NULL) this->nested_array[widget_index]->Invalidate(this);
 
	if (this->nested_array != NULL) this->nested_array[widget_index]->SetDirty(this);
 
}
 

	
 
/**
 
 * Do all things to make a button look clicked and mark it to be
 
 * unclicked in a few ticks.
 
 * @param widget the widget to "click"
 
 */
 
void Window::HandleButtonClick(byte widget)
 
{
 
	this->LowerWidget(widget);
 
	this->flags4 |= WF_TIMEOUT_BEGIN;
 
	this->InvalidateWidget(widget);
 
	this->SetWidgetDirty(widget);
 
}
 

	
 
/**
 
 * Return a widget of the requested type from the window.
 
 * @param widget_type the widget type to look for
 
 */
 
const Widget *Window::GetWidgetOfType(WidgetType widget_type) const
 
{
 
	for (uint i = 0; i < this->widget_count; i++) {
 
		if (this->widget[i].type == widget_type) return &this->widget[i];
 
	}
 
	return NULL;
 
@@ -400,31 +400,31 @@ static void DispatchLeftClickEvent(Windo
 

	
 
			if (widget_type == WWT_CAPTION) { // 'Title bar'
 
				StartWindowDrag(w);
 
				return;
 
			}
 
		}
 

	
 
		if ((w->desc_flags & WDF_RESIZABLE) && widget_type == WWT_RESIZEBOX) {
 
			/* When the resize widget is on the left size of the window
 
			 * we assume that that button is used to resize to the left. */
 
			int left_pos = (wi != NULL) ? wi->left : nw->pos_x;
 
			StartWindowSizing(w, left_pos < (w->width / 2));
 
			w->InvalidateWidget(widget_index);
 
			w->SetWidgetDirty(widget_index);
 
			return;
 
		}
 

	
 
		if ((w->desc_flags & WDF_STICKY_BUTTON) && widget_type == WWT_STICKYBOX) {
 
			w->flags4 ^= WF_STICKY;
 
			w->InvalidateWidget(widget_index);
 
			w->SetWidgetDirty(widget_index);
 
			return;
 
		}
 
	}
 

	
 
	Point pt = { x, y };
 

	
 
	if (double_click) {
 
		w->OnDoubleClick(pt, widget_index);
 
	} else {
 
		w->OnClick(pt, widget_index);
 
	}
 
}
 
@@ -2431,53 +2431,53 @@ void UpdateWindows()
 
		if (w->viewport != NULL) UpdateViewportPosition(w);
 
	}
 
	NetworkDrawChatMessage();
 
	/* Redraw mouse cursor in case it was hidden */
 
	DrawMouseCursor();
 
}
 

	
 
/**
 
 * Mark window as dirty (in need of repainting)
 
 * @param cls Window class
 
 * @param number Window number in that class
 
 */
 
void InvalidateWindow(WindowClass cls, WindowNumber number)
 
void SetWindowDirty(WindowClass cls, WindowNumber number)
 
{
 
	const Window *w;
 
	FOR_ALL_WINDOWS_FROM_BACK(w) {
 
		if (w->window_class == cls && w->window_number == number) w->SetDirty();
 
	}
 
}
 

	
 
/**
 
 * Mark a particular widget in a particular window as dirty (in need of repainting)
 
 * @param cls Window class
 
 * @param number Window number in that class
 
 * @param widget_index Index number of the widget that needs repainting
 
 */
 
void InvalidateWindowWidget(WindowClass cls, WindowNumber number, byte widget_index)
 
void SetWindowWidgetDirty(WindowClass cls, WindowNumber number, byte widget_index)
 
{
 
	const Window *w;
 
	FOR_ALL_WINDOWS_FROM_BACK(w) {
 
		if (w->window_class == cls && w->window_number == number) {
 
			w->InvalidateWidget(widget_index);
 
			w->SetWidgetDirty(widget_index);
 
		}
 
	}
 
}
 

	
 
/**
 
 * Mark all windows of a particular class as dirty (in need of repainting)
 
 * @param cls Window class
 
 */
 
void InvalidateWindowClasses(WindowClass cls)
 
void SetWindowClassesDirty(WindowClass cls)
 
{
 
	Window *w;
 
	FOR_ALL_WINDOWS_FROM_BACK(w) {
 
		if (w->window_class == cls) w->SetDirty();
 
	}
 
}
 

	
 
/**
 
 * Mark window data as invalid (in need of re-computing)
 
 * @param w Window with invalid data
 
 */
 
void InvalidateThisWindowData(Window *w, int data)
src/window_func.h
Show inline comments
 
@@ -30,20 +30,20 @@ void InputLoop();
 
void InvalidateThisWindowData(Window *w, int data = 0);
 
void InvalidateWindowData(WindowClass cls, WindowNumber number, int data = 0);
 
void InvalidateWindowClassesData(WindowClass cls, int data = 0);
 

	
 
void DeleteNonVitalWindows();
 
void DeleteAllNonVitalWindows();
 
void DeleteConstructionWindows();
 
void HideVitalWindows();
 
void ShowVitalWindows();
 

	
 
void ReInitAllWindows();
 

	
 
void InvalidateWindowWidget(WindowClass cls, WindowNumber number, byte widget_index);
 
void InvalidateWindow(WindowClass cls, WindowNumber number);
 
void InvalidateWindowClasses(WindowClass cls);
 
void SetWindowWidgetDirty(WindowClass cls, WindowNumber number, byte widget_index);
 
void SetWindowDirty(WindowClass cls, WindowNumber number);
 
void SetWindowClassesDirty(WindowClass cls);
 

	
 
void DeleteWindowById(WindowClass cls, WindowNumber number, bool force = true);
 
void DeleteWindowByClass(WindowClass cls);
 

	
 
#endif /* WINDOW_FUNC_H */
src/window_gui.h
Show inline comments
 
@@ -610,25 +610,25 @@ public:
 
		return this->widget[widget_index].right - this->widget[widget_index].left + 1;
 
	}
 

	
 
	bool SetFocusedWidget(byte widget_index);
 

	
 
	void HandleButtonClick(byte widget);
 
	const Widget *GetWidgetOfType(WidgetType widget_type) const;
 

	
 
	void RaiseButtons(bool autoraise = false);
 
	void CDECL SetWidgetsDisabledState(bool disab_stat, int widgets, ...);
 
	void CDECL SetWidgetsHiddenState(bool hidden_stat, int widgets, ...);
 
	void CDECL SetWidgetsLoweredState(bool lowered_stat, int widgets, ...);
 
	void InvalidateWidget(byte widget_index) const;
 
	void SetWidgetDirty(byte widget_index) const;
 

	
 
	void DrawWidgets() const;
 
	void DrawViewport() const;
 
	void DrawSortButtonState(int widget, SortButtonState state) const;
 

	
 
	void DeleteChildWindows() const;
 

	
 
	void SetDirty() const;
 
	void ReInit();
 

	
 
	/*** Event handling ***/
 

	
0 comments (0 inline, 0 general)