mirror of https://github.com/OpenTTD/OpenTTD
Codechange: change Source into a class with conversion helpers
A Source is either a CompanyID (Headquarters), IndustryID or TownID. When making those types stronger a lot of casts would be needed, but with these simple helpers the intent is shown more clearly.pull/13511/head
parent
2929411130
commit
155d7de132
|
@ -427,6 +427,7 @@ add_files(
|
|||
soundloader_type.h
|
||||
soundloader_raw.cpp
|
||||
soundloader_wav.cpp
|
||||
source_type.h
|
||||
sprite.cpp
|
||||
sprite.h
|
||||
spritecache.cpp
|
||||
|
|
|
@ -130,23 +130,4 @@ struct CargoArray : std::array<uint, NUM_CARGO> {
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
/** Types of cargo source and destination */
|
||||
enum class SourceType : uint8_t {
|
||||
Industry, ///< Source/destination is an industry
|
||||
Town, ///< Source/destination is a town
|
||||
Headquarters, ///< Source/destination are company headquarters
|
||||
};
|
||||
|
||||
typedef uint16_t SourceID; ///< Contains either industry ID, town ID or company ID (or INVALID_SOURCE)
|
||||
static const SourceID INVALID_SOURCE = 0xFFFF; ///< Invalid/unknown index of source
|
||||
|
||||
/** A location from where cargo can come from (or go to). Specifically industries, towns and headquarters. */
|
||||
struct Source {
|
||||
SourceID id; ///< Index of industry/town/HQ, INVALID_SOURCE if unknown/invalid.
|
||||
SourceType type; ///< Type of \c source_id.
|
||||
|
||||
auto operator<=>(const Source &source) const = default;
|
||||
};
|
||||
|
||||
#endif /* CARGO_TYPE_H */
|
||||
|
|
|
@ -118,17 +118,17 @@ void AddCargoDelivery(CargoType cargo_type, CompanyID company, uint32_t amount,
|
|||
{
|
||||
if (amount == 0) return;
|
||||
|
||||
if (src.id != INVALID_SOURCE) {
|
||||
if (src.IsValid()) {
|
||||
/* Handle pickup update. */
|
||||
switch (src.type) {
|
||||
case SourceType::Industry: {
|
||||
CargoMonitorID num = EncodeCargoIndustryMonitor(company, cargo_type, src.id);
|
||||
CargoMonitorID num = EncodeCargoIndustryMonitor(company, cargo_type, src.ToIndustryID());
|
||||
CargoMonitorMap::iterator iter = _cargo_pickups.find(num);
|
||||
if (iter != _cargo_pickups.end()) iter->second += amount;
|
||||
break;
|
||||
}
|
||||
case SourceType::Town: {
|
||||
CargoMonitorID num = EncodeCargoTownMonitor(company, cargo_type, src.id);
|
||||
CargoMonitorID num = EncodeCargoTownMonitor(company, cargo_type, src.ToTownID());
|
||||
CargoMonitorMap::iterator iter = _cargo_pickups.find(num);
|
||||
if (iter != _cargo_pickups.end()) iter->second += amount;
|
||||
break;
|
||||
|
|
|
@ -132,7 +132,7 @@ void CargoPacket::Reduce(uint count)
|
|||
/* static */ void CargoPacket::InvalidateAllFrom(Source src)
|
||||
{
|
||||
for (CargoPacket *cp : CargoPacket::Iterate()) {
|
||||
if (cp->source == src) cp->source.id = INVALID_SOURCE;
|
||||
if (cp->source == src) cp->source.MakeInvalid();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "station_type.h"
|
||||
#include "order_type.h"
|
||||
#include "cargo_type.h"
|
||||
#include "source_type.h"
|
||||
#include "vehicle_type.h"
|
||||
#include "core/multimap.hpp"
|
||||
#include "saveload/saveload.h"
|
||||
|
@ -53,7 +54,7 @@ private:
|
|||
TileIndex source_xy = INVALID_TILE; ///< The origin of the cargo.
|
||||
Vector travelled{0, 0}; ///< If cargo is in station: the vector from the unload tile to the source tile. If in vehicle: an intermediate value.
|
||||
|
||||
Source source{INVALID_SOURCE, SourceType::Industry}; ///< Source of the cargo
|
||||
Source source{Source::Invalid, SourceType::Industry}; ///< Source of the cargo
|
||||
|
||||
#ifdef WITH_ASSERT
|
||||
bool in_vehicle = false; ///< NOSAVE: Whether this cargo is in a vehicle or not.
|
||||
|
@ -504,9 +505,8 @@ public:
|
|||
{
|
||||
return cp1->source_xy == cp2->source_xy &&
|
||||
cp1->periods_in_transit == cp2->periods_in_transit &&
|
||||
cp1->source.type == cp2->source.type &&
|
||||
cp1->first_station == cp2->first_station &&
|
||||
cp1->source.id == cp2->source.id;
|
||||
cp1->source == cp2->source;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1114,7 +1114,7 @@ static Money DeliverGoods(int num_pieces, CargoType cargo_type, StationID dest,
|
|||
Station *st = Station::Get(dest);
|
||||
|
||||
/* Give the goods to the industry. */
|
||||
uint accepted_ind = DeliverGoodsToIndustry(st, cargo_type, num_pieces, src.type == SourceType::Industry ? src.id : INVALID_INDUSTRY, company->index);
|
||||
uint accepted_ind = DeliverGoodsToIndustry(st, cargo_type, num_pieces, src.type == SourceType::Industry ? src.ToIndustryID() : INVALID_INDUSTRY, company->index);
|
||||
|
||||
/* If this cargo type is always accepted, accept all */
|
||||
uint accepted_total = HasBit(st->always_accepted, cargo_type) ? num_pieces : accepted_ind;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "vehicle_type.h"
|
||||
#include "company_type.h"
|
||||
#include "settings_type.h"
|
||||
#include "source_type.h"
|
||||
#include "core/random_func.hpp"
|
||||
|
||||
void ResetPriceBaseMultipliers();
|
||||
|
|
|
@ -2280,19 +2280,19 @@ bool AfterLoadGame()
|
|||
case TAE_MAIL:
|
||||
/* Town -> Town */
|
||||
s->src.type = s->dst.type = SourceType::Town;
|
||||
if (Town::IsValidID(s->src.id) && Town::IsValidID(s->dst.id)) continue;
|
||||
if (Town::IsValidID(s->src.ToTownID()) && Town::IsValidID(s->dst.ToTownID())) continue;
|
||||
break;
|
||||
case TAE_GOODS:
|
||||
case TAE_FOOD:
|
||||
/* Industry -> Town */
|
||||
s->src.type = SourceType::Industry;
|
||||
s->dst.type = SourceType::Town;
|
||||
if (Industry::IsValidID(s->src.id) && Town::IsValidID(s->dst.id)) continue;
|
||||
if (Industry::IsValidID(s->src.ToIndustryID()) && Town::IsValidID(s->dst.ToTownID())) continue;
|
||||
break;
|
||||
default:
|
||||
/* Industry -> Industry */
|
||||
s->src.type = s->dst.type = SourceType::Industry;
|
||||
if (Industry::IsValidID(s->src.id) && Industry::IsValidID(s->dst.id)) continue;
|
||||
if (Industry::IsValidID(s->src.ToIndustryID()) && Industry::IsValidID(s->dst.ToIndustryID())) continue;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
|
@ -2310,8 +2310,8 @@ bool AfterLoadGame()
|
|||
if (ss != nullptr && sd != nullptr && ss->owner == sd->owner &&
|
||||
Company::IsValidID(ss->owner)) {
|
||||
s->src.type = s->dst.type = SourceType::Town;
|
||||
s->src.id = ss->town->index;
|
||||
s->dst.id = sd->town->index;
|
||||
s->src.SetIndex(ss->town->index);
|
||||
s->dst.SetIndex(sd->town->index);
|
||||
s->awarded = ss->owner;
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@
|
|||
|
||||
/* static */ SQInteger ScriptSubsidy::GetSourceIndex(SubsidyID subsidy_id)
|
||||
{
|
||||
if (!IsValidSubsidy(subsidy_id)) return INVALID_SOURCE;
|
||||
if (!IsValidSubsidy(subsidy_id)) return Source::Invalid;
|
||||
|
||||
return ::Subsidy::Get(subsidy_id)->src.id;
|
||||
}
|
||||
|
@ -96,7 +96,7 @@
|
|||
|
||||
/* static */ SQInteger ScriptSubsidy::GetDestinationIndex(SubsidyID subsidy_id)
|
||||
{
|
||||
if (!IsValidSubsidy(subsidy_id)) return INVALID_SOURCE;
|
||||
if (!IsValidSubsidy(subsidy_id)) return Source::Invalid;
|
||||
|
||||
return ::Subsidy::Get(subsidy_id)->dst.id;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* 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 source_type.h Type for the source of cargo. */
|
||||
|
||||
#ifndef SOURCE_TYPE_H
|
||||
#define SOURCE_TYPE_H
|
||||
|
||||
#include "company_type.h"
|
||||
#include "industry_type.h"
|
||||
#include "town_type.h"
|
||||
|
||||
/** Types of cargo source and destination */
|
||||
enum class SourceType : uint8_t {
|
||||
Industry = 0, ///< Source/destination is an industry
|
||||
Town = 1, ///< Source/destination is a town
|
||||
Headquarters = 2, ///< Source/destination are company headquarters
|
||||
};
|
||||
|
||||
using SourceID = uint16_t; ///< Contains either industry ID, town ID or company ID (or Source::Invalid)
|
||||
static_assert(sizeof(SourceID) >= sizeof(CompanyID));
|
||||
static_assert(sizeof(SourceID) >= sizeof(IndustryID));
|
||||
static_assert(sizeof(SourceID) >= sizeof(TownID));
|
||||
|
||||
/** A location from where cargo can come from (or go to). Specifically industries, towns and headquarters. */
|
||||
struct Source {
|
||||
public:
|
||||
static constexpr SourceID Invalid = 0xFFFF; ///< Invalid/unknown index of source
|
||||
|
||||
SourceID id; ///< Index of industry/town/HQ, Source::Invalid if unknown/invalid.
|
||||
SourceType type; ///< Type of \c source_id.
|
||||
|
||||
constexpr CompanyID ToCompanyID() const { assert(this->type == SourceType::Headquarters); return static_cast<CompanyID>(this->id); }
|
||||
constexpr IndustryID ToIndustryID() const { assert(this->type == SourceType::Industry); return static_cast<IndustryID>(this->id); }
|
||||
constexpr TownID ToTownID() const { assert(this->type == SourceType::Town); return static_cast<TownID>(this->id); }
|
||||
|
||||
constexpr void MakeInvalid() { this->id = Source::Invalid; }
|
||||
constexpr void SetIndex(SourceID index) { this->id = index; }
|
||||
|
||||
constexpr bool IsValid() const noexcept { return this->id != Source::Invalid; }
|
||||
auto operator<=>(const Source &source) const = default;
|
||||
};
|
||||
|
||||
#endif /* SOURCE_TYPE_H */
|
|
@ -123,8 +123,8 @@ std::pair<NewsReferenceType, NewsReferenceType> SetupSubsidyDecodeParam(const Su
|
|||
static inline void SetPartOfSubsidyFlag(Source source, PartOfSubsidy flag)
|
||||
{
|
||||
switch (source.type) {
|
||||
case SourceType::Industry: Industry::Get(source.id)->part_of_subsidy |= flag; return;
|
||||
case SourceType::Town: Town::Get(source.id)->cache.part_of_subsidy |= flag; return;
|
||||
case SourceType::Industry: Industry::Get(source.ToIndustryID())->part_of_subsidy |= flag; return;
|
||||
case SourceType::Town: Town::Get(source.ToTownID())->cache.part_of_subsidy |= flag; return;
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
@ -188,8 +188,8 @@ static bool CheckSubsidyDuplicate(CargoType cargo, Source src, Source dst)
|
|||
*/
|
||||
static bool CheckSubsidyDistance(Source src, Source dst)
|
||||
{
|
||||
TileIndex tile_src = (src.type == SourceType::Town) ? Town::Get(src.id)->xy : Industry::Get(src.id)->location.tile;
|
||||
TileIndex tile_dst = (dst.type == SourceType::Town) ? Town::Get(dst.id)->xy : Industry::Get(dst.id)->location.tile;
|
||||
TileIndex tile_src = (src.type == SourceType::Town) ? Town::Get(src.ToTownID())->xy : Industry::Get(src.ToIndustryID())->location.tile;
|
||||
TileIndex tile_dst = (dst.type == SourceType::Town) ? Town::Get(dst.ToTownID())->xy : Industry::Get(dst.ToIndustryID())->location.tile;
|
||||
|
||||
return (DistanceManhattan(tile_src, tile_dst) <= SUBSIDY_MAX_DISTANCE);
|
||||
}
|
||||
|
@ -237,20 +237,20 @@ CommandCost CmdCreateSubsidy(DoCommandFlag flags, CargoType cargo_type, Source s
|
|||
|
||||
switch (src.type) {
|
||||
case SourceType::Town:
|
||||
if (!Town::IsValidID(src.id)) return CMD_ERROR;
|
||||
if (!Town::IsValidID(src.ToTownID())) return CMD_ERROR;
|
||||
break;
|
||||
case SourceType::Industry:
|
||||
if (!Industry::IsValidID(src.id)) return CMD_ERROR;
|
||||
if (!Industry::IsValidID(src.ToIndustryID())) return CMD_ERROR;
|
||||
break;
|
||||
default:
|
||||
return CMD_ERROR;
|
||||
}
|
||||
switch (dst.type) {
|
||||
case SourceType::Town:
|
||||
if (!Town::IsValidID(dst.id)) return CMD_ERROR;
|
||||
if (!Town::IsValidID(dst.ToTownID())) return CMD_ERROR;
|
||||
break;
|
||||
case SourceType::Industry:
|
||||
if (!Industry::IsValidID(dst.id)) return CMD_ERROR;
|
||||
if (!Industry::IsValidID(dst.ToIndustryID())) return CMD_ERROR;
|
||||
break;
|
||||
default:
|
||||
return CMD_ERROR;
|
||||
|
@ -403,7 +403,7 @@ bool FindSubsidyIndustryCargoRoute()
|
|||
bool FindSubsidyCargoDestination(CargoType cargo_type, Source src)
|
||||
{
|
||||
/* Choose a random destination. */
|
||||
Source dst{INVALID_SOURCE, Chance16(1, 2) ? SourceType::Town : SourceType::Industry};
|
||||
Source dst{Source::Invalid, Chance16(1, 2) ? SourceType::Town : SourceType::Industry};
|
||||
|
||||
switch (dst.type) {
|
||||
case SourceType::Town: {
|
||||
|
@ -422,7 +422,7 @@ bool FindSubsidyCargoDestination(CargoType cargo_type, Source src)
|
|||
/* Check if the town can accept this cargo. */
|
||||
if (town_cargo_accepted[cargo_type] < 8) return false;
|
||||
|
||||
dst.id = dst_town->index;
|
||||
dst.SetIndex(dst_town->index);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -434,7 +434,7 @@ bool FindSubsidyCargoDestination(CargoType cargo_type, Source src)
|
|||
/* The industry must accept the cargo */
|
||||
if (!dst_ind->IsCargoAccepted(cargo_type)) return false;
|
||||
|
||||
dst.id = dst_ind->index;
|
||||
dst.SetIndex(dst_ind->index);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -539,13 +539,13 @@ static IntervalTimer<TimerGameEconomy> _economy_subsidies_monthly({TimerGameEcon
|
|||
bool CheckSubsidised(CargoType cargo_type, CompanyID company, Source src, const Station *st)
|
||||
{
|
||||
/* If the source isn't subsidised, don't continue */
|
||||
if (src.id == INVALID_SOURCE) return false;
|
||||
if (!src.IsValid()) return false;
|
||||
switch (src.type) {
|
||||
case SourceType::Industry:
|
||||
if (!(Industry::Get(src.id)->part_of_subsidy & POS_SRC)) return false;
|
||||
if (!(Industry::Get(src.ToIndustryID())->part_of_subsidy & POS_SRC)) return false;
|
||||
break;
|
||||
case SourceType::Town:
|
||||
if (!(Town::Get(src.id)->cache.part_of_subsidy & POS_SRC)) return false;
|
||||
if (!(Town::Get(src.ToTownID())->cache.part_of_subsidy & POS_SRC)) return false;
|
||||
break;
|
||||
default: return false;
|
||||
}
|
||||
|
@ -579,7 +579,7 @@ bool CheckSubsidised(CargoType cargo_type, CompanyID company, Source src, const
|
|||
switch (s->dst.type) {
|
||||
case SourceType::Industry:
|
||||
for (const auto &i : st->industries_near) {
|
||||
if (s->dst.id == i.industry->index) {
|
||||
if (s->dst.ToIndustryID() == i.industry->index) {
|
||||
assert(i.industry->part_of_subsidy & POS_DST);
|
||||
subsidised = true;
|
||||
if (!s->IsAwarded()) s->AwardTo(company);
|
||||
|
@ -588,7 +588,7 @@ bool CheckSubsidised(CargoType cargo_type, CompanyID company, Source src, const
|
|||
break;
|
||||
case SourceType::Town:
|
||||
for (const Town *tp : towns_near) {
|
||||
if (s->dst.id == tp->index) {
|
||||
if (s->dst.ToTownID() == tp->index) {
|
||||
assert(tp->cache.part_of_subsidy & POS_DST);
|
||||
subsidised = true;
|
||||
if (!s->IsAwarded()) s->AwardTo(company);
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include "cargo_type.h"
|
||||
#include "company_type.h"
|
||||
#include "source_type.h"
|
||||
#include "subsidy_type.h"
|
||||
#include "core/pool_type.hpp"
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include "command_type.h"
|
||||
#include "cargo_type.h"
|
||||
#include "source_type.h"
|
||||
#include "misc/endian_buffer.hpp"
|
||||
|
||||
CommandCost CmdCreateSubsidy(DoCommandFlag flags, CargoType cargo_type, Source src, Source dst);
|
||||
|
|
|
@ -83,8 +83,8 @@ struct SubsidyListWindow : Window {
|
|||
/* determine src coordinate for subsidy and try to scroll to it */
|
||||
TileIndex xy;
|
||||
switch (s->src.type) {
|
||||
case SourceType::Industry: xy = Industry::Get(s->src.id)->location.tile; break;
|
||||
case SourceType::Town: xy = Town::Get(s->src.id)->xy; break;
|
||||
case SourceType::Industry: xy = Industry::Get(s->src.ToIndustryID())->location.tile; break;
|
||||
case SourceType::Town: xy = Town::Get(s->src.ToTownID())->xy; break;
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
|
||||
|
@ -93,8 +93,8 @@ struct SubsidyListWindow : Window {
|
|||
|
||||
/* otherwise determine dst coordinate for subsidy and scroll to it */
|
||||
switch (s->dst.type) {
|
||||
case SourceType::Industry: xy = Industry::Get(s->dst.id)->location.tile; break;
|
||||
case SourceType::Town: xy = Town::Get(s->dst.id)->xy; break;
|
||||
case SourceType::Industry: xy = Industry::Get(s->dst.ToIndustryID())->location.tile; break;
|
||||
case SourceType::Town: xy = Town::Get(s->dst.ToTownID())->xy; break;
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue