Changeset - r25226:099b6b8941ab
[Not reviewed]
master
0 6 0
peter1138 - 5 years ago 2019-03-30 07:13:08
peter1138@openttd.org
Feature: Per-group wagon removal flag.
6 files changed with 43 insertions and 6 deletions:
0 comments (0 inline, 0 general)
src/autoreplace_cmd.cpp
Show inline comments
 
@@ -732,24 +732,27 @@ CommandCost CmdAutoreplaceVehicle(TileIn
 
	if (v->type == VEH_TRAIN) {
 
		Train *t = Train::From(v);
 
		if (t->IsArticulatedPart() || t->IsRearDualheaded()) return CMD_ERROR;
 
		free_wagon = !t->IsFrontEngine();
 
		if (free_wagon && t->First()->IsFrontEngine()) return CMD_ERROR;
 
	} else {
 
		if (!v->IsPrimaryVehicle()) return CMD_ERROR;
 
	}
 

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

	
 
	const Group *g = Group::GetIfValid(v->group_id);
 
	if (g != nullptr) wagon_removal = HasBit(g->flags, GroupFlags::GF_REPLACE_WAGON_REMOVAL);
 

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

	
 
	CommandCost cost = CommandCost(EXPENSES_NEW_VEHICLES, 0);
src/autoreplace_gui.cpp
Show inline comments
 
@@ -366,26 +366,33 @@ public:
 
					default:
 
						SetDParam(1, STR_GROUP_NAME);
 
						SetDParam(2, sel_group);
 
						break;
 
				}
 
				break;
 

	
 
			case WID_RV_SORT_DROPDOWN:
 
				SetDParam(0, _engine_sort_listing[this->window_number][this->sort_criteria]);
 
				break;
 

	
 
			case WID_RV_TRAIN_WAGONREMOVE_TOGGLE: {
 
				const Company *c = Company::Get(_local_company);
 
				SetDParam(0, c->settings.renew_keep_length ? STR_CONFIG_SETTING_ON : STR_CONFIG_SETTING_OFF);
 
				bool remove_wagon;
 
				const Group *g = Group::GetIfValid(this->sel_group);
 
				if (g != nullptr) {
 
					remove_wagon = HasBit(g->flags, GroupFlags::GF_REPLACE_WAGON_REMOVAL);
 
				} else {
 
					const Company *c = Company::Get(_local_company);
 
					remove_wagon = c->settings.renew_keep_length;
 
				}
 
				SetDParam(0, remove_wagon ? STR_CONFIG_SETTING_ON : STR_CONFIG_SETTING_OFF);
 
				break;
 
			}
 

	
 
			case WID_RV_TRAIN_ENGINEWAGON_DROPDOWN:
 
				SetDParam(0, this->replace_engines ? STR_REPLACE_ENGINES : STR_REPLACE_WAGONS);
 
				break;
 
		}
 
	}
 

	
 
	void DrawWidget(const Rect &r, int widget) const override
 
	{
 
		switch (widget) {
 
@@ -519,27 +526,34 @@ public:
 
			case WID_RV_RAIL_ROAD_TYPE_DROPDOWN: // Rail/roadtype selection dropdown menu
 
				switch (this->window_number) {
 
					case VEH_TRAIN:
 
						ShowDropDownList(this, GetRailTypeDropDownList(true, true), sel_railtype, WID_RV_RAIL_ROAD_TYPE_DROPDOWN);
 
						break;
 

	
 
					case VEH_ROAD:
 
						ShowDropDownList(this, GetRoadTypeDropDownList(RTTB_ROAD | RTTB_TRAM, true, true), sel_roadtype, WID_RV_RAIL_ROAD_TYPE_DROPDOWN);
 
						break;
 
				}
 
				break;
 

	
 
			case WID_RV_TRAIN_WAGONREMOVE_TOGGLE: // toggle renew_keep_length
 
				DoCommandP(0, GetCompanySettingIndex("company.renew_keep_length"), Company::Get(_local_company)->settings.renew_keep_length ? 0 : 1, CMD_CHANGE_COMPANY_SETTING);
 
			case WID_RV_TRAIN_WAGONREMOVE_TOGGLE: {
 
				const Group *g = Group::GetIfValid(this->sel_group);
 
				if (g != nullptr) {
 
					DoCommandP(0, this->sel_group | (GroupFlags::GF_REPLACE_WAGON_REMOVAL << 16), (HasBit(g->flags, GroupFlags::GF_REPLACE_WAGON_REMOVAL) ? 0 : 1) | (_ctrl_pressed << 1), CMD_SET_GROUP_FLAG);
 
				} else {
 
					// toggle renew_keep_length
 
					DoCommandP(0, GetCompanySettingIndex("company.renew_keep_length"), Company::Get(_local_company)->settings.renew_keep_length ? 0 : 1, CMD_CHANGE_COMPANY_SETTING);
 
				}
 
				break;
 
			}
 

	
 
			case WID_RV_START_REPLACE: { // Start replacing
 
				if (this->GetWidget<NWidgetLeaf>(widget)->ButtonHit(pt)) {
 
					this->HandleButtonClick(WID_RV_START_REPLACE);
 
					ReplaceClick_StartReplace(false);
 
				} else {
 
					bool replacment_when_old = EngineHasReplacementWhenOldForCompany(Company::Get(_local_company), this->sel_engine[0], this->sel_group);
 
					ShowDropDownMenu(this, _start_replace_dropdown, replacment_when_old ? 1 : 0, WID_RV_START_REPLACE, !this->replace_engines ? 1 << 1 : 0, 0);
 
				}
 
				break;
 
			}
 

	
src/group.h
Show inline comments
 
@@ -54,25 +54,26 @@ struct GroupStatistics {
 
	static GroupStatistics &GetAllGroup(const Vehicle *v);
 

	
 
	static void CountVehicle(const Vehicle *v, int delta);
 
	static void CountEngine(const Vehicle *v, int delta);
 
	static void VehicleReachedProfitAge(const Vehicle *v);
 

	
 
	static void UpdateProfits();
 
	static void UpdateAfterLoad();
 
	static void UpdateAutoreplace(CompanyID company);
 
};
 

	
 
enum GroupFlags : uint8 {
 
	GF_REPLACE_PROTECTION, ///< If set to true, the global autoreplace has no effect on the group
 
	GF_REPLACE_PROTECTION,    ///< If set to true, the global autoreplace has no effect on the group
 
	GF_REPLACE_WAGON_REMOVAL, ///< If set, autoreplace will perform wagon removal on vehicles in this group.
 
	GF_END,
 
};
 

	
 
/** Group data. */
 
struct Group : GroupPool::PoolItem<&_group_pool> {
 
	std::string name;           ///< Group Name
 
	Owner owner;                ///< Group Owner
 
	VehicleType vehicle_type;   ///< Vehicle type of the group
 

	
 
	uint8 flags;                ///< Group flags
 
	Livery livery;              ///< Custom colour scheme for vehicles in this group
 
	GroupStatistics statistics; ///< NOSAVE: Statistics and caches on the vehicles in the group.
src/group_cmd.cpp
Show inline comments
 
@@ -306,36 +306,37 @@ CommandCost CmdCreateGroup(TileIndex til
 
	if (!IsCompanyBuildableVehicleType(vt)) return CMD_ERROR;
 

	
 
	if (!Group::CanAllocateItem()) return CMD_ERROR;
 

	
 
	const Group *pg = Group::GetIfValid(GB(p2, 0, 16));
 
	if (pg != nullptr) {
 
		if (pg->owner != _current_company) return CMD_ERROR;
 
		if (pg->vehicle_type != vt) return CMD_ERROR;
 
	}
 

	
 
	if (flags & DC_EXEC) {
 
		Group *g = new Group(_current_company);
 
		ClrBit(g->flags, GroupFlags::GF_REPLACE_PROTECTION);
 
		g->vehicle_type = vt;
 
		g->parent = INVALID_GROUP;
 

	
 
		if (pg == nullptr) {
 
			const Company *c = Company::Get(_current_company);
 
			g->livery.colour1 = c->livery[LS_DEFAULT].colour1;
 
			g->livery.colour2 = c->livery[LS_DEFAULT].colour2;
 
			if (c->settings.renew_keep_length) SetBit(g->flags, GroupFlags::GF_REPLACE_WAGON_REMOVAL);
 
		} else {
 
			g->parent = pg->index;
 
			g->livery.colour1 = pg->livery.colour1;
 
			g->livery.colour2 = pg->livery.colour2;
 
			g->flags = pg->flags;
 
		}
 

	
 
		_new_group_id = g->index;
 

	
 
		InvalidateWindowData(GetWindowClassForVehicleType(vt), VehicleListIdentifier(VL_GROUP_LIST, vt, _current_company).Pack());
 
		InvalidateWindowData(WC_COMPANY_COLOUR, g->owner, g->vehicle_type);
 
	}
 

	
 
	return CommandCost();
 
}
 

	
 

	
src/saveload/afterload.cpp
Show inline comments
 
@@ -3118,24 +3118,41 @@ bool AfterLoadGame()
 
			}
 
		}
 
	}
 

	
 
	/* Make sure all industries exclusive supplier/consumer set correctly. */
 
	if (IsSavegameVersionBefore(SLV_GS_INDUSTRY_CONTROL)) {
 
		for (Industry *i : Industry::Iterate()) {
 
			i->exclusive_supplier = INVALID_OWNER;
 
			i->exclusive_consumer = INVALID_OWNER;
 
		}
 
	}
 

	
 
	if (IsSavegameVersionBefore(SLV_GROUP_REPLACE_WAGON_REMOVAL)) {
 
		/* Propagate wagon removal flag for compatibility */
 
		/* Temporary bitmask of company wagon removal setting */
 
		uint16 wagon_removal = 0;
 
		for (const Company *c : Company::Iterate()) {
 
			if (c->settings.renew_keep_length) SetBit(wagon_removal, c->index);
 
		}
 
		for (Group *g : Group::Iterate()) {
 
			if (g->flags != 0) {
 
				/* Convert old replace_protection value to flag. */
 
				g->flags = 0;
 
				SetBit(g->flags, GroupFlags::GF_REPLACE_PROTECTION);
 
			}
 
			if (HasBit(wagon_removal, g->owner)) SetBit(g->flags, GroupFlags::GF_REPLACE_WAGON_REMOVAL);
 
		}
 
	}
 

	
 
	/* Compute station catchment areas. This is needed here in case UpdateStationAcceptance is called below. */
 
	Station::RecomputeCatchmentForAll();
 

	
 
	/* Station acceptance is some kind of cache */
 
	if (IsSavegameVersionBefore(SLV_127)) {
 
		for (Station *st : Station::Iterate()) UpdateStationAcceptance(st, false);
 
	}
 

	
 
	/* Road stops is 'only' updating some caches */
 
	AfterLoadRoadStops();
 
	AfterLoadLabelMaps();
 
	AfterLoadCompanyStats();
