void InitializeSoundPool()
{
	_sounds.Clear();

	/* Copy original sound data to the pool */
	SndCopyToPool();
}
static void Load_RAIL()
{
	_railtype_list.Clear();

	LabelObject lo;
	int index;

	while ((index = SlIterateArray()) != -1) {
		SlObject(&lo, _label_object_desc);
		*_railtype_list.Append() = (RailTypeLabel)lo.label;
	}
}
Example #3
0
static void Load_WAYP()
{
	/* Precaution for when loading failed and it didn't get cleared */
	_old_waypoints.Clear();

	int index;

	while ((index = SlIterateArray()) != -1) {
		OldWaypoint *wp = _old_waypoints.Append();
		memset(wp, 0, sizeof(*wp));

		wp->index = index;
		SlObject(wp, _old_waypoint_desc);
	}
}
void AfterLoadLabelMaps()
{
	if (NeedRailTypeConversion()) {
		SmallVector<RailType, RAILTYPE_END> railtype_conversion_map;

		for (uint i = 0; i < _railtype_list.Length(); i++) {
			RailType r = GetRailTypeByLabel(_railtype_list[i]);
			if (r == INVALID_RAILTYPE) r = RAILTYPE_BEGIN;

			*railtype_conversion_map.Append() = r;
		}

		for (TileIndex t = 0; t < MapSize(); t++) {
			switch (GetTileType(t)) {
				case MP_RAILWAY:
					SetRailType(t, railtype_conversion_map[GetRailType(t)]);
					break;

				case MP_ROAD:
					if (IsLevelCrossing(t)) {
						SetRailType(t, railtype_conversion_map[GetRailType(t)]);
					}
					break;

				case MP_STATION:
					if (HasStationRail(t)) {
						SetRailType(t, railtype_conversion_map[GetRailType(t)]);
					}
					break;

				case MP_TUNNELBRIDGE:
					if (GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL) {
						SetRailType(t, railtype_conversion_map[GetRailType(t)]);
					}
					break;

				default:
					break;
			}
		}
	}

	_railtype_list.Clear();
}
/**
 * Refits a vehicle (chain).
 * This is the vehicle-type independent part of the CmdRefitXXX functions.
 * @param v            The vehicle to refit.
 * @param only_this    Whether to only refit this vehicle, or to check the rest of them.
 * @param num_vehicles Number of vehicles to refit (not counting articulated parts). Zero means the whole chain.
 * @param new_cid      Cargotype to refit to
 * @param new_subtype  Cargo subtype to refit to. 0xFF means to try keeping the same subtype according to GetBestFittingSubType().
 * @param flags        Command flags
 * @param auto_refit   Refitting is done as automatic refitting outside a depot.
 * @return Refit cost.
 */
