Files @ r25958:603d75b53498
Branch filter:

Location: cpp/openttd-patchpack/source/src/cargotype.cpp - annotation

Patric Stout
Doc: update multiplayer documentation with latest changes (#9552)

Although several places were fixed during the PR making the change,
not all made it in this document.

While at it, removed all kinds of Markdown warnings by an excessive
usage of spacebar in this document.
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r18668:b656d614c4fd
r6123:049e9624d068
r6091:2faa7d307565
r6091:2faa7d307565
r13871:7588cd2474cc
r17611:e84f76d88e45
r14922:51cba7fe7b9b
r6091:2faa7d307565
r8264:d493cb51fe8a
r8264:d493cb51fe8a
r6091:2faa7d307565
r6091:2faa7d307565
r21383:942c32fb8b0e
r21383:942c32fb8b0e
r12408:d7d52eed8c09
r6091:2faa7d307565
r15610:623a23fb6560
r19893:0fdf665730bf
r13874:a3b7b89e1abf
r13874:a3b7b89e1abf
r22867:9bff1c966805
r6113:c77736e8b915
r15610:623a23fb6560
r19893:0fdf665730bf
r19893:0fdf665730bf
r22867:9bff1c966805
r19893:0fdf665730bf
r19893:0fdf665730bf
r15610:623a23fb6560
r13874:a3b7b89e1abf
r13874:a3b7b89e1abf
r6091:2faa7d307565
r6091:2faa7d307565
r6091:2faa7d307565
r6091:2faa7d307565
r6091:2faa7d307565
r18994:b2513f4fbc6f
r24284:acfc33244660
r18994:b2513f4fbc6f
r18994:b2513f4fbc6f
r18994:b2513f4fbc6f
r18994:b2513f4fbc6f
r18994:b2513f4fbc6f
r6091:2faa7d307565
r6113:c77736e8b915
r6113:c77736e8b915
r6091:2faa7d307565
r6091:2faa7d307565
r6091:2faa7d307565
r6640:772ee7bcd404
r6640:772ee7bcd404
r6640:772ee7bcd404
r12405:ba094e765533
r12405:ba094e765533
r12405:ba094e765533
r6640:772ee7bcd404
r6640:772ee7bcd404
r6640:772ee7bcd404
r6091:2faa7d307565
r6091:2faa7d307565
r6091:2faa7d307565
r6091:2faa7d307565
r12405:ba094e765533
r6113:c77736e8b915
r6148:21ae18e64c5f
r7931:4c17a74c399e
r6091:2faa7d307565
r6091:2faa7d307565
r6091:2faa7d307565
r6091:2faa7d307565
r6091:2faa7d307565
r6091:2faa7d307565
r15610:623a23fb6560
r25472:a02bcac2091b
r25472:a02bcac2091b
r25472:a02bcac2091b
r25472:a02bcac2091b
r25472:a02bcac2091b
r25472:a02bcac2091b
r25472:a02bcac2091b
r25472:a02bcac2091b
r25472:a02bcac2091b
r25472:a02bcac2091b
r25472:a02bcac2091b
r25472:a02bcac2091b
r25472:a02bcac2091b
r25472:a02bcac2091b
r25472:a02bcac2091b
r25472:a02bcac2091b
r25472:a02bcac2091b
r25472:a02bcac2091b
r25472:a02bcac2091b
r25472:a02bcac2091b
r25472:a02bcac2091b
r25472:a02bcac2091b
r15610:623a23fb6560
r13874:a3b7b89e1abf
r13874:a3b7b89e1abf
r13874:a3b7b89e1abf
r6143:9ed364174dfd
r6143:9ed364174dfd
r25310:e304033a69f3
r12408:d7d52eed8c09
r6143:9ed364174dfd
r6143:9ed364174dfd
r6143:9ed364174dfd
r6143:9ed364174dfd
r6143:9ed364174dfd
r6460:74b53af67ae0
r6460:74b53af67ae0
r15610:623a23fb6560
r15610:623a23fb6560
r6460:74b53af67ae0
r13874:a3b7b89e1abf
r6460:74b53af67ae0
r6460:74b53af67ae0
r6460:74b53af67ae0
r6460:74b53af67ae0
r6460:74b53af67ae0
r25310:e304033a69f3
r12408:d7d52eed8c09
r6460:74b53af67ae0
r6460:74b53af67ae0
r6460:74b53af67ae0
r6460:74b53af67ae0
r6460:74b53af67ae0
r6460:74b53af67ae0
r15610:623a23fb6560
r15610:623a23fb6560
r13871:7588cd2474cc
r13871:7588cd2474cc
r13871:7588cd2474cc
r13871:7588cd2474cc
r13871:7588cd2474cc
r13871:7588cd2474cc
r13871:7588cd2474cc
r13871:7588cd2474cc
r13871:7588cd2474cc
r13871:7588cd2474cc
r13871:7588cd2474cc
r13871:7588cd2474cc
r13871:7588cd2474cc
r13871:7588cd2474cc
r13871:7588cd2474cc
r25783:02166e47d365
r25783:02166e47d365
r14955:fecfdf8f80c1
r14922:51cba7fe7b9b
r23628:b9e9809abe89
r14922:51cba7fe7b9b
r14922:51cba7fe7b9b
r14922:51cba7fe7b9b
r14922:51cba7fe7b9b
r23628:b9e9809abe89
r23628:b9e9809abe89
r14922:51cba7fe7b9b
r16604:2b94452893e9
r14922:51cba7fe7b9b
r14922:51cba7fe7b9b
r23628:b9e9809abe89
r14922:51cba7fe7b9b
r14922:51cba7fe7b9b
r14922:51cba7fe7b9b
r23628:b9e9809abe89
r14922:51cba7fe7b9b
r23628:b9e9809abe89
r14922:51cba7fe7b9b
r23628:b9e9809abe89
r14922:51cba7fe7b9b
r23628:b9e9809abe89
r14955:fecfdf8f80c1
r14955:fecfdf8f80c1
r14955:fecfdf8f80c1
r14922:51cba7fe7b9b
r14922:51cba7fe7b9b
r14922:51cba7fe7b9b
r23628:b9e9809abe89
r14922:51cba7fe7b9b
r14922:51cba7fe7b9b
r14922:51cba7fe7b9b
r14922:51cba7fe7b9b
r14922:51cba7fe7b9b
r23628:b9e9809abe89
r14922:51cba7fe7b9b
r25310:e304033a69f3
r23628:b9e9809abe89
r14922:51cba7fe7b9b
r14922:51cba7fe7b9b
r14922:51cba7fe7b9b
r23628:b9e9809abe89
r14955:fecfdf8f80c1
r25783:02166e47d365
r19893:0fdf665730bf
r25783:02166e47d365
r25301:13cfd266320c
r14955:fecfdf8f80c1
r25783:02166e47d365
r19893:0fdf665730bf
r14955:fecfdf8f80c1
r25783:02166e47d365
r25783:02166e47d365
r25783:02166e47d365
r14922:51cba7fe7b9b
r14922:51cba7fe7b9b
/*
 * This file is part of OpenTTD.
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 */

/** @file cargotype.cpp Implementation of cargoes. */

#include "stdafx.h"
#include "cargotype.h"
#include "newgrf_cargo.h"
#include "string_func.h"
#include "strings_func.h"

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

#include "safeguards.h"

CargoSpec CargoSpec::array[NUM_CARGO];

/**
 * Bitmask of cargo types available. This includes phony cargoes like regearing cargoes.
 * Initialized during a call to #SetupCargoForClimate.
 */
CargoTypes _cargo_mask;

/**
 * Bitmask of real cargo types available. Phony cargoes like regearing cargoes are excluded.
 */
CargoTypes _standard_cargo_mask;

/**
 * Set up the default cargo types for the given landscape type.
 * @param l Landscape
 */
void SetupCargoForClimate(LandscapeID l)
{
	assert(l < lengthof(_default_climate_cargo));

	/* Reset and disable all cargo types */
	for (CargoID i = 0; i < lengthof(CargoSpec::array); i++) {
		*CargoSpec::Get(i) = {};
		CargoSpec::Get(i)->bitnum = INVALID_CARGO;

		/* Set defaults for newer properties, which old GRFs do not know */
		CargoSpec::Get(i)->multiplier = 0x100;
	}

	_cargo_mask = 0;

	for (CargoID i = 0; i < lengthof(_default_climate_cargo[l]); i++) {
		CargoLabel cl = _default_climate_cargo[l][i];

		/* Bzzt: check if cl is just an index into the cargo table */
		if (cl < lengthof(_default_cargo)) {
			/* Copy the indexed cargo */
			CargoSpec *cargo = CargoSpec::Get(i);
			*cargo = _default_cargo[cl];
			if (cargo->bitnum != INVALID_CARGO) SetBit(_cargo_mask, i);
			continue;
		}

		/* Loop through each of the default cargo types to see if
		 * the label matches */
		for (uint j = 0; j < lengthof(_default_cargo); j++) {
			if (_default_cargo[j].label == cl) {
				*CargoSpec::Get(i) = _default_cargo[j];

				/* Populate the available cargo mask */
				SetBit(_cargo_mask, i);
				break;
			}
		}
	}
}

/**
 * Get the cargo ID of a default cargo, if present.
 * @param l Landscape
 * @param ct Default cargo type.
 * @return ID number if the cargo exists, else #CT_INVALID
 */
CargoID GetDefaultCargoID(LandscapeID l, CargoType ct)
{
	assert(l < lengthof(_default_climate_cargo));

	if (ct == CT_INVALID) return CT_INVALID;

	assert(ct < lengthof(_default_climate_cargo[0]));
	CargoLabel cl = _default_climate_cargo[l][ct];
	/* Bzzt: check if cl is just an index into the cargo table */
	if (cl < lengthof(_default_cargo)) {
		cl = _default_cargo[cl].label;
	}

	return GetCargoIDByLabel(cl);
}

/**
 * Get the cargo ID by cargo label.
 * @param cl Cargo type to get.
 * @return ID number if the cargo exists, else #CT_INVALID
 */
CargoID GetCargoIDByLabel(CargoLabel cl)
{
	for (const CargoSpec *cs : CargoSpec::Iterate()) {
		if (cs->label == cl) return cs->Index();
	}

	/* No matching label was found, so it is invalid */
	return CT_INVALID;
}


/**
 * Find the CargoID of a 'bitnum' value.
 * @param bitnum 'bitnum' to find.
 * @return First CargoID with the given bitnum, or #CT_INVALID if not found or if the provided \a bitnum is invalid.
 */
CargoID GetCargoIDByBitnum(uint8 bitnum)
{
	if (bitnum == INVALID_CARGO) return CT_INVALID;

	for (const CargoSpec *cs : CargoSpec::Iterate()) {
		if (cs->bitnum == bitnum) return cs->Index();
	}

	/* No matching label was found, so it is invalid */
	return CT_INVALID;
}

/**
 * Get sprite for showing cargo of this type.
 * @return Sprite number to use.
 */
SpriteID CargoSpec::GetCargoIcon() const
{
	SpriteID sprite = this->sprite;
	if (sprite == 0xFFFF) {
		/* A value of 0xFFFF indicates we should draw a custom icon */
		sprite = GetCustomCargoSprite(this);
	}

	if (sprite == 0) sprite = SPR_CARGO_GOODS;

	return sprite;
}

std::vector<const CargoSpec *> _sorted_cargo_specs;   ///< Cargo specifications sorted alphabetically by name.
span<const CargoSpec *> _sorted_standard_cargo_specs; ///< Standard cargo specifications sorted alphabetically by name.

/** Sort cargo specifications by their name. */
static bool CargoSpecNameSorter(const CargoSpec * const &a, const CargoSpec * const &b)
{
	static char a_name[64];
	static char b_name[64];

	GetString(a_name, a->name, lastof(a_name));
	GetString(b_name, b->name, lastof(b_name));

	int res = strnatcmp(a_name, b_name); // Sort by name (natural sorting).

	/* If the names are equal, sort by cargo bitnum. */
	return (res != 0) ? res < 0 : (a->bitnum < b->bitnum);
}

/** Sort cargo specifications by their cargo class. */
static bool CargoSpecClassSorter(const CargoSpec * const &a, const CargoSpec * const &b)
{
	int res = (b->classes & CC_PASSENGERS) - (a->classes & CC_PASSENGERS);
	if (res == 0) {
		res = (b->classes & CC_MAIL) - (a->classes & CC_MAIL);
		if (res == 0) {
			res = (a->classes & CC_SPECIAL) - (b->classes & CC_SPECIAL);
			if (res == 0) {
				return CargoSpecNameSorter(a, b);
			}
		}
	}

	return res < 0;
}

/** Initialize the list of sorted cargo specifications. */
void InitializeSortedCargoSpecs()
{
	_sorted_cargo_specs.clear();
	/* Add each cargo spec to the list. */
	for (const CargoSpec *cargo : CargoSpec::Iterate()) {
		_sorted_cargo_specs.push_back(cargo);
	}

	/* Sort cargo specifications by cargo class and name. */
	std::sort(_sorted_cargo_specs.begin(), _sorted_cargo_specs.end(), &CargoSpecClassSorter);

	/* Count the number of standard cargos and fill the mask. */
	_standard_cargo_mask = 0;
	uint8 nb_standard_cargo = 0;
	for (const auto &cargo : _sorted_cargo_specs) {
		if (cargo->classes & CC_SPECIAL) break;
		nb_standard_cargo++;
		SetBit(_standard_cargo_mask, cargo->Index());
	}

	/* _sorted_standard_cargo_specs is a subset of _sorted_cargo_specs. */
	_sorted_standard_cargo_specs = { _sorted_cargo_specs.data(), nb_standard_cargo };
}