src/saveload/saveload.h
Show inline comments
 
@@ -316,24 +316,25 @@ enum SaveLoadVersion : uint16 {
 
	 * indicate he is loading a savegame from a patchpack.
 
	 * For future patchpack creators: please follow a system like JGRPP, where
 
	 * the version is masked with 0x8000, and the true version is stored in
 
	 * its own chunk with feature toggles.
 
	 */
 
	SLV_START_PATCHPACKS,                   ///< 220  First known patchpack to use a version just above ours.
 
	SLV_END_PATCHPACKS = 286,               ///< 286  Last known patchpack to use a version just above ours.
 

	
 
	SLV_GS_INDUSTRY_CONTROL,                ///< 287  PR#7912 and PR#8115 GS industry control.
 
	SLV_VEH_MOTION_COUNTER,                 ///< 288  PR#8591 Desync safe motion counter
 
	SLV_INDUSTRY_TEXT,                      ///< 289  PR#8576 v1.11.0-RC1  Additional GS text for industries.
 
	SLV_MAPGEN_SETTINGS_REVAMP,             ///< 290  PR#8891 v1.11  Revamp of some mapgen settings (snow coverage, desert coverage, heightmap height, custom terrain type).
 
	SLV_GROUP_REPLACE_WAGON_REMOVAL,        ///< 291  PR#7441 Per-group wagon removal flag.
 

	
 
	SL_MAX_VERSION,                         ///< Highest possible saveload version
 
};
 

	
 
/** Save or load result codes. */
 
enum SaveOrLoadResult {
 
	SL_OK     = 0, ///< completed successfully
 
	SL_ERROR  = 1, ///< error that was caught before internal structures were modified
 
	SL_REINIT = 2, ///< error that was caught in the middle of updating game state, need to clear it. (can only happen during load)
 
};
 

	
 
/** Deals with the type of the savegame, independent of extension */
0 comments (0 inline, 0 general)