static CommandCost RefitVehicle(Vehicle *v, bool only_this, uint8 num_vehicles, CargoID new_cid, byte new_subtype, DoCommandFlag flags, bool auto_refit)
{
	CommandCost cost(v->GetExpenseType(false));
	uint total_capacity = 0;
	uint total_mail_capacity = 0;
	num_vehicles = num_vehicles == 0 ? UINT8_MAX : num_vehicles;

	VehicleSet vehicles_to_refit;
	if (!only_this) {
		GetVehicleSet(vehicles_to_refit, v, num_vehicles);
		/* In this case, we need to check the whole chain. */
		v = v->First();
	}

	static SmallVector<RefitResult, 16> refit_result;
	refit_result.Clear();

	v->InvalidateNewGRFCacheOfChain();
	byte actual_subtype = new_subtype;
	for (; v != NULL; v = (only_this ? NULL : v->Next())) {
		/* Reset actual_subtype for every new vehicle */
		if (!v->IsArticulatedPart()) actual_subtype = new_subtype;

		if (v->type == VEH_TRAIN && !vehicles_to_refit.Contains(v->index) && !only_this) continue;

		const Engine *e = v->GetEngine();
		if (!e->CanCarryCargo()) continue;

		/* If the vehicle is not refittable, or does not allow automatic refitting,
		 * count its capacity nevertheless if the cargo matches */
		bool refittable = HasBit(e->info.refit_mask, new_cid) && (!auto_refit || HasBit(e->info.misc_flags, EF_AUTO_REFIT));
		if (!refittable && v->cargo_type != new_cid) continue;

		/* Determine best fitting subtype if requested */
		if (actual_subtype == 0xFF) {
			actual_subtype = GetBestFittingSubType(v, v, new_cid);
		}

		/* Back up the vehicle's cargo type */
		CargoID temp_cid = v->cargo_type;
		byte temp_subtype = v->cargo_subtype;
		if (refittable) {
			v->cargo_type = new_cid;
			v->cargo_subtype = actual_subtype;
		}

		uint16 mail_capacity = 0;
		uint amount = e->DetermineCapacity(v, &mail_capacity);
		total_capacity += amount;
		/* mail_capacity will always be zero if the vehicle is not an aircraft. */
		total_mail_capacity += mail_capacity;

		if (!refittable) continue;

		/* Restore the original cargo type */
		v->cargo_type = temp_cid;
		v->cargo_subtype = temp_subtype;

		bool auto_refit_allowed;
		CommandCost refit_cost = GetRefitCost(v, v->engine_type, new_cid, actual_subtype, &auto_refit_allowed);
		if (auto_refit && !auto_refit_allowed) {
			/* Sorry, auto-refitting not allowed, subtract the cargo amount again from the total. */
			total_capacity -= amount;
			total_mail_capacity -= mail_capacity;

			if (v->cargo_type == new_cid) {
				/* Add the old capacity nevertheless, if the cargo matches */
				total_capacity += v->cargo_cap;
				if (v->type == VEH_AIRCRAFT) total_mail_capacity += v->Next()->cargo_cap;
			}
			continue;
		}
		cost.AddCost(refit_cost);

		/* Record the refitting.
		 * Do not execute the refitting immediately, so DetermineCapacity and GetRefitCost do the same in test and exec run.
		 * (weird NewGRFs)
		 * Note:
		 *  - If the capacity of vehicles depends on other vehicles in the chain, the actual capacity is
		 *    set after RefitVehicle() via ConsistChanged() and friends. The estimation via _returned_refit_capacity will be wrong.
		 *  - We have to call the refit cost callback with the pre-refit configuration of the chain because we want refit and
		 *    autorefit to behave the same, and we need its result for auto_refit_allowed.
		 */
		RefitResult *result = refit_result.Append();
		result->v = v;
		result->capacity = amount;
		result->mail_capacity = mail_capacity;
		result->subtype = actual_subtype;
	}

	if (flags & DC_EXEC) {
		/* Store the result */
		for (RefitResult *result = refit_result.Begin(); result != refit_result.End(); result++) {
			Vehicle *u = result->v;
			if (u->cargo_type != new_cid) {
				u->cargo.Truncate(u->cargo_cap);
			} else if (u->cargo_cap > result->capacity) {
				u->cargo.Truncate(u->cargo_cap - result->capacity);
			}
			u->cargo_type = new_cid;
			u->cargo_cap = result->capacity;
			u->cargo_subtype = result->subtype;
			if (u->type == VEH_AIRCRAFT) {
				Vehicle *w = u->Next();
				if (w->cargo_cap > result->mail_capacity) {
					w->cargo.Truncate(w->cargo_cap - result->mail_capacity);
				}
				w->cargo_cap = result->mail_capacity;
			}
		}
	}

	refit_result.Clear();
	_returned_refit_capacity = total_capacity;
	_returned_mail_refit_capacity = total_mail_capacity;
	return cost;
}
Example #6
0
/** Free the list of savegames. */
void FiosFreeSavegameList()
{
	_fios_items.Clear();
	_fios_items.Compact();
}
Example #7
0
/**
 * Try to add a fios item set with the given filename.
 * @param filename        the full path to the file to read
 * @param basepath_length amount of characters to chop of before to get a relative filename
 * @return true if the file is added.
 */
bool FiosFileScanner::AddFile(const char *filename, size_t basepath_length, const char *tar_filename)
{
	const char *ext = strrchr(filename, '.');
	if (ext == NULL) return false;

	char fios_title[64];
	fios_title[0] = '\0'; // reset the title;

	FiosType type = this->callback_proc(this->mode, filename, ext, fios_title, lastof(fios_title));
	if (type == FIOS_TYPE_INVALID) return false;

	for (const FiosItem *fios = _fios_items.Begin(); fios != _fios_items.End(); fios++) {
		if (strcmp(fios->name, filename) == 0) return false;
	}

	FiosItem *fios = _fios_items.Append();
#ifdef WIN32
	struct _stat sb;
	if (_tstat(OTTD2FS(filename), &sb) == 0) {
#else
	struct stat sb;
	if (stat(filename, &sb) == 0) {
#endif
		fios->mtime = sb.st_mtime;
	} else {
		fios->mtime = 0;
	}

	fios->type = type;
	strecpy(fios->name, filename, lastof(fios->name));

	/* If the file doesn't have a title, use its filename */
	const char *t = fios_title;
	if (StrEmpty(fios_title)) {
		t = strrchr(filename, PATHSEPCHAR);
		t = (t == NULL) ? filename : (t + 1);
	}
	strecpy(fios->title, t, lastof(fios->title));
	str_validate(fios->title, lastof(fios->title));

	return true;
}


/**
 * Fill the list of the files in a directory, according to some arbitrary rule.
 *  @param mode The mode we are in. Some modes don't allow 'parent'.
 *  @param callback_proc The function that is called where you need to do the filtering.
 *  @param subdir The directory from where to start (global) searching.
 */
static void FiosGetFileList(SaveLoadDialogMode mode, fios_getlist_callback_proc *callback_proc, Subdirectory subdir)
{
	struct stat sb;
	struct dirent *dirent;
	DIR *dir;
	FiosItem *fios;
	int sort_start;
	char d_name[sizeof(fios->name)];

	_fios_items.Clear();

	/* A parent directory link exists if we are not in the root directory */
	if (!FiosIsRoot(_fios_path)) {
		fios = _fios_items.Append();
		fios->type = FIOS_TYPE_PARENT;
		fios->mtime = 0;
		strecpy(fios->name, "..", lastof(fios->name));
		strecpy(fios->title, ".. (Parent directory)", lastof(fios->title));
	}

	/* Show subdirectories */
	if ((dir = ttd_opendir(_fios_path)) != NULL) {
		while ((dirent = readdir(dir)) != NULL) {
			strecpy(d_name, FS2OTTD(dirent->d_name), lastof(d_name));

			/* found file must be directory, but not '.' or '..' */
			if (FiosIsValidFile(_fios_path, dirent, &sb) && S_ISDIR(sb.st_mode) &&
					(!FiosIsHiddenFile(dirent) || strncasecmp(d_name, PERSONAL_DIR, strlen(d_name)) == 0) &&
					strcmp(d_name, ".") != 0 && strcmp(d_name, "..") != 0) {
				fios = _fios_items.Append();
				fios->type = FIOS_TYPE_DIR;
				fios->mtime = 0;
				strecpy(fios->name, d_name, lastof(fios->name));
				snprintf(fios->title, lengthof(fios->title), "%s" PATHSEP " (Directory)", d_name);
				str_validate(fios->title, lastof(fios->title));
			}
		}
		closedir(dir);
	}

	/* Sort the subdirs always by name, ascending, remember user-sorting order */
	{
		SortingBits order = _savegame_sort_order;
		_savegame_sort_order = SORT_BY_NAME | SORT_ASCENDING;
		QSortT(_fios_items.Begin(), _fios_items.Length(), CompareFiosItems);
		_savegame_sort_order = order;
	}

	/* This is where to start sorting for the filenames */
	sort_start = _fios_items.Length();

	/* Show files */
	FiosFileScanner scanner(mode, callback_proc);
	if (subdir == NO_DIRECTORY) {
		scanner.Scan(NULL, _fios_path, false);
	} else {
		scanner.Scan(NULL, subdir, true, true);
	}

	QSortT(_fios_items.Get(sort_start), _fios_items.Length() - sort_start, CompareFiosItems);

	/* Show drives */
	FiosGetDrives();

	_fios_items.Compact();
}

/**
 * Get the title of a file, which (if exists) is stored in a file named
 * the same as the data file but with '.title' added to it.
 * @param file filename to get the title for
 * @param title the title buffer to fill
 * @param last the last element in the title buffer
 * @param subdir the sub directory to search in
 */
static void GetFileTitle(const char *file, char *title, const char *last, Subdirectory subdir)
{
	char buf[MAX_PATH];
	strecpy(buf, file, lastof(buf));
	strecat(buf, ".title", lastof(buf));

	FILE *f = FioFOpenFile(buf, "r", subdir);
	if (f == NULL) return;

	size_t read = fread(title, 1, last - title, f);
	assert(title + read <= last);
	title[read] = '\0';
	str_validate(title, last);
	FioFCloseFile(f);